290 likes | 472 Views
Using the Macro Facility to Create HTML, XML and RTF output. Rick Langston, SAS Institute Inc. What we can use Macro to do. Can generate any text, not just SAS code, such as... HTML and XML RTF for Word documents Examples for HTML and RTF shown herein
E N D
Using the Macro Facility to Create HTML, XML and RTF output Rick Langston, SAS Institute Inc.
What we can use Macro to do • Can generate any text, not just SAS code, such as... • HTML and XML • RTF for Word documents • Examples for HTML and RTF shown herein • Using the new experimental PROC STREAM
Basic example filename new 'mytest.htm' recfm=v lrecl=32767; %macro make_table(nrows,ncols); <table> %do i=1 %to &nrows; <tr> %do j=1 %to &ncols; <td>&j</td> %end; </tr> %end; </table> %mend; proc stream outfile=new; begin %make_table(2,3) ;;;;
What is produced <table> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> </table>
What is produced <table> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> </table>
/* adding newlines */ %macro make_table(nrows,ncols); &streamdelim newline; <table> %do i=1 %to &nrows; &streamdelim newline; <tr> %do j=1 %to &ncols; &streamdelim newline; <td>&j</td> %end; &streamdelim newline; </tr> %end; &streamdelim newline; </table> %mend; proc stream outfile=new; begin %make_table(2,3) ;;;;
What is produced <table> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> </table>
Using the <PRE>...</PRE> tags filename prefmt temp; data _null_; file prefmt; input; put _infile_; cards4; this is some preformatted text that we would like to see before our table ;;;;
%macro make_table(nrows,ncols); &streamdelim newline; <pre> &streamdelimreadfileprefmt; &streamdelim newline; </pre> &streamdelim newline; <table> %do i=1 %to &nrows; &streamdelim newline; <tr> %do j=1 %to &ncols; &streamdelim newline; <td>&j</td> %end; &streamdelim newline; </tr> %end; &streamdelim newline; </table> %mend;
What is produced <pre> this is some preformatted text that we would like to see before our table </pre> <table> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> </table>
/* using & and % */ %macro make_table(nrows,ncols); <title>Using row %nrstr(&) col of &nrows%nrstr(&) &ncols</title> &streamdelim newline; Use <a href=%nrstr("http://www.somedomain.com/x%20y/&z=123")> this</a> link to find out more. <br> <table> %do i=1 %to &nrows; <tr> %do j=1 %to &ncols; <td>&j</td> %end; </tr> %end; </table> %mend;
/* using & and % */ %macro make_table(nrows,ncols); <title>Using row %nrstr(&) col of &nrows%nrstr(&) &ncols</title> &streamdelim newline; Use <a href=%nrstr("http://www.somedomain.com/x%20y/&z=123")> this</a> link to find out more. <br> <table> %do i=1 %to &nrows; <tr> %do j=1 %to &ncols; <td>&j</td> %end; </tr> %end; </table> %mend;
/* using & and % */ %macro make_table(nrows,ncols); <title>Using row %nrstr(&) col of &nrows%nrstr(&) &ncols</title> &streamdelim newline; Use <a href=%nrstr("http://www.somedomain.com/x%20y/&z=123")>this</a> link to find out more. <br> <table> %do i=1 %to &nrows; <tr> %do j=1 %to &ncols; <td>&j</td> %end; </tr> %end; </table> %mend;
A tip for handling input HTML • File my.htm contains < 1 & 2 > • We try the following: proc stream outfile=out; begin &streamdelim; %include 'my.htm'; ;;;; • We get noise such as: WARNING: Apparent symbolic reference LT not resolved.
A tip for handling input HTML proc stream outfile=out; begin &streamdelim; %let amp=P %let lt=L %let gt=n %include 'my.htm'; ;;;;
Using/Creating RTF files • These are script and text based files • Alternate creation from Word • Can’t do this with DOC/DOCX because it’s binary • This example courtesy of Don Henderson
One way to make our RTF file filename classrtf 'class.rtf' recfm=v lrecl=32767; filename new 'new.rtf' recfm=v lrecl=32767; procstream outfile=new quoting=both asis; begin %let name=Alfred; %let height=69; %let weight=112.5; %let sex=male; %let age=14; &streamdelim; %include classrtf; ;;;;
Example macro for alternate method %macro each_student(obsnum); %global name height weight sex age; data _null_; set sashelp.class(firstobs=&obsnumobs=&obsnum); call symputx('name',name); call symputx('height',height); call symputx('weight',weight); call symputx('sex',put(sex,$sex.)); call symputx('age',age); run; filename new "&name..rtf" recfm=v lrecl=32767; filename classrtf 'class.rtf' recfm=v lrecl=32767; proc stream outfile=new quoting=both asis; begin &streamdelim; %include classrtf; ;;;; %mend;
Invoking the macro data _null_; set sashelp.class(obs=3); rc = dosubl( cats('%each_student(' , _n_ , ');' ) ); run; • Use DOSUBL instead of CALL EXECUTE • Creates Alfred.rtf, Alice.rtf, Barbara.rtf
Use of DOSUBL %macro getcount(data); %global numobs; Procsql; select count(*) into:numobs from &data; quit; %mend; data temp; do x=1 to 10; output; end; run; • Code in red is generated by the macro
Use of DOSUBL filename outfile temp; proc stream outfile=outfile; begin some text here %getcount(work.temp) obscount for work.temp is &numobs. %let x=%sysfunc(dosubl(%nrstr(%getcount(work.temp)))); obscount for work.temp is &numobs. text after the dosub call ;;;; data _null_; infileoutfile; input; put _infile_; run;
Use of DOSUBL some text here Procsql; select count(*) into:numobs from work.temp; quit; obscount for work.temp is . obscount for work.temp is 10. text after the dosubcall
Summary • Any scripting language is possible • HTML, RTF given as examples • Deal with & and % via %nrstr if needed • PROC STREAM available as experimental in 9.3 • readfile to read a file with no tokenizing (9.3m2)
Contact Info • Rick Langston, SAS Institute Inc. • Rick.Langston@sas.com • Don Henderson’s blog entry • http://www.sascommunity.org/wiki/SAS%C2%AE_Server_Pages:_Generating_Dynamic_Content