Search code examples
macrossascode-readability

Is it possible to pass a macro into a macro?


In SAS I can use this handy snippet to do something like this.

%let listofvars = work.apples work.bananas work.oranges; 
%let var_no = 1;
%let var = %scan(&listofvars, &var_no, ' ');
%do %while (&var ne);
    proc sort data = &var; 
        by id;
    run; 

    %let var_no = %eval(&var_no +1);
    %let var = %scan(&listofvars, &var_no, ' ');
%end;

To sort each of those datasets.

I'd quite like to reduce the snippet to a loop macro, so I can do something like this:

%let setlist = work.apples work.bananas work.oranges;

%macro mymacro(dataset);
    proc sort data = &dataset.
    by id;
    run;
%mend;

%loop(&setlist, mymacro); 
/*the loop macro will know to pass the &var. in as a arguement to the macro*/ 

This will make for much better code readability.

Is this possible?


Solution

  • Yes. The name macro routine can be a macro. Macros "write" SAS code for you.

    %macro create(dataset);
    data &dataset;
    do i=1 to 10;
        id=rannor(0);
        output;
    end;
    run;
    %mend;
    
    %macro sort(dataset);
    proc sort data=&dataset;
    by id;
    run;
    %mend;
    
    %macro loop(list,mcr);
    %local i n val ;
    %let n=%sysfunc(countw(&list));
    %do i=1 %to &n;
        %let val = %scan(&list,&i);
        %&mcr(&val);
    %end;
    %mend;  
    
    %let sets = apples oranges pears;
    options mprint;
    %loop(&sets,create);
    %loop(&sets,sort);