2016年5月26日木曜日

マクロ言語入門6:クォート処理【%BQUOTE関数】




%STR と %BQUOTE は同じクォート処理系の関数ですが、まったく異なる動きをします。



%STR関数の性質

%STRで囲った範囲の特殊文字をクォートする。



%BQUOTE関数の性質

%BQUOTEで囲った範囲に「クォート処理されていないマクロやマクロ変数」が含まれる場合は可能な限り展開してから、結果に含まれる特殊文字をクォートする。




具体例


以下は、変数Aに値を入れるマクロです。

%macro TEST( VAL );

       data DT1;
           length A $30.;
           A = "&VAL";
       run;

%mend;


このマクロを実行して変数Aに「A,B,C」という値を入れたいとします。

 
 A,B,C  


まどろっこしい書き方ですが、以下のように書いて実行すると、、

%let X= A,B,C;
%TEST( &X );

ログ
ERROR: マクロに定義された数よりも多い定位置パラメータが与えられています。

エラーが出ます。これは 「%TEST( &X );」 → 「%TEST( A,B,C );」という順に展開されるわけですが、
「%TEST(A,B,C)」にはカンマが含まれてるので「3つ引数があるのか」と解釈されてしまうからです。




%BQUOTE関数を使ってみる


マクロ変数Xを展開した後の値「A,B,C」をクォート処理したいので、%BQUOTE関数を使います。

%let X = A,B,C;
%TEST( %bquote(&X) );

 
 A,B,C  




%BQUOTE , %NRBQUOTE関数


%BQUOTE と %NRBQUOTE は同じ性質ですが、クォート対象の文字が異なります。

マクロ関数対象の文字
%BQUOTE






+ - * / < > = ¬ ^ ~ ; , # 半角スペース
AND OR NOT EQ NE LE LT GE GT IN ' " ( )

以下のようにクォートする文字としてカッコを含めて記述すると、SASが混乱してバグってしまうので注意
%bquote(aa(bb)
%bquote(aa)bb)
%NRBQUOTE




%BQUOTE関数と同じ+ & %

このマクロ関数は挙動を勘違いしやすいうえ、扱いづらいため個人的にはあまり使ってません。
以下「%NRBQUOTEの詳しい挙動」も要確認!



💬 %NRBQUOTEの詳しい挙動

例えば、以下2つのマクロ変数があったとします。
  • マクロ変数X: 「&Y」という値がクォート処理されずに格納されている
  • マクロ変数Y: 「&Z」という値がクォート処理されずに格納されている


これに対して、以下を実行すると、、

%put %nrbquote(&X);

%BQUOTE, %NRBQUOTEで囲った範囲の「クォート処理されていないマクロやマクロ変数」は可能な限り展開されるので、

→「&X」を展開すると「&Y」
→「&Y」を展開すると「&Z」
→「&Z」というマクロ変数は存在しないため、これ以上展開できない
→「&Z」を展開できない旨のWARNINGをログに出力


%NRBQUOTEは「&」もクォート対象になっているので、

→「&Z」というマクロ変数として解釈されないようクォート処理




実践例


%SYSFUNC関数を使う時によくクォート処理します。詳細は以下過去記事をご覧ください。



とにかくマクロ関数は複雑で、何故そうなるの?という挙動が沢山あります。
実際に使用する際は、結果をよく確認したほうが良さそうです。


0 件のコメント:

コメントを投稿