前のページ|次のページ

マクロのトラブルシューティング

よくあるマクロ問題を解決する

マクロ機能を操作したときに発生する可能性のある問題の一部を、次の表に示します。これらの問題の多くは、エラーメッセージがSASログに書き込まれないため、解決することが困難です。表には、問題ごとに考えられる原因と解決策を示します。
よく発生するマクロ問題
問題
原因
説明
マクロ定義のサブミット後、SASウィンドウ環境のセッションが応答しなくなる。コードを入力してサブミットしても、何も起こらない。
  • %MENDステートメントの構文エラー
  • セミコロン、かっこ、または引用符の欠損
  • %MENDステートメントの欠損
  • コメントが閉じられていない
%MENDステートメントが認識されないため、すべてのテキストがマクロ定義の一部になっています。
マクロの呼び出し後、SASウィンドウ環境のセッションが応答しなくなる。
呼び出しに関するエラー。パラメータ付きで定義されたマクロを呼び出す場合の、1つ以上のパラメータの指定もれ、かっこの不足など。
マクロ機能は、ユーザーが呼び出しを終了するまで待機します。
マクロをサブミットしてもコンパイルされない。
マクロ定義内のどこかに構文エラーがある。
コンパイルされるのは、構文的に正しいマクロのみです。
マクロを呼び出しても実行されないか、一部実行されてから停止する。
  • 不正な値が(たとえばパラメータとして)マクロに渡された。
  • マクロ定義内のどこかに構文エラーがある。
マクロは、受け取るパラメータの数が正しく、パラメータのタイプが正しい場合にのみ、正常に実行されます。
マクロは実行されるが、SASコードが不正な結果を返すか、結果を何も返さない。
マクロまたはSASコードのロジックが不正。
コードが、オープンコードとしてサブミットされると正しく動作するが、マクロによって生成されると動作せず、不明なエラーメッセージを発行する。
  • 意図したとおりにトークン化されていない。
  • マクロ定義内のどこかに構文エラーがある。
まれに、マクロクォーティング関数が、渡されたテキストのトークン化を変更する場合があります。%UNQUOTE関数を使用してください。
%MACROステートメントが、"無効なステートメント"エラーを生成する。
  • MACROシステムオプションを無効にしている。
  • マクロ定義内のどこかに構文エラーがある。
マクロ機能が動作するには、MACROシステムオプションが有効である必要があります。SAS構成ファイルを適宜編集してください。
一般的なマクロエラーと警告メッセージの一部を、次の表に示します。メッセージごとに問題の原因を示し、詳細情報へのリンクを示します。
一般的なマクロエラーメッセージと原因
エラーメッセージ
考えられる原因
詳細情報
Apparent invocation of macro xxx not resolved.
  • マクロ名にスペルミスがある。
  • MAUTOSOURCEシステムオプションを無効にしている。
  • MAUTOSOURCEは有効だが、SASAUTOS=システムオプションで不正なパス名を指定している。
  • 自動呼び出し機能を使用しているが、マクロ名とファイル名に別の名前を与えている。
  • 自動呼び出し機能を使用しているが、ファイル名に.sas拡張子を付けていない。
  • マクロ定義内に構文エラーがある。
Apparent symbolic reference xxx not resolved.
  • マクロ変数を作成したCALL SYMPUTと同じDATAステップ内で、そのマクロ変数を置換しようとしている。
  • マクロ変数名にスペルミスがある。
  • 範囲外のマクロ変数を参照している。
  • マクロ変数の末尾にテキストを追加するときに、ピリオドの区切り文字を付け忘れた。
マクロ機能のエラーメッセージと警告のリストについては、 SASマクロのエラーメッセージおよび SASマクロ警告メッセージを参照してください。

マクロ変数の置換の問題を解決する

マクロプロセッサは、&が前に付いたトークン名を調べるときに、それに一致するマクロ変数のエントリをマクロシンボルテーブル内で検索します。マクロプロセッサは、一致するエントリを見つけると、シンボルテーブルから関連付けられたテキストを取り出して、入力スタックにある&nameをそのテキストに置き換えます。マクロ変数名がマクロプロセッサに渡されて、一致するエントリがシンボルテーブル内で検出されなかった場合、入力スタックのトークンは置換されず、次のメッセージが生成されます。
WARNING: Apparent symbolic reference
NAME not resolved.
置換されないトークンは、SASの他の部分で使用するために、入力スタックに転送されます。
注: SERRORシステムオプションを有効にした場合にのみ、警告メッセージが表示されます。
これらの問題を解決するには、マクロ変数名を正しく記述しており、適切なスコープ内で参照していることを確認します。
マクロ変数は置換されるが、正しい値に置換されない場合、いくつかの項目を確認できます。まず、変数が計算の結果である場合、正しい値を計算に渡していることを確認します。また、不注意にグローバル変数の値を変更していないことも確認します。(変数のスコープの問題については、マクロ変数のスコープの問題を解決するを参照してください。)
別のよくある問題は、マクロ変数の末尾にテキストを追加したが、マクロ変数名の末尾と追加したテキストの先頭を示す区切り文字を、挿入し忘れることです。たとえば、WEEK1、WEEK2などへの参照を含むTITLEステートメントを記述する場合を考えます。次に示すように、これらの文字列の前の部分(WEEK)をマクロ変数に設定し、TITLEステートメント内でWEEKの番号を指定します。
%let wk=week;

title "This is data for &wk1";   /* INCORRECT */
これらのステートメントをコンパイルすると、マクロプロセッサは、WKではなくWK1という名前のマクロ変数を検索します。この問題を修正するには、次のステートメントに示すように、マクロ変数名の末尾と追加したテキストとの間にピリオド(マクロ区切り文字)を追加します。
%let wk=week;

title "This is data for &wk.1";
注意:
マクロ変数名では、AF、DMS、またはSYSを接頭語として使用しないでください。
AF、DMS、およびSYSという文字列は、SASが作成するマクロ変数の接頭語として頻繁に使用されます。SASでは、AF、DMS、またはSYSをマクロ変数名の接頭語として使用することは、禁止されていません。ただし、これらの文字列を接頭語として使用すると、ユーザーが指定した名前とSASが作成したマクロ変数(将来のSASのリリースでの自動マクロ変数を含む)の名前との間に、競合が発生する恐れがあります。名前の競合が発生した場合、競合の内容によっては、警告メッセージやエラーメッセージが発行されないことがあります。そのため、マクロ名およびマクロ変数名の文字列の先頭には、AF、DMS、またはSYSという文字列を使用しないことをお勧めします。

マクロ変数のスコープの問題を解決する

マクロ変数でよく発生する間違いは、マクロ変数のスコープの外にあるローカルマクロ変数参照に関連しています。マクロ変数のスコープ で説明されているように、マクロ変数はグローバルまたはローカルのいずれかです。スコープ外の変数を参照すると、マクロプロセッサは、その変数参照を置換できません。たとえば、次のプログラムについて考えます。
%macro totinv(var);
   data inv;
      retain total 0;
      set Sasuser.Houses end=final;
      total=total+&var;
      if final then call symput("macvar",put(total,dollar14.2));
   run;
   %put **** TOTAL=&macvar ****;
%mend totinv;

%totinv(price)
%put **** TOTAL=&macvar ****;   /* ERROR */
これらのステートメントをサブミットすると、マクロTOTINV内の%PUTステートメントによって、TOTALの値がログに書き込まれます。マクロ呼び出しの後の%PUTステートメントによって警告メッセージが生成され、テキストTOTAL=&macvarが次のようにログに書き込まれます。
TOTAL= $1,240,800.00
WARNING: Apparent symbolic reference MACVAR not resolved.
**** TOTAL=&macvar ****
2番目の%PUTステートメントは、マクロ変数MACVARがTOTINVマクロに対してローカルであるため、実行に失敗します。エラーを修正するには、%GLOBALステートメントを使用して、マクロ変数MACVARを宣言する必要があります。
マクロ変数でよく発生する別の間違いは、マクロ変数名の重複に関連します。マクロ定義内で、グローバルマクロ変数と同じ名前のマクロ変数を参照した場合、グローバル変数に影響を与えます。その影響は、意図したものではない場合があります。重複しない名前をマクロ変数に与えるか、%LOCALステートメントを使用して、変数のスコープをローカルとして明確に定義するようにしてください。この手法の例については、マクロ変数をローカルにするを参照してください。

オープンコードステートメントの再帰問題を解決する

再帰とは、自分自身を呼び出すことです。オープンコードの再帰は、オープンコードによって、マクロステートメントによる別のマクロステートメントの呼び出しが誤って生じた場合に発生します。この呼び出しは、再帰参照と呼ばれます。オープンコードの再帰を引き起こす最もよくあるエラーは、セミコロンの欠損です。次の例では、%LETステートメントがセミコロンで終わっていません。
%let a=b   /* ERROR */
%put **** &a ****;
マクロプロセッサは、%LETステートメント内で%PUTステートメントを検出すると、次のエラーメッセージを生成します。
ERROR: Open code statement recursion detected.
通常、オープンコードの再帰エラーは、マクロプロセッサがマクロステートメントを意図されたとおりに読み込まないために発生します。オープンコードの再帰エラーは、ほとんどがコードのタイプミスによって生じ、実行ロジックのエラーではないため、通常は慎重に校正することによって解決できます。
オープンコードの再帰エラーから回復するには、まず、1つのセミコロンをサブミットしてみます。これで効果がない場合は、次の文字列をサブミットしてみます。
*'; *"; *); */; %mend; run;
次のメッセージがSASログに表示されるまで、この文字列のサブミットを続けます。
ERROR:No matching %MACRO statement for this %MEND statement.
この方法で効果がない場合は、SASセッションを閉じてSASを再起動します。当然ながら、SASを閉じて再起動すると、保存されていないデータはすべて失われます。マクロの開発中は必ず頻繁に保存するようにし、それらのマクロをサブミットする前に、必ず慎重に校正してください。

マクロ関数の問題を解決する

マクロ関数の問題のよくある原因としては、次のようなものがあります。
  • 関数名のスペルミス
  • 左かっこまたは右かっこの付け忘れ
  • 引数の指定もれ、または余分な引数の指定
マクロ関数に関連するエラーが発生した場合に、他のエラーメッセージも表示されることがあります。それらのメッセージは、入力スタックに無効なトークンが残っていることにより、マクロプロセッサによって生成されます。
次に示す例について考えます。この例では、%SUBSTR関数を使用して、マクロ変数LINCOLNの値の一部をマクロ変数SECONDWDに割り当てようとしています。しかし、2番目の%LETステートメントにタイプミスがあり、%SUBSTRが誤って%SUBSRTと記述されています。
%macro test;
%let lincoln=Four score and seven;
%let secondwd=%subsrt(&lincoln,6,5);   /* ERROR */
%put *** &secondwd ***;
%mend test;

%test
この誤りのあるプログラムをサブミットすると、次のメッセージがSASログに表示されます。
WARNING:Apparent invocation of macro SUBSRT not resolved.
このエラーメッセージは、誤って記述された関数名をはっきりと指摘しています。

未置換のマクロの問題を解決する

マクロプロセッサにマクロ名が渡されたが、マクロプロセッサがそれに対応するマクロ定義を検出できなかった場合、次のメッセージが生成されます。
WARNING: Apparent invocation of macro
NAME not resolved.
このエラーの原因として、次のことが考えられます。
  • マクロ名またはマクロ関数名のスペルミス
  • マクロ定義内のエラーにより、マクロがダミーマクロとしてコンパイルされた
ダミーマクロとは、マクロプロセッサによって部分的にコンパイルされるが保存されないマクロのことです。
注: MERRORシステムオプションを有効にした場合にのみ、この警告メッセージが表示されます。

“ブラックホール”マクロ問題を解決する

マクロプロセッサは、マクロ定義のコンパイルを開始すると、対応する%MENDステートメントを検出するまでトークンを読み込み、コンパイルします。%MENDステートメントの記述が抜けている場合、または前のステートメントでセミコロンを付け忘れたことによって%MENDステートメントが認識されなかった場合、マクロプロセッサはトークンのコンパイルを停止しません。サブミットしたすべてのコード行は、マクロの一部になります。
マクロ定義に%MEDステートメントを追加して再サブミットしても、エラーは修正されません。修正したマクロ定義をサブミットすると、マクロプロセッサは、そのマクロ定義を、修正前のマクロ定義内でネストされているものとして扱います。コンパイルを停止するには、マクロプロセッサによって、対応する%MENDステートメントが検出される必要があります。
注: %MACROステートメントと%MENDステートメントの対応付けが容易になるように、マクロ名を指定して%MENDステートメントを使用することをお勧めします。
サブミットしたステートメントがSASによって処理されていないと判断した場合、回復方法がわからなければ、一度に1つの%MENDステートメントをサブミットしてみて、次のメッセージがSASログに表示されるまでそれを繰り返します。
ERROR:No matching %MACRO statement for this %MEND statement.
その後、元のエラーを含むマクロ定義を再び呼び出し、%MENDステートメントのエラーを修正してから、そのマクロ定義をサブミットしてコンパイルします。
他にも、同様の問題を引き起こす構文エラーがあります。たとえば、一致しない引用符や、閉じていないかっこなどです。多くの場合、これらの構文エラーのいずれかが他の問題を引き起こしています。次の例について考えてみます。
%macro rooms;
   /* other macro statements& */
   %put **** %str(John's office) ****;   /* ERROR */
%mend rooms;

%rooms
これらのステートメントをサブミットすると、マクロプロセッサは、マクロ定義ROOMSのコンパイルを開始します。ところが、%PUTステートメント内の一重引用符に、パーセント記号のマークが付けられていません。そのため、コンパイル時にマクロプロセッサは、この一重引用符をリテラルトークンの先頭と解釈します。その場合、右かっこ、ステートメントの末尾のセミコロン、またはマクロ定義の最後にある%MENDステートメントが認識されません。
このエラーから回復するには、次の文字列をサブミットする必要があります。
');
%mend;
この方法で効果がない場合は、次の文字列をサブミットしてみます。
*'; *"; *); */; %mend; run;
次のメッセージがSASログに表示されるまで、この文字列のサブミットを続けます。
ERROR:No matching %MACRO statement for this %MEND statement.
エラーが実際に発生する前に、それらを検出した方が、明らかに簡単です。マクロをサブミットしてコンパイルする前に、それらを入念に確認することで、細かい構文エラーを回避できます。構文チェックリストについては、バグのないマクロの開発を参照してください。
注: 説明の付かない予想外のマクロの動作を引き起こす別の原因として、マクロ変数名またはマクロ名として予約語を使用することが挙げられます。たとえば、SASではSYSで始まる名前が予約されているため、SYSで始まる名前のマクロおよびマクロ変数を作成することはできません。ほとんどのホスト環境にも、予約語があります。たとえば、PCベースのプラットフォームでは、コンソール入力用として、CONという予約語があります。予約済みのSASキーワードについては、 マクロ機能の予約語を参照してください。ホスト環境の予約語については、SASドキュメントを確認してください。

タイミングの問題を解決する

多くのマクロエラーは、ユーザーが意図したタイミングとは異なるタイミングでマクロ変数が置換された場合、またはユーザーが期待するタイミングでマクロステートメントが実行されなかった場合に発生します。タイミングの重要性を示す主な例として、CALL SYMPUTを使用してDATAステップ変数をマクロ変数に書き込む場合が挙げられます。このマクロ変数は、それを定義した同じDATAステップ内では使用できません。その後のステップ(DATAステップのRUNステートメントの後)でのみ使用できます。
タイミングエラーを防ぐには、マクロプロセッサがどのように動作するかを理解することが重要です。簡単に説明すると、コンパイルと実行という2つの主なステップがあります。コンパイルステップは、すべてのマクロコードをコンパイル済みコードに置換します。次に、そのコードが実行されます。ほとんどのタイミングエラーは、次の理由によって発生します。
  • コンパイル中に起きると期待されていることが、実際には実行されるまで起きない場合。
  • 後で起きると期待されていることが、実際には即座に実行された場合。
以降では、コンパイルと実行のタイミングがなぜ重要になるかについて、理解に役立つ2つの例を示します。

直ちに実行するマクロステートメントの例

次のプログラムでは、%LETステートメントとSR_CIT変数を使用して、データセットに高齢者のデータが含まれているかどうかを示そうとしています。
data senior;
   set census;
   if age > 65 then
   do;
      %let sr_cit = yes;  /* ERROR */
      output;
   end;
run;
しかし、得られる結果は、期待する結果とは異なります。%LETステートメントは、DATAステップがコンパイルされている間、つまりデータセットが読み込まれる前に、即座に実行されます。そのため、%LETステートメントは、IF条件の結果とは無関係に実行されます。65よりも大きいAGEの値を持つオブザベーションがデータセットに含まれない場合でも、SR_CITは常にyesになります。
これを解決するには、IFロジックによって制御し、IFステートメントがtrueの場合にのみ実行するという方法で、マクロ変数の値を設定します。この場合、次の正しいプログラムのように、CALL SYMPUTステートメントを使用する必要があります。
%let sr_cit = no;
data senior;
   set census;
   if age > 65 then
   do;
      call symput ("sr_cit","yes");
    output;
   end;
run;
このプログラムをサブミットすると、65よりも大きいAGEの値を持つオブザベーションが検出された場合にのみ、SR_CITの値はyesに設定されます。なお、SR_CITの値はnoに初期設定されています。通常、マクロ変数を初期化しておくのは良いことです。

DATAステップのコンパイル時のマクロ置換の問題を解決する

前の例では、DATAステップ内のマクロ変数に条件付きで値を割り当てるには、CALL SYMPUTを使用する必要があるということを学習しました。そのため、次のプログラムをサブミットします。
%let sr_age = 0;
data senior;
   set census;
   if age > 65 then
   do;
      call symput("sr_age",age);
      put "This data set contains data about a person";
      put "who is &sr_age years old."; /* ERROR */
   end;
run;
AGEの値が67である場合、次のようなログメッセージが表示されることが期待できます。
This data set contains data about a person
who is 67 years old.
しかし実際は、AGEの値に関係なく、次のメッセージがログに出力されます。
This data set contains data about a person
who is 0 years old.
DATAステップがコンパイルされるときに、&SR_AGEがマクロ機能に渡されて置換されます。その置換結果が返されて、DATAステップが実行されます。目的の結果を得るには、代わりに、修正された次のプログラムをサブミットします。
%let sr_age = 0;
data senior;
   set census;
   if age > 65 then
   do;
      call symput("sr_age",age);
      stop;
   end;
run;

data _null_;
   put "This data set contains data about a person";
   put "who is &sr_age years old.";
run;
注: PUTのようなステートメントでは、二重引用符を使用します。これは、一重引用符で囲むとマクロ変数が置換されないためです。
マクロ変数が作成されたのと同じステップ内で、そのマクロ変数を誤って参照している別の例を次に示します。
data _null_;
   retain total 0;
   set mydata end=final;
   total=total+price;
   call symput("macvar",put(total,dollar14.2));
   if final then put "*** total=&macvar ***"; /* ERROR */
run;
これらのステートメントをサブミットすると、次の行がSASログに書き込まれます。
WARNING:Apparent symbolic reference MACVAR not resolved.*** total=&macvar ***
このDATAステップがトークン化され、コンパイル化されるときに、ワードスキャナが&を検出してマクロプロセッサを起動します。起動されたマクロプロセッサは、シンボルテーブル内のMACVARエントリを検索します。そのようなエントリが存在しないため、マクロプロセッサは警告メッセージを生成します。入力スタックにトークンが残っているため、それらのトークンがDATAステップコンパイラに転送されます。DATAステップの実行中に、CALL SYMPUTステートメントによってマクロ変数MACVARが作成され、それに値が割り当てられます。ところが、PUTステートメントには、&macvarというテキストが生成されます。これは、マクロのコンパイル中に、このテキストがすでに処理されたためです。これらのステートメントを再びサブミットして、マクロが正常に動作したように見えたとしても、そのMACVARの値は、前回のDATAステップの実行時に設定された値を反映しています。この値は、誤解を招く場合があります。
通常、%&は、他のSASコードのコンパイル時に、直ちに実行または置換を引き起こします。このことを覚えておいてください。
CALL SYMPUTを使用してマクロ変数を作成するその他の例および説明については、CALL SYMPUTルーチンを使用したスコープの特殊なケースを参照してください。

自動呼び出し機能の問題を解決する

プロダクション(デバッグ済み)マクロを保存して使用する場合、自動呼び出し機能は有効な手段になります。自動呼び出しマクロの呼び出しでエラーが発生した場合、その原因は次の2つのうちのいずれかです。
  • 間違った自動呼び出しライブラリの指定
  • 無効な自動呼び出しマクロ定義
エラーが自動呼び出しライブラリ指定にある場合、MERRORオプションが設定されていれば、SASによって、次の警告メッセージのいずれか、またはすべてが生成されることがあります。
WARNING: No logical assign for filename
FILENAME.
WARNING: Source level autocall is not found or cannot be opened.
         Autocall has been suspended and OPTION NOMAUTOSOURCE has
         been set. To use the autocall facility again, set OPTION
         MAUTOSOURCE.
WARNING: Apparent invocation of macro
MACRO-NAME not resolved.
エラーが自動呼び出しマクロ定義にある場合、SASによって次のようなメッセージが生成されます。
NOTE: Line generated by the invoked macro
"MACRO-NAME".

自動呼び出しライブラリ指定の修正

自動呼び出しライブラリの指定によってエラーが発生した場合、その原因は、マクロプロセッサが、SASAUTOSシステムオプションで指定された1つまたは複数のライブラリから、自動呼び出しマクロ定義を含むメンバを検出できなかったためです。
このエラーを修正するには、次の手順に従います。
  1. 未置換のマクロ呼び出しによって無効なSASステートメントが作成された場合、1つのセミコロンをサブミットして、無効なステートメントを終了させます。その後、SASは、以降のステートメントを正しく認識できます。
  2. OPTIONSプロシジャの出力を表示するか、SASウィンドウ環境でOPTIONSウィンドウを参照することによって、SASAUTOSシステムオプションの値を調べます(あるいは、SAS構成ファイルまたはSAS AUTOEXECファイルを編集します)。各ファイル参照名またはディレクトリ名を確認します。エラーが見つかった場合、新しいOPTIONSステートメントをサブミットするか、OPTIONSウィンドウでSASAUTOSの設定を変更します。
  3. MAUTOSOURCEシステムオプションを確認します。SASは、ライブラリを1つも開けなかった場合、NOMAUTOSOURCEオプションを設定します。NOMAUTOSOURCEが存在する場合、新しいOPTIONSステートメントまたはOPTIONSウィンドウを使用して、MAUTOSOURCEをリセットします。
  4. ライブラリ指定が正しい場合、各ディレクトリの内容を調べて、自動呼び出しライブラリメンバが存在し、それに同じ名前のマクロ定義が含まれていることを確認します。メンバが欠損している場合は、それを追加します。
  5. 新しいOPTIONSステートメントまたはOPTIONSウィンドウを使用して、MRECALLオプションを設定します。デフォルトでは、マクロプロセッサは、未定義のマクロを一度だけ検索します。このオプションを設定すると、マクロプロセッサは、指定された自動呼び出しライブラリを再検索します。
  6. 自動呼び出しマクロのソースを含む自動呼び出しマクロを呼び出し、それをサブミットします。
  7. NOMRECALLオプションをリセットします。
注: 一部のホスト環境は、SASAUTOSライブラリに割り当てられている環境変数やシステムレベルの論理名を持つ場合があります。お使いのホスト環境でのSASAUTOSライブラリ指定の処理方法に関する詳細は、お使いの動作環境に対応するSASドキュメントを参照してください。

自動呼び出しマクロ定義エラーの修正

自動呼び出し機能によって自動呼び出しライブラリメンバが検出されると、マクロプロセッサは、そのライブラリメンバに含まれるすべてのマクロをコンパイルします。コンパイルされたマクロは、コンパイル済みマクロが含まれるカタログに保存されます。SASセッションの他の部分では、これらのマクロのいずれかを呼び出すことによって、WORKライブラリからコンパイル済みマクロを取り出します。いかなる状況であっても、自動呼び出し機能は、同じ名前のコンパイル済みマクロがすでに自動呼び出しライブラリメンバに存在する場合、そのメンバを使用します。そのため、自動呼び出しマクロを呼び出したときに、その自動呼び出しマクロ定義にエラーがあることがわかった場合、今後の使用のために、自動呼び出しライブラリメンバを修正する必要があります。プログラム内またはセッション内で、修正したバージョンを直接コンパイルします。
ウィンドウ環境で自動呼び出しマクロ定義を修正するには、次の手順を実行します。
  1. INCLUDEコマンドを使用して、自動呼び出しライブラリメンバをSASプログラムエディタウィンドウに表示します。マクロがカタログのSOURCEエントリに保存されている場合、COPYコマンドを使用して、そのプログラムをプログラムエディタウィンドウに表示します。
  2. エラーを修正します。
  3. 修正したマクロのコピーを、そのマクロが外部ファイル内にある場合はFILEコマンドを使用し、カタログエントリ内にある場合はSAVEコマンドを使用して、自動呼び出しライブラリに保存します。
  4. プログラムエディタウィンドウから、マクロ定義をサブミットします。
その後、修正したバージョンがマクロプロセッサによってコンパイルされ、エラーのあるコンパイル済みマクロと置き換えられます。これで、修正したコンパイル済みマクロを次の呼び出しで実行する準備が整いました。
自動呼び出しマクロ定義を対話的なラインモードセッションで修正するには、次の手順を実行します。
  1. 自動呼び出しマクロのソースを、テキストエディタを使用して編集します。
  2. エラーを修正します。
  3. %INCLUDEステートメントを使用して、修正したライブラリメンバをSASセッションで表示します。
その後、修正したバージョンがマクロプロセッサによってコンパイルされ、エラーのあるコンパイル済みマクロと置き換えられます。これで、修正したコンパイル済みマクロを次の呼び出しで実行する準備が整いました。

自動呼び出しファイル名とマクロ名

マクロを自動呼び出しマクロとして使用する場合、そのマクロを、それと同じ名前のファイルに保存する必要があります。また、ファイル拡張子も必要です.sas(オペレーティングシステムがファイル拡張子を使用している場合)。自動呼び出し機能で問題が発生した場合は、マクロ名とファイル名が一致していることを必ず確認し、必要に応じてファイルの拡張子が正しいことを確認してください。

コンパイル済みマクロに関する情報の表示

コンパイル済みマクロを含むカタログ内のエントリの一覧を表示するには、カタログウィンドウまたはCATALOGプロシジャを使用します。次のPROCステップは、ライブラリ参照名MYSASLIBで指定したSASライブラリ内のマクロカタログの内容を表示します。
libname mysaslib
'SAS-library';
   proc catalog catalog=mysaslib.sasmacr;
      contents;
   run;
   quit;
PROC CATALOGを使用して、カタログ内のSOURCEエントリに保存された自動呼び出しライブラリのマクロに関する情報を表示することもできます。コンパイル済みマクロをコピー、削除、または名前変更するために、PROC CATALOGまたはエクスプローラウィンドウを使用することはできません。
MCOMPILENOTEシステムオプションを使用して、マクロのコンパイルが完了した際にログにメモを出力することができます。詳細については、MCOMPILENOTEシステムオプションを参照してください。
SAS 6.11以降では、PROC SQLを使用して、すべてのコンパイル済みマクロに関する情報を取得できます。たとえば、次のステートメントをサブミットすると、次に示すような出力が生成されます。
proc sql;
   select * from dictionary.catalogs
        where memname in ('SASMACR');
コンパイル済みマクロを表示するためのPROC SQLプログラムの出力
Library Member Member Object Object Date Object Name Name Type Name Type Object Description Modified Alias ------------------------------------------------------------------------------------------- WORK SASMACR CATALOG FINDAUTO MACRO 05/28/96 SASDATA SASMACR CATALOG CLAUSE MACRO Count words in clause 05/24/96 SASDATA SASMACR CATALOG CMPRES MACRO CMPRES autocall macro 05/24/96 SASDATA SASMACR CATALOG DATATYP MACRO DATATYP autocall macro 05/24/96 SASDATA SASMACR CATALOG LEFT MACRO LEFT autocall macro 05/24/96
コンパイル済みマクロを呼び出すときに、それらの情報を表示するには、SASシステムオプションのMLOGIC、MPRINT、およびSYMBOLGENを使用します。SASシステムオプションMLOGICを指定すると、マクロの実行中に表示される通常の情報と共に、ライブラリ参照名、およびコンパイル済みマクロがコンパイルされた日付がログに書き込まれます。

式の評価の問題を解決する

次のマクロステートメントは、%EVAL関数を使用します。
%EVAL関数を使用するマクロステートメント
%DO
%IF-%THEN
%SCAN
%DO %UNTIL
%QSCAN
%SYSEVALF
%DO %WHILE
%QSUBSTR
%SUBSTR
また、%EVAL関数を使用して、式の評価を指定できます。
式の評価中における最もよくあるエラーは、数値オペランドが必要とされる場所に文字オペランドが存在するか、トークンが数値演算子なのか文字値なのかがあいまいな場合に発生します。マクロ式で、これらおよびその他のマクロ式に関するエラーについて説明しています。
特殊文字やキーワードが文字列に現れる場合、頻繁にエラーが発生します。次のプログラムについて考えます。
%macro conjunct(word= );
   %if &word = and or &word = but or &word = or %then   /* ERROR */
      %do %put *** &word is a conjunction. ***;

   %else
      %do %put *** &word is not a conjunction. ***;
%mend conjunct;
この%IFステートメントでは、テストされるWORDの値があいまいです。これらの値は、数値演算子ANDおよびORとしても解釈できます。そのため、次のエラーメッセージがログに生成されます。
ERROR: A character operand was found in the %EVAL function or %IF
       condition where a numeric operand is required. The condition
       was:word = and or      &word = but or       &word = or
ERROR: The macro will stop executing.
この問題を修正するには、次の修正済みプログラムに示すように、クォーティング関数%BQUOTEおよび%STRを使用します。
%macro conjunct(word= );
   %if %bquote(&word) = %str(and) or %bquote(&word) = but or
          %bquote(&word) = %str(or) %then
      %do %put *** &word is a conjunction. ***;

   %else
      %do %put *** &word is not a conjunction. ***;
%mend conjunct;
この修正済みプログラムでは、%BQUOTE関数によってマクロ変数の置換結果をクォーティングしています(一致しない引用符などの半端な値を含むワードを渡す場合)。%STR関数は、比較する値ANDおよびORを、コンパイル時にクォーティングします。そのため、これらの値はあいまいではありません。値BUTはあいまいではない(SAS言語にもマクロ言語にも含まれない)ため、これに対して%STRを使用する必要はありません。詳細については、マクロクォーティングを参照してください。
前のページ|次のページ|ページの先頭へ