マクロの引数にカンマ、クォートなどを渡す : %bquote, %str, %superq - SAS
%bquote , %str などを用いて、マクロの引数に、カンマ、クォートといった記号を渡す方法です。何度か質問されたので、まとめてみます。
まずはサンプル用のマクロとして、マクロの引数に渡った値をログに出力するだけの単純なマクロを作ります。
%macro TEST(ARGS) ; %put &=ARGS. ; %mend TEST ;
まずは失敗例。下記のように、カンマやダブルクォーテーションを引数として渡そうとしてみます。しかし、カンマを付けてしまうと、"1"が 1つ目の引数の値、"2"が 2つ目の引数の値としてみなされてしまいます。マクロ定義の引数より多く引数を渡したと言われ、ERROR になってしまいます。
実行ログ 67 %TEST("1", "2") ; ERROR: マクロに定義された数よりも多い定位置パラメータが与えられています。 68
カンマやダブルクォーテーションを渡すためには、%bquote あるいは %str を使うことで、渡すことができます。
%str は、ダブルクォーテーションの前に % を書かないといけないので、少々面倒ですね。
実行ログ 69 %TEST(%bquote("1", "2")) ; ARGS="1", "2" 70 71 %TEST(%str(%"1%", %"2%")) ; ARGS="1", "2"
また、引数をマクロ変数にて、渡したい場合は %bquote を使うことでできます。%str だと渡すことができません。
実行ログ 61 %let ARGS = "1", "2" ; 62 %TEST(%bquote(&ARGS.)) ; ARGS="1", "2" 63 64 %let ARGS = ("1", "2") ; 65 %TEST(%bquote(&ARGS.)) ; ARGS=("1", "2") 66
カンマなどだけでなく、& や % を渡したい場合は、%nrstr , %nrbquote を使います。
実行ログ 61 %TEST(%nrstr(1 &test 2 & 100 %desu)) ; ARGS=1 &test 2 & 100 %desu 62 %let ARGS = "1" & "2" & 100% ; 63 64 %TEST(%nrbquote(&ARGS.)) ; ARGS="1" & "2" & 100% 65
ただし、%nrbquote は、&TEST や %TEST のように、& と % の次に文字が続くと、マクロ変数やマクロとみなされて、WARNING になってしまいます。
実行ログ 59 /* %let だと 展開してしまうので、シングルクォーテーションで囲って、call symputx にて、マクロ変数を定義 */ 60 /* シングルクォーテーションで囲った文字列内だと、マクロやマクロ変数は展開されません。 */ 61 data _null_ ; 62 call symputx('ARGS', '"1" &and "2" & 100%DESU ') ; 63 run ; 64 65 %TEST(%bquote(&ARGS.)) ; WARNING: ANDのシンボリック参照を解決できません。 WARNING: マクロDESUの呼び出しを解決できません。 WARNING: ANDのシンボリック参照を解決できません。 WARNING: マクロDESUの呼び出しを解決できません。 WARNING: ANDのシンボリック参照を解決できません。 WARNING: マクロDESUの呼び出しを解決できません。 ARGS="1" &and "2" & 100%DESU 66
& や % を含んだマクロ変数をマクロの引数として渡したい場合は、%superq を用います。%superq にマクロ変数を指定すると(&は書きません)、格納していた値が展開されますが、その中に &~ や %~ があっても、展開されることはありません。
実行ログ 61 data _null_ ; 62 call symputx('ARGS1', '"1" &and "2" & 100%DESU ') ; 63 run ; 65 %TEST(%superq(ARGS1)) ; ARGS="1" &and "2" & 100%DESU 66
コメント
コメントを投稿