2009-09-04 16 views
2

私はSAS 9.1.3を使用してDATAステップでマクロを呼び出していますが、マクロはPROCレポートステップを生成するので、コールするためにEXECUTEコールを使用し、PROCレポートステップをすべて生成してからすべて実行しますデータステップの後。SASでCALL EXECUTEスタックの実行順序を変更できますか?

私は配列を使用していて、マクロは、この配列内のすべての要素のためのたびに実行されます。

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の実行順序を変更する方法がありますので、質問レポートを順に印刷することができますか、それとも独自のことをするだけですか?

ありがとうございます!

答えて

5

私はあなたがyoutはcall execute()ラインのためのより多くのこのような何かを意味すると仮定します。私はcall execute() sが正しい順序で起こっていることを示し、このようないくつかのログの行を取得し、テストマクロで

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

。あなたは何か似ていますか?

マクロ

%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 
+0

うん、ハハ、変数に全体CONCATENATEを忘れてしまった;) はそうです、私はログに生成されたステップの正しい順序を得るが、彼らは出力に吐き出すされて起動したとき、彼らは何が完全に無秩序に見えているか(今私は5つの質問をテストとして使用しています)。 – chucknelson

+0

OK - テストをしてODSをHTMLに変換しました。そこにレポートテーブルが正しい順序であります。私はなぜODS LISTINGが異なる順序でそれらを出力に入れるのか理解していません。 – chucknelson

+0

CALL EXECUTEさんはうまく機能しており、順番に質問しています。 – chucknelson

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; 
+0

洞察をお寄せいただきありがとうございます。まだSASでは「マクロ言語」には達していません;)上記の例は、私の問題を説明するために単純化したものです。私は物事をループし、変数/質問のデータセットを読み込むためにDATAステップを使用しています - このものをハードコーディングするのではなく、haha。 – chucknelson

2

データステップがコンパイルされて実行されます。 call execute(str);はstrを入力キューにプッシュし、のデータステップが実行された後にがポップされるようにします。注文は保存され、期間です。

ただし、マクロの呼び出しを次のように二重引用符で囲んだ文字列に入れると、 が呼び出されます。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 
*/ 
関連する問題