Can I change the order of execution of the CALL EXECUTE stack in SAS?
I'm using SAS 9.1.3 to call a macro in the DATA step, but the macro generates a PROC REPORT step, so I use CALL EXECUTE to call it, generate all those PROC REPORT steps, and then execute them all after the DATA step.
I am using an array, and the macro is executed every time for every element in that array:
DATA macro_test;
ARRAY questions[3] $ 32 ('question1' 'question2' 'question3');
DO i=1 to 3;
a_question = questions(i);
CALL EXECUTE( "%report_by_question(a_question)" );
end;
RUN;
The point is that the report outputs go (usually) back - first it will print question3, then 2, then 1.
Is there a way to change the order in which the CALL EXECUTE is executed so that I can print reports on demand or do it myself?
Thank!
source to share
I assume you mean something more like the yout line call execute()
:
CALL EXECUTE( "%report_by_question(" || trim(left(a_question)) || ");" );
With a test macro, I get some log lines like this showing what is call execute()
happening in the correct order. Are you getting something like this?
Macro
%macro report_by_question(a);
data test_&a;
do i=1 to 10000000;
output;
end;
run;
%mend;
Magazines
NOTE: CALL EXECUTE generated line. 1 + data test_question1; do i = 1 to 10000000; output; end; run; NOTE: The data set WORK.TEST_QUESTION1 has 10000000 observations and 1 variables. NOTE: DATA statement used (Total process time): real time 6.14 seconds cpu time 0.45 seconds 1 +; 2 + data test_question2; do i = 1 to 10000000; output; end; run; NOTE: The data set WORK.TEST_QUESTION2 has 10000000 observations and 1 variables. NOTE: DATA statement used (Total process time): real time 3.87 seconds cpu time 0.53 seconds 2 +; 3 + data test_question3; do i = 1 to 10000000; output; end; run; NOTE: The data set WORK.TEST_QUESTION3 has 10000000 observations and 1 variables. NOTE: DATA statement used (Total process time): real time 3.12 seconds cpu time 0.45 seconds
source to share
The data step is compiled and then executed. call execute(str);
pushes str into the input queue so they pop out after the data step is done. Order is maintained, period.
However, if you put the macro call in a double-quoted string, this is how you do: call execute ("% report (q)"); then the macro is called when the data step is compiled, which is even before the data step starts.
If you do not want to call the macro at compile time, then either the macro or it is enclosed in a single quote. Below is an example. Hope this helps.
/* create a dataset with 1 var and 3 obs */
data qs;
input q $;
cards;
q1
q2
q3
;
run;
/* reporting macro -- a mockup */
%macro report(q=);
%put report for q=&q;
%mend report;
/* call the reporting macro for each q */
data _null_;
set qs;
macro = catx(q, '%report(q=', ')');
call execute(macro);
run;
/* on log
report for q=q1
report for q=q2
report for q=q3
*/
/* to show what happens when the
macro is invoked during the compile
time */
data _null_;
call execute("%report(q=q1)");
put "after call execute";
run;
/* on log
1 data _null_;
2 call execute("%report(q=q1)");
report for q=q1
3 put "after call execute";
4 run;
after call execute
*/
source to share
I prefer to do all macros using the macro language. I guess the tradeoff is that you have few macros scattered throughout your program. However, to prevent your program from generating reports, just comment out the macro call (*% loopit;) Also , you do not need to type "question1", "question2", "question3", etc.
Hope this is helpful to you!
%macro report_by_question(input);
%put "Question: " &input;
%mend;
%macro loopit;
%do i=1 %to 3;
%report_by_question("question&i.");
%end;
%mend loopit;
%loopit;
source to share