Wednesday, April 16, 2014
Monday, March 5, 2012
Use GREPLAY to create multiple graphs per page
This sample program uses PROC GREPLAY together with macro code to dynamically replay a specific number of graphs per page.
The graphics output in the Results tab was produced using SAS® 9.2. Submitting the sample code with releases of SAS prior to SAS 9.2 might produce different results.
/* Delete any old entries in WORK.GSEG catalog */
proc greplay nofs igout=work.gseg;
delete _all_;
run;
quit;
/* Specify macro debugging options */
options mprint mlogic symbolgen;
goptions reset=all device=gif;
/* Macro MAKEGRAF creates GSLIDE graph entries that are TREPLAYED */
/* by PROC GREPLAY later in this program. Remove the %DO loop and GSLIDE */
/* procedure and place your code within the MAKEGRAF macro when you are */
/* ready to create your own individual graph entries. */
%macro makegraf;
%do i=1 %to 6;
proc gslide;
title1 "GRAPH &i";
run;
quit;
%end;
%mend makegraf;
/* This macro will dynamically treplay a specified number of grseg entries */
/* per page/screen. The specified values for the parameters */
/* ACROSS and DOWN will determine the number of panels in the template */
/* and the number of graphs per page/screen. */
%MACRO PERPAGE(across,down);
/* Create macro variable perpage */
%let perpage=%eval(&across*&down);
/* Use DSGI functions HSIZE/VSIZE to determine default HSIZE and VSIZE */
/* and modify for correct aspect ratio. */
data garea;
rc=ginit();
call gask('hsize',hsize,rc);
hsze=hsize/&across;
call symput('hsize',left(trim(hsze)));
call gask('vsize',vsize,rc);
vsze=vsize/&down;
call symput('vsize',left(trim(vsze)));
rc=gterm();
run;
/* Adjust VSIZE and HSIZE to reflect dimension of template panel. */
/* Turn DISPLAY off. */
goptions nodisplay vsize=&vsize hsize=&hsize;
/* Invoke macro MAKEGRAF, */
/* gslide entries created in WORK.GSEG catalog. */
%makegraf
/* Use DSGI function NUMGRAPH to determine the number of entries in */
/* WORK.GSEG catalog. */
data numgraf;
rc=gset('catalog','work','gseg');
rc=ginit();
call gask('numgraph',grsegcnt,rc);
call symput('grsegcnt',grsegcnt);
call symput('loopit',ceil(grsegcnt/&perpage));
ymult=100/&down;
xmult=100/&across;
rc=gterm();
run;
/* Calculate the panel coordinates for template */
data coord;
set numgraf;
do x=0 to (100-xmult) by xmult;
llx=x;
ulx=x;
urx=x+xmult;
lrx=x+xmult;
do y=0 to (100-ymult) by ymult;
lly=y;
uly=y+ymult;
ury=y+ymult;
lry=y;
output;
end;
end;
run;
proc sort;
by descending y;
run;
/* Create macro variables that resolve to panel coordinates */
data mccoord;
set coord end=eof;
call symput('llx'||left(_n_),llx);
call symput('ulx'||left(_n_),ulx);
call symput('urx'||left(_n_),urx);
call symput('lrx'||left(_n_),lrx);
call symput('lly'||left(_n_),lly);
call symput('uly'||left(_n_),uly);
call symput('ury'||left(_n_),ury);
call symput('lry'||left(_n_),lry);
if eof then call symput('total',_n_);
run;
/* Macro to create template */
%macro tempdef;
%do i=1 %to &total;
&i / llx=&&llx&i lly=&&lly&i
ulx=&&ulx&i uly=&&uly&i
urx=&&urx&i ury=&&ury&i
lrx=&&lrx&i lry=&&lry&i
color=black
%end;
%mend tempdef;
/* Macro to generate TREPLAY statement for GREPLAY */
%macro tplay;
%do j=1 %to &perpage;
%if %eval(&i*&perpage-(&perpage-&j)) <= &grsegcnt %then
&j:%eval(&i*&perpage-(&perpage-&j));
%end;
%mend tplay;
/* Macro to generate templated grseg entries */
%macro greplay;
proc greplay nofs igout=work.gseg tc=tempcat;
tdef spec&perpage
%tempdef;
template spec&perpage;
%do i=1 %to &loopit;
treplay %tplay;
run;
%end;
quit;
%mend greplay;
/* Reset the graphics options */
goptions reset=all device=gif
gsfname=grafout gsfmode=replace
xpixels=600 ypixels=400;
filename grafout 'c:\temp\test.gif';
/* Invoke the GREPLAY macro */
%greplay
%MEND PERPAGE;
/* Invoke the PERPAGE macro, specifying how you */
/* want the graphs laid out on the page. */
%PERPAGE(across=2,down=3);
Copied from SAS KNOWLEDGE BASE / SAMPLES & SAS NOTES
Tuesday, November 30, 2010
Use DO WHILE to read in every word in a string
%let cnt=1;
%let tword=%qscan(&tstring,&cnt,%str( ));
%* let ntot1=%qscan(&tcount,&cnt,%str( ));
%do %while(&tword ne);
      data _null_;
            set &dir..&dsn;
            if &tname="&tword";
            call symput('twlbl',trim(left(&tlname)));
      run;
      %concat; *** Macro program is appended after Macro descrip;
      %let cnt=%eval(&cnt+1);
      %let tword=%qscan(&tstring,&cnt,%str( ));
      %* let ntot1=%qscan(&tcount,&cnt,%str( ));
%end; *** End of While(tword ne);
%let cnt=%eval(&cnt-1);
Thursday, November 18, 2010
Rename all vars in a dataset using SASHELP
data dsn;
a=1;
b=2;
c=3;
d=4;
e=5;
f=6;
run;
%macro test(lib,dsn);
*/1)*/ data _null_;
      set sashelp.vtable(where=(libname="&LIB" and memname="&DSN"));
      call symput('nvars',nvar);
run;
*/2)*/ data dsn;
      set sashelp.vcolumn(where=(libname="&LIB" and memname="&DSN"));
      call symput(cats("var",_n_),name);
run;
*/3)*/ proc datasets library=&LIB;
      modify &DSN;
      rename
      %do i = 1 %to &nvars;
            &&var&i=Rename_&&var&i.
      %end;
      ;
quit;
run;
%mend;
%test(WORK,DSN);
Thursday, August 19, 2010
Wednesday, June 16, 2010
Handling leading, trailing blanks in macro variable
%let macvar = &macvar;
Wednesday, April 14, 2010
Read all files in one directory
%macro readraw(dir=.);
%local fileref rc did dnum dmem memname;
%let fileref=thisdir;
%let rc=%sysfunc(filename(fileref,&dir));
%let did=%sysfunc(dopen(&fileref));
%let dnum=%sysfunc(dnum(&did));
%do dmem=1 %to &dnum;
%let memname=%sysfunc(dread(&did, &dmem));
%if %upcase(%scan(&memname,-1,.)) = DAT %then %do;
%let dataset=%scan(&memname,1,.);
data &dataset;
infile "&dir\&memname";
input Course_code $4. Location $15. Begin_date date9.;
format Begin_date date9.;
run;
proc print data=&dataset;
title "%trim(&syslast)";
run;
%end;
%end;
%let rc=%sysfunc(dclose(&did));
%let rc=%sysfunc(filename(fileref));
%mend readraw;
options mprint;
%readraw(dir=c:\workshop\winsas\amacr);
Tuesday, February 2, 2010
Creating a Stored Macro Facility
libname macro '/home/dltmp/maclib';
%macro test / store des='This is my program';
%let x=1;
%mend;
%copy test/source;
proc catalog cat=macro.sasmacr;
contents;
run;
Link: http://www2.sas.com/proceedings/forum2008/101-2008.pdf
Tuesday, September 22, 2009
SYMGLOBL and SYMLOCAL
%let c=yes;
%macro test;
%let d=yes;
data _null_;
if symlocal ('c') then put '**** c is local';
if symglobl('c') then put '**** c is global';
if symlocal ('d') then put '**** d is local';
if symglobl('d') then put '**** d is global';
run;
%mend test;
%test;
**** c is global
**** d is local
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
Deleting a Macro Variable
%let a=yes;
data _null_;
if symexist('a') then put '**** a exists';
call symdel('a');
if symexist('a') then put '**** a still exists';
else put '**** a doesnt exist';
run;
**** a exists
**** a doesnt exist
NOTE: DATA statement used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds
SYMEXIST to check if a Macro Variable Exists
data _null_;
if symexist('a') then put '**** a exists';
Else put '**** a doesnt exist';
if symexist('b') then put '**** b exists';
Else put '**** b doesnt exist';
run;
**** a exists
**** b doesnt exist
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
Monday, September 7, 2009
Macro IN Operator (SAS 9.2)
%macro test;
%if &dsn IN ae ds co cm %then %do;
Some---SAS—Statements;
%end;
%test;
Note:
No need of % sign in front of IN operator.
In SAS 9.2 both IN and # work if you use the system option minoperator inside your macro call.
%macro test/minoperator;
%if &dsn # ae ds co cm %then %do;
Some---SAS—Statements;
%end;
%test;
%macro test;
%if &dsn IN ae ds co cm %then %do;
Some---SAS—Statements;
%end;
%test;
MINOPERATOR option tells SAS to recognize the word 'IN' or special symbol # by the SAS macro facility as an infix operator when evaluating logical or integer expressions.
Here is another way of writing the macro code with delimiters.
Use MINDELIMITER option to change the default delimiter from space to any other, in this case it is comma (,).
options mindelimiter;
%macro test/mindelimiter=',';
%if &dsn IN ae,ds,co,cm %then %do;
Some---SAS—Statements;
%end;
%test;
Tuesday, June 23, 2009
SYSPARM
data one;
set one;
if scan(sysparm(),1) ^= ' ' then do;
......
data _null_;
array p{3} p1-p3;
inp=sysparm();
if inp='' then abort abend;
do i = 1 to 3;
p[i]=scan(inp,i);
end;
call symput('v1',left(trim(p1)));
......
sas program.sas -sysparm "XYZ ABC OPQ"
Sunday, June 14, 2009
Using Macros to Skip a Section of Code
I. Statement Can Be Repeated Or Nested
SAS statements you want to execute.....
%macro SKIP ;
SAS statements you want to skip.....
%mend SKIP ;
SAS statements you want to execute.....
%macro SKIP ;
More SAS statements you want to skip.....
%mend SKIP ;
SAS statements you want to execute.....
II. Use NOSOURCE Option
Options Nosource;
%macro SKIP ;
SAS statements you want to skip.....
%mend SKIP ;
Options Source;
SAS statements you want to execute.....
