我可以在SAS中更改CALL EXECUTE堆栈的执行顺序吗?

时间:2009-09-04 14:36:14

标签: sas sas-macro

我正在使用SAS 9.1.3在DATA步骤中调用宏,但宏生成PROC REPORT步骤,因此我使用CALL EXECUTE调用它,生成所有这些PROC REPORT步骤,然后执行它们全部在DATA步骤之后。

我正在使用一个数组,每次为该数组中的每个元素执行宏:

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;

问题是,报告输出(通常)向后 - 它将首先打印问题3,然后打印2,然后打印1.

有没有办法修改CALL EXECUTE的执行顺序,这样我可以按顺序打印问题报告,还是只做自己的事情?

谢谢!

3 个答案:

答案 0 :(得分:5)

我认为你的意思更像是call execute()行:

 CALL EXECUTE( "%report_by_question(" || trim(left(a_question)) || ");" ); 

使用测试宏我得到一些这样的日志行,表明call execute()正在以正确的顺序发生。你有类似的东西吗?

%macro report_by_question(a);
data test_&a;
  do i=1 to 10000000;
    output;
  end;
run;
%mend;

日志

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

答案 1 :(得分:2)

编译数据步骤然后执行。 call execute(str);将str推入输入队列,以便在数据步骤完成执行后弹出。订单保留,期间。

但是,如果将宏调用放在双引号字符串中,则执行以下操作:     call execute(“%report(q)”); 然后在编译数据步骤时调用宏,这甚至在数据步骤开始运行之前。

如果您不想在编译时调用宏,则可以使用宏引用它,也可以将其放在单引号字符串中。以下是一个例子。希望这会有所帮助。

/* 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
*/

答案 2 :(得分:1)

我更喜欢使用宏语言做一切与宏相关的事情。我想权衡的是你的程序中散布的宏很少。但是,为了防止您的程序生成报告,只需注释掉宏调用(*%loopit;)另外,您不必输入“question1”,“question2”,“question3”等等!!!
希望这对你有用!

%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;