「CALL SYMPUT」 または 「CALL SYMPUTX」 で定義したマクロ変数が、ローカル・グローバルどちらになるのか解説します。
まずは前提知識。
マクロ変数を入れる箱の事をシンボルテーブルといいます。
・ローカルシンボルテーブル ・・・ ローカルマクロ変数を入れる箱
・グローバルシンボルテーブル ・・・ グローバルマクロ変数を入れる箱
図1
つまりマクロ変数がローカルなのか?グローバルなのか?という問題は、どちらのシンボルテーブルに入るかを問題としているわけです。
CALL SYMPUT で定義したマクロ変数の、ローカル・グローバルの判定方法
📝 説明の前に・・
SAS社のリファレンスの説明と実際の動作に差異があったため、私の実験結果に基づく動作の説明も含みます。何か不足している点など、お気づきの点がありましたらコメントいただけると幸いです。
つまりマクロ変数がローカルなのか?グローバルなのか?という問題は、どちらのシンボルテーブルに入るかを問題としているわけです。
📝 説明の前に・・
SAS社のリファレンスの説明と実際の動作に差異があったため、私の実験結果に基づく動作の説明も含みます。何か不足している点など、お気づきの点がありましたらコメントいただけると幸いです。
CALL SYMPUT が含まれるデータステップの「run;」がマクロの中にあるのか、マクロの外にあるのかで、ローカル・グローバルの判定結果が変わります。
マクロの中に「run;」がある
判定は以下のとおり。
マクロの中に「run;」がある
%macro TEST;
data _null_; call symput("MAC1", "1234"); run; %mend; %TEST; |
マクロ外に「run;」がある
data _null_;
call symput("MAC1", "1234"); run; |
判定は以下のとおり。
図2
具体例
では具体例をみていきましょう。
まず今回の解説で使うマクロ変数を予めリセット(削除)しときます。
%symdel MAC1 MAC2 MAC3 MAC4 MAC5 MAC6 MAC7 MAC8 MAC9 MAC10 / nowarn;
|
① マクロ外で定義したマクロ変数が、「グローバル」になる例。
data _null_;
call symput("MAC1","abcd"); run; %put _user_; GLOBAL MAC1 abcd |
② マクロ内で定義したマクロ変数が、「グローバル」になる例。
%macro TEST; data _null_; call symput("MAC2","abcd"); run;
%put _user_;
%mend;
%TEST; ログ GLOBAL MAC2 abcd |
③ マクロ内で定義したマクロ変数が、「ローカル」になる例。
%macro TEST; %let MAC3 = abcd; data _null_; call symput("MAC4","1234"); run; %put _user_; %mend; %TEST; ログ TEST MAC3 abcd TEST MAC4 1234 |
上のほうで示した「図2」のオレンジ色で示した「例外あり」のルートでは以下の例外が起きます。
① マクロ内で「SQLプロシジャ」の後に実行するCALL SYMPUTのマクロ変数は「ローカル」になる。
%macro TEST;
proc sql ; select * from SASHELP.CLASS; quit; data _null_; call symput("MAC5","abcd"); run; %put _user_;
%mend;
%TEST; ログ TEST MAC5 abcd |
② マクロ内で「%GOTO &マクロ変数」や「%GOTO %マクロ名」みたいな記述があると、その後のCALL SYMPUTのマクロ変数は「ローカル」になる。
③ マクロで「parmbuff」を使っていると、CALL SYMPUTのマクロ変数は「ローカル」になる。
失敗例
① たまに質問を頂くので注意喚起。
てことで、どうでしょう、、正直最初はなんじゃこりゃーって感じでいろんなシチュエーションがあって覚えらんないですよね。慣れれば、なんとなくわかってきます。
記事一覧
1. 基本概念
2. %LET編
3. CALL SYMPUT編
4. マクロ変数の展開
5. マクロ変数の作成場所を明示的に指定する
%let MAC6=GOGO; %macro TEST;
%goto &MAC6; %GOGO: data _null_; call symput("MAC7","1234"); run; %put _user_;
%mend;
%TEST; ログ TEST MAC7 1234 GLOBAL MAC6 GOGO |
③ マクロで「parmbuff」を使っていると、CALL SYMPUTのマクロ変数は「ローカル」になる。
%macro TEST / parmbuff;
data _null_; call symput("MAC8","1234"); run;
%put _user_;
%mend;
%TEST; ログ TEST MAC8 1234 |
CALL SYMPUTで定義したマクロ変数を同じデータステップ内で参照することは出来ません。
data _null_; call symput("MAC9","123"); x = &MAC9; run; ログ WARNING: MAC9のシンボリック参照を解決できません。 |
② これは上級者が遭遇する失敗例。
「CALL SYMPUTでマクロ変数を定義」&「そのマクロ変数を使用(参照)する」みたいなマクロがあったとして、そのマクロをCALL EXECUTEで実行すると、うまくマクロ変数の参照が出来ないようです。
%macro TEST; data _null_; call symput("MAC10","123"); run; %put &MAC10; %mend; data _null_; call execute('%TEST'); run; ログ WARNING: MAC10のシンボリック参照を解決できません。 |
SAS社のUsage Noteにも載ってました。
てことで、どうでしょう、、正直最初はなんじゃこりゃーって感じでいろんなシチュエーションがあって覚えらんないですよね。慣れれば、なんとなくわかってきます。
1. 基本概念
2. %LET編
3. CALL SYMPUT編
4. マクロ変数の展開
5. マクロ変数の作成場所を明示的に指定する
0 件のコメント:
コメントを投稿