2

我正在使用 SAS 9.1.3 在 DATA 步骤中调用宏,但宏会生成 PROC REPORT 步骤,因此我使用 CALL EXECUTE 来调用它,生成所有这些 PROC REPORT 步骤,然后在数据步。

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

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;

问题是,报告输出(通常)向后输出 - 它会先打印 question3,然后是 2,然后是 1。

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

谢谢!

4

3 回答 3

5

我假设你的意思更像是你的call execute()线路:

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

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

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

日志

注意: CALL EXECUTE 生成的行。
1 + 数据 test_question1; 做 i=1 到 10000000;输出; 结尾; 跑;

注意:数据集 WORK.TEST_QUESTION1 有 10000000 个观察值和 1 个变量。
注意:使用的 DATA 语句(总处理时间):
      实时 6.14 秒
      处理器时间 0.45 秒


1 + ;
2 + 数据 test_question2; 做 i=1 到 10000000;输出; 结尾; 跑;

注意:数据集 WORK.TEST_QUESTION2 有 10000000 个观察值和 1 个变量。
注意:使用的 DATA 语句(总处理时间):
      实时 3.87 秒
      处理器时间 0.53 秒


2 + ;
3 + 数据 test_question3; 做 i=1 到 10000000;输出; 结尾; 跑;

注意:数据集 WORK.TEST_QUESTION3 有 10000000 个观测值和 1 个变量。
注意:使用的 DATA 语句(总处理时间):
      实时 3.12 秒
      处理器时间 0.45 秒
于 2009-09-04T14:57:38.973 回答
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
*/
于 2009-09-10T15:48:08.270 回答
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;
于 2009-09-04T19:00:58.503 回答