前回の続きです。ちょっとした落とし穴を紹介。
まず以下の例を見てみましょう。
* マクロ変数を削除 ; %symdel X / nowarn; * call symputxでマクロ変数を作りログに出力 ; %macro TEST; data _null_; call symputx("X", "abcd"); run; %mend; %TEST; %put "&X"; |
ログ "abcd" |
ログを見てみると、問題なくマクロ変数を参照できてますね。
では次のプログラムはどうでしょうか?
* マクロ変数を削除 ; %symdel X2 X3 / nowarn; * call symputxでマクロ変数を作りログに出力 ; %macro TEST2; %let X2=1; data _null_; call symputx("X3", "abcd"); run; %mend; %TEST2; %put "&X3"; |
ログ WARNING: 記号参照X3を展開していません。 |
WARNINGが出て参照できませんでした。
最初のマクロとの違いと言えば「%let X2=1;」が追加されたくらいですが、実はこれが影響してます。
超ざっくり説明すると、「%let X2=1;」はマクロTEST2の中で定義してるマクロ変数で、いわゆるローカルマクロ変数(以下参照)です。
ローカルマクロ変数: そのマクロ内でしか参照できないマクロ変数(マクロが実行終了すると消去される)
グローバルマクロ変数: どの場所からでも参照できるマクロ変数
|
マクロの中でひとつでもローカルマクロ変数があると、同マクロ内に書かれたCALL SYMPUTXの結果もローカルマクロ変数となります。(グローバルマクロ変数になる場合もある。詳細はこちらを参照)
もしグローバルマクロ変数に変えたい場合、はじめに「%GLOBAL マクロ変数名;」を追記すればOK。
逆にローカルマクロ変数にしたい場合は、%LOCALステートメントを追記します。
またSYMPUTにはなくSYMPUTXのみの機能として以下のように書けちゃいます。
call symputx("X3", "abcd" , "G") ; "G" … グローバルマクロ変数にする。 "L" … ローカルマクロ変数にする(マクロ外で実行するとグローバルマクロ変数になる) |
この点もCALL SYMPUTXを使うメリットだと思います。
釈然としなかった問題でした。素晴らしい!
返信削除ありがとうございます!
返信削除コメント頂けると励みになります。