前のページ|次のページ

デバッグの方法

システムオプションを使用して、問題をトラッキングする

SASシステムオプションMLOGIC、MLOGICNEST、MPRINT、MPRINTNEST、およびSYMBOLGENは、マクロコードおよびマクロが生成するSASコードをトラッキングするのに役立ちます。これらのオプションが生成するメッセージは、それを生成したオプションの名前が先頭に付加されて、SASログに表示されます。
注: マクロ機能を使用する場合は、マクロのオプションMACRO、MERROR、およびSERRORを使用します。SOURCEは、マクロ機能を使用する場合に役立つシステムオプションです。%INCLUDEを使用する場合、SOURCE2システムオプションを使用することも役に立ちます。
以降のセクションでは、各システムオプションを別々に説明しますが、当然、それらを組み合わせて使用することができます。ただし、これらのオプションによって大量の出力が生成される場合があり、多すぎる情報は、少なすぎる情報と同様に混乱を招くことがあります。そのため、必要と判断したオプションのみを使用し、デバッグが完了したら無効にしてください。

MLOGICを使用した実行フローのトレース

MLOGICシステムオプションを指定すると、パラメータの置換などのマクロの実行フロー、変数のスコープ(グローバルまたはローカル)、評価されたマクロ式の状態、ループの反復回数、各マクロの実行開始と終了がトレースされます。単純な構文エラーとは対照的に、プログラムロジックにバグがあると思われる場合、MLOGICオプションを使用します。
注: MLOGICによって大量の出力が生成される場合があるため、必要なときにのみこのオプションを使用し、デバッグが終了したら無効にしてください。
次の例では、マクロFIRSTによってマクロSECONDを呼び出し、式を評価しています。
%macro second(param);
   %let a = %eval(&param); &a
%mend second;

%macro first(exp);
   %if (%second(&exp) ge 0) %then
      %put **** result >= 0 ****;
   %else
      %put **** result < 0 ****;
%mend first;

options mlogic;
%first(1+2)
オプションMLOGICを指定してこの例をサブミットすると、各マクロの実行開始時刻、渡したパラメータの値、および式の評価結果が表示されます。
MLOGIC(FIRST):  Beginning execution.
MLOGIC(FIRST):  Parameter EXP has value 1+2
MLOGIC(SECOND):  Beginning execution.
MLOGIC(SECOND):  Parameter PARAM has value 1+2
MLOGIC(SECOND):  %LET (variable name is A)
MLOGIC(SECOND):  Ending execution.
MLOGIC(FIRST):  %IF condition (%second(&exp) ge 0) is TRUE
MLOGIC(FIRST):  %PUT **** result >= 0 ****
MLOGIC(FIRST):  Ending execution.

MLOGICNESTによって生成されるネスト情報

MLOGICNESTを指定すると、マクロのネスト情報を、MLOGICの出力としてSASログに書き込むことができます。MLOGICNESTを設定しても、MLOGICを設定したことにはなりません。ネスト情報を含む出力をSASログに書き込むには、MLOGICおよびMLOGICNESTの両システムオプションを設定する必要があります。
詳細と例については、MLOGICNESTシステムオプションを参照してください。

MPRINTを使用した生成済みSASステートメントの検証

MPRINTシステムオプションを指定すると、マクロが生成した各SASステートメントがSASログに書き込まれます。コードが期待どおり生成されず、コードにバグがあると疑われる場合、MPRINTオプションを使用します。
たとえば、次のプログラムでは単純なDATAステップを生成しています。
%macro second(param);
   %let a = %eval(&param); &a
%mend second;

%macro first(exp);
   data _null_;
      var=%second(&exp);
      put var=;
   run;
%mend first;

options mprint;
%first(1+2)
オプションMPRINTを指定してこれらのステートメントをサブミットすると、次の行がSASログに書き込まれます。
MPRINT(FIRST):   DATA _NULL_; MPRINT(FIRST):   VAR= MPRINT(SECOND):3 MPRINT(FIRST):; MPRINT(FIRST):   PUT VAR=; MPRINT(FIRST):   RUN; VAR=3
MPRINTオプションを使用することで、生成されたテキストを表示し、それを生成したマクロを特定できます。

MPRINTNESTによって生成されるネスト情報

MPRINTNESTを指定すると、マクロのネスト情報を、MPRINTの出力としてSASログに書き込むことができます。この値は、外部ファイルに送信されるMPRINTの出力には効果がありません。詳細については、MFILEシステムオプションを参照してください。
MPRINTNESTを設定しても、MPRINTを設定したことにはなりません。ネスト情報を含む出力をSASログに書き込むには、MPRINTおよびMPRINTNESTの両システムオプションを設定する必要があります。
詳細と例については、MPRINTNESTシステムオプションを参照してください。

外部ファイルへのMPRINT出力の保存

マクロの実行中にマクロ機能によって生成されたテキストを、外部ファイルに保存できます。最近のSASセッションで生成されたテキストをテストするときに、マクロの実行中に生成されたステートメントをファイルに出力しておくと、マクロのデバッグに役立ちます。
この機能を使用するには、MFILEシステムオプションとMPRINTシステムオプションの両方を有効に設定します。また、MPRINTを、マクロ機能によって生成された出力を含むファイルへのファイル参照名として割り当てるには、次のように設定します。
options mprint mfile;
filename mprint 'external-file';
MPRINTシステムオプションによって作成された外部ファイルは、SASセッションが終了するまで開かれたままになります。マクロ機能によって生成されたMPRINTのテキストは、SASセッション中はログに書き込まれ、セッションが終了すると外部ファイルに書き込まれます。このテキストは、マクロの実行中に生成され、マクロ変数参照とマクロ式が置換されたプログラムステートメントから成ります。外部ファイルには、マクロによって生成されたステートメントのみが保存されます。マクロの外部のどのステートメントも、外部ファイルには書き込まれません。各ステートメントは、ワード間のスペースを1つ開けて、新しい行に書き込まれます。テキストは、ログに表示されているMPRINT(macroname:という接頭語を付けないで外部ファイルに保存されます。
MPRINTがファイル参照名として割り当てられていないか、外部ファイルアクセスできない場合、警告メッセージがログに書き込まれ、MFILEが無効になります。この機能を再び使用するには、もう一度MFILEを指定する必要があります。
デフォルトでは、MPRINTオプションとMFILEオプションは無効になっています。
次の例では、MPRINTオプションとMFILEオプションを使用して、生成されたテキストをTEMPOUTという名前の外部ファイルに保存しています。
options mprint mfile;
filename mprint 'TEMPOUT';

%macro temp;
   data one;
      %do i=1 %to 3;
         x&i=&i;
      %end;
   run;
%mend temp;

%temp
マクロ機能によって次の行がSASログに書き込まれ、TEMPOUTという名前の外部ファイルが作成されます。
MPRINT(TEMP):   DATA ONE;
NOTE: The macro generated output from MPRINT will also be written
      to external file '/u/local/abcdef/TEMPOUT' while OPTIONS
      MPRINT and MFILE are set.
MPRINT(TEMP):   X1=1;
MPRINT(TEMP):   X2=2;
MPRINT(TEMP):   X3=3;
MPRINT(TEMP):   RUN;
SASセッションが終了したときの、ファイルTEMPOUTの内容は次のとおりです。
DATA ONE;
X1=1;
X2=2;
X3=3;
RUN;
注: MPRINTを使用した外部ファイルへのコードの書き込みは、デバッグ専用ツールです。デバッグ以外の目的で、MPRINTを使用してSASコードファイルを作成しないでください。

SYMBOLGENを使用したマクロ変数の置換の検証

SYMBOLGENシステムオプションを指定すると、各マクロ変数の置換結果が、メッセージとしてSASログに書き込まれます。特殊文字によってマクロ変数が意図したとおりに置換されないといった、クォーティングの問題を特定する場合、特にこのオプションが役に立ちます。
例として、次のステートメントをサブミットする場合を考えます。
options symbolgen;

%let a1=dog;
%let b2=cat;
%let b=1;
%let c=2;
%let d=a;
%let e=b;
%put **** &&&d&b ****;
%put **** &&&e&c ****;
SYMBOLGENオプションによって、次の行がSASログに書き込まれます。
SYMBOLGEN:&& resolves to &.SYMBOLGEN:Macro variable D resolves to a SYMBOLGEN:Macro variable B resolves to 1 SYMBOLGEN:Macro variable A1 resolves to dog **** dog **** SYMBOLGEN:&& resolves to &.SYMBOLGEN:Macro variable E resolves to b SYMBOLGEN:Macro variable C resolves to 2 SYMBOLGEN:Macro variable B2 resolves to cat **** cat ****
SYMBOLGENオプションによって得られたログを読むことは、プログラムステートメントを調べて間接的に置換をトレースするよりも簡単です。SYMBOLGENオプションを指定したことで、マクロプロセッサによるマクロ変数の置換の各ステップがトレースされていることに注目してください。置換が完了すると、%PUTステートメントによってSASログに値が書き込まれます。
マクロクォーティング関数によってマスクされたマクロ変数の値を、SYMBOLGENを使用してトレースしたときに、出力するためにクォーティングが解除されたことを示す追加メッセージが表示される場合があります。たとえば、SYMBOLGENを使用して次のステートメントをサブミットしたとします。
%let nickname = %str(My name%'s O%'Malley, but I%'m called Bruce);
%put *** &nickname ***;
これらのステートメントの実行が完了すると、次のメッセージがSASログに出力されます。
SYMBOLGEN:  Macro variable NICKNAME resolves to
                            My name's O'Malley, but I'm called Bruce
SYMBOLGEN:  Some characters in the above value which were
                           subject to macro quoting have been
                           unquoted for printing.
*** My name's O'Malley, but I'm called Bruce ***
このクォーティング解除メッセージは、無視することができます。

%PUTステートメントを使用して、問題をトラッキングする

マクロの開発中およびデバッグ中に、SYMBOLGENシステムオプションを使用してマクロ変数の値をSASログに書き込むことに加えて、%PUTステートメントを使用すると効果的です。マクロが完成したら、それらの%PUTステートメントを削除するか、コメント化することができます。次の表に、%PUTステートメントがデバッグで役立つ場合の例をいくつか示します。
マクロのデバッグ時に役立つ%PUTステートメントの例
状況
マクロ変数の値を表示する
%PUT ****&=variable-name****;
変数の値の先頭または末尾の空白を確認する
%PUT ***&variable-name***;
ループの実行中に、二重アンパサンドの置換を確認する
%PUT ***variable-name&i = &&variable-name***;
条件の評価を確認する
%PUT ***This condition was met.***;
ご存知のように、マクロ変数はシンボルテーブルに格納されます。シンボルテーブルには、グローバルマクロ変数が格納されるグローバルシンボルテーブルと、ローカルマクロ変数が格納されるローカルシンボルテーブルがあります。デバッグ中に、時々これらのテーブルを出力してマクロ変数のグループのスコープと値を調べると、役立つ場合があります。これを実行するには、次のオプションのいずれかを指定して%PUTステートメントを使用します。
_ALL_
スコープに関係なく、現在定義されているすべてのマクロ変数を表示します。ユーザー定義のグローバル変数とローカル変数、および自動マクロ変数が含まれます。
_AUTOMATIC_
すべての自動マクロ変数を表示します。スコープは、AUTOMATICとして表示されます。自動マクロ変数は、SYSPBUFFを除き、すべてグローバルです。
_GLOBAL_
マクロプロセッサによって作成されていない、すべてのグローバルマクロ変数を表示します。スコープは、GLOBALとして表示されます。自動マクロ変数は表示されません。
_LOCAL_
現在実行中のマクロ内で定義された、ユーザー定義のローカルマクロ変数にを表示します。スコープは、そのマクロ変数が定義されているマクロの名前で表示されます。
_USER_
スコープに関係なく、すべてのユーザー定義マクロ変数を表示します。グローバルマクロ変数の場合、スコープはGLOBALになります。ローカルマクロ変数の場合、スコープはマクロの名前になります。
次の例では、引数_USER_を指定して%PUTステートメントを使用し、マクロTOTINVで使用できるグローバル変数とローカル変数を調べています。%PUTステートメントによって値がログに書き込まれるタイミングを、ユーザー定義マクロ変数TRACEを使用して制御していることに注目してください。
%macro totinv(var);
   %global macvar;
   data inv;
      retain total 0;
      set Sasuser.Houses end=final;
      total=total+&var;
      if final then call symput("macvar",put(total,dollar14.2));
   run;

   %if &trace = ON  %then
      %do;
         %put *** Tracing macro scopes. ***;
         %put _USER_;
      %end;
%mend totinv;

%let trace=ON;
%totinv(price)
%put *** TOTAL=&macvar ***;
これらのステートメントをサブミットすると、SASログには、マクロTOTINV内の1番目の%PUTステートメントによって、トレースが有効になったことを示すメッセージが書き込まれ、次にすべてのユーザー定義マクロ変数のスコープと値が書き込まれます。
*** Tracing macro scopes.***Tracing macro scopes. *** TOTINV VAR price GLOBAL TRACE ON GLOBAL MACVAR $1,240,800.00 *** TOTAL= $1,240,800.00 ***
マクロ変数の適用範囲の詳細については、マクロ変数のスコープを参照してください。
前のページ|次のページ|ページの先頭へ