以下は、変数Aに値を入れるマクロです。
%macro TEST( VAL );
data DT1; length A $30.; A = "&VAL"; run; %mend; |
このマクロを実行して変数Aに「A,B,C」という値を入れたいとします。
A
|
---|
A,B,C
|
何も考えず書くと、、
%TEST(A,B,C);
ログ ERROR: マクロに定義された数よりも多い定位置パラメータが与えられています。 |
エラーが出ます。これは%TEST(A,B,C)にカンマが含まれてるので「3つ引数があるのか」と解釈されてしまうからです。
解決策
%STR関数で囲ってあげます。
%TEST( %str(A,B,C) );
|
%STR関数は、カンマやセミコロンなどSASの構文として意味のある特定の文字を、ただの文字として解釈させる関数です。
このただの文字として解釈させる事を「クォート処理」といいます。
関数によってクォート対象の文字が異なります。
マクロ関数 | 対象の文字 | 備考 |
---|---|---|
%STR | + - * / < > = ¬ ^ ~ ; , # 半角スペース AND OR NOT EQ NE LE LT GE GT IN | ' " ( ) 上記文字をクォートしたい場合、その文字の前に%をつける(%直後の1文字のみに効果がある) この方法の落とし穴を記事の下の方の例③に示しているので要確認!
|
%NRSTR | %STR関数と同じ+ & % | %STR関数と同じ |
ちなみに%NRSTR の先頭の「NR」は 「Not Resolved」の意味で、つまり「マクロやマクロ変数を展開させない」という意味合いがあります。
なので&や%がクォート対象となっています。
では最初に書いたマクロTESTを使って、クォート処理の例を紹介します。
(例③④は落とし穴的な挙動なので要注意です!)
例①
欲しい結果
「&Mrs」 というマクロ変数として解釈されないようクォート処理をします。
例②
シングルクォーテーションをクォート処理します。
「%JUICE」 というマクロとして解釈されないようクォート処理をします。
(おまけ) シングルクォートとダブルクォート
以下プログラムは、&Mrsというマクロ変数が指定されてると解釈されてしまい、ログにWARNINGが出ます。
しかし、以下はWARNINGが出ず期待通りの結果が得られます。
これは「シングルクォーテーションで囲まれた文字に&や%が含まれていても、ただの文字として解釈される」というルールがあるからです。
記事一覧
1. マクロ変数とは
2. マクロの登録と実行
3. 定位置パラメータ
4. キーワードパラメータ
5. クォート処理
6. クォート処理2
7. ループ処理
8. 条件分岐処理
9. ドット
10. &&
11. 演算評価
12. 補足
A
|
---|
Mr.&Mrs.Smith
|
「&Mrs」 というマクロ変数として解釈されないようクォート処理をします。
%TEST( %nrstr(Mr.&Mrs.Smith) );
|
欲しい結果
A
|
---|
It's a small world
|
シングルクォーテーションをクォート処理します。
%TEST( %str(It%'s a small world) );
|
例③
欲しい結果
A |
---|
100%JUICE |
「%JUICE」 というマクロとして解釈されないようクォート処理をします。
%TEST( %nrstr(100%JUICE) ); または %TEST( %nrstr(100%%)JUICE ); |
2個目の例を「%TEST( %nrstr(100%)JUICE )」とすると、、
%NRSTR関数での「%)」は「)」をクォート処理せよという命令になってしまいます(%NRSTR関数の閉じカッコがクォート処理されるのでSASの挙動もおかしくなる)
そこで%STR, %NRSTR関数内に「%%」と書くと、
- この「%」は直後の文字「'」「"」「(」「)」をクォートするという意味ではない、と命令する
- 「%%」は「%」に置き換わる
例④
コメントステートメントとして解釈されないようクォート処理をします。
欲しい結果
A |
---|
/* abcd */ |
コメントステートメントとして解釈されないようクォート処理をします。
%TEST( %str(/)%str(*) abcd %str(*)%str(/) ); |
「%TEST( %str(/* abcd */) )」という書き方はNG。%STR関数の中でもコメントステートメントとして認識されるからです。なので「/*」を1文字ずつ%STR関数で分けてクォート処理しています。
ちなみに、コメントステートメントの種類(「/* */」「* ;」「%* ;」)によってマクロ内での挙動が異なっているのが影響してますが、
ほしい結果が「* abcd ;」の場合は「%TEST( * abcd ; )」という書き方でOK。
ややこしい。。コメントステートメントを含む文字をクォート処理する場合は挙動確認したほうが良いです。
以下プログラムは、&Mrsというマクロ変数が指定されてると解釈されてしまい、ログにWARNINGが出ます。
data OUT1;
A = "Mr.&Mrs.Smith"; run; ログ WARNING: MRSのシンボリック参照を解決できません。 |
しかし、以下はWARNINGが出ず期待通りの結果が得られます。
data OUT2;
A = 'Mr.&Mrs.Smith'; run; |
これは「シングルクォーテーションで囲まれた文字に&や%が含まれていても、ただの文字として解釈される」というルールがあるからです。
2. マクロの登録と実行
3. 定位置パラメータ
4. キーワードパラメータ
5. クォート処理
6. クォート処理2
7. ループ処理
8. 条件分岐処理
9. ドット
10. &&
11. 演算評価
12. 補足
0 件のコメント:
コメントを投稿