マクロの引数にカンマ、クォートなどを渡す : %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      

参考

コメント

このブログの人気の投稿

日付フォーマットでない文字項目をSAS日付に変換するときにログ出力されるメッセージを抑制したい - SAS

Linuxコマンド: date で◯か月前 / ◯か月後を取得するときの注意

データセット(.sas7bdatファイル)の文字コードを取得したい - SAS