SASマクロ コーディング作法

【SAS】マクロ内で生成する一時データセットの命名規則について

皆さんはマクロ内で生成する一時データセットについて、どのように命名されていますでしょうか?

私の場合は「_マクロ名_」という接頭辞を必ず付けるようにしています。

例えば、クロス集計用マクロcross_count内で生成される一時データセット名は、以下のように「_cross_count_」という接頭辞になっています。

_cross_count_temp
_cross_count_temp2
_cross_count_sum&_r.

上記のような命名規則にしている理由は以下になります

  • ①マクロ外で生成されるデータセット名と被るのを防ぐ
  • ②どのマクロで生成されたデータセットかわかりやすくする
  • ③不要になった一時データセットを略記法で一括削除できる
  • では、それぞれの理由についてご説明いたします。

    ①マクロ外で生成されるデータセット名と被るのを防ぐ

    既存のデータセット名と同じ名前のデータセットを生成した場合、後から生成されたデータセットで置換されてしまうのはご存じかと思います。

    この仕様が、大規模なプログラムになるとマズいのです。

    大規模なプログラムになるほど、プログラム本体だけでなく、SASAUTOSや%INCLUDEステートメントで呼び出す外部プログラムも含めて、定義されているマクロの数が膨大に増えていきます。

    例えば以下のように、マクロ01~マクロ30が、プログラム本体やSASAUTOS、外部プログラムの至る所で定義されていたとします。

    %macro マクロ01; %mend;
    %macro マクロ02; %mend;
    %macro マクロ03; %mend;
    ・・・
    ・・・
    ・・・
    %macro マクロ30; %mend;
     
    (このマクロ名は便宜的にテキトーに付けてます)

    ここで、マクロ15だけ修正する必要が生じた場合のことを考えてみてほしいのですが、マクロ15内で生成する一時データセット名が、他のマクロで生成された一時データセット名と被っているかどうか、いちいちチェックするのは面倒ではないでしょうか?

    あるいは、新規のマクロを追加したくなったときに、その新規のマクロ内で生成する一時データセットが、後続で使用するデータセットを上書いてしまわないか、心配になることはないでしょうか?

    そのような、後続処理に影響を及ぼすリスクを下げるために、「_マクロ名_」という接頭辞を必ず付けるようにしています。

    「_マクロ名_」を頭に付けるだけで、データセット名が被ってしまうような事態はほとんど起こらなくなります。

    ②どのマクロで生成されたデータセットかわかりやすくする

    まぁ、これは説明する必要はなさそうですが、一時データセットを削除せしない場合、データセット名に規則性が無いと、どこで生成されたデータセットかわからなり、WORK領域が散らかっていきます。

    ましてや、他人が作成したプログラムを引き継いだ場合はなおさらです。

    これは自論ですが、業務効率化とミス防止の基本は、規則的に整理する、ことだと考えています。

    これを徹底している人の業務は引き継ぎやすく、その業務への理解やミス防止につながります。

    ③不要になった一時データセットを略記法で一括削除できる

    以下は、クロス集計用マクロcross_countの最後で、不要な一時データセットを略記法「_cross_count_:」で一括削除している箇所です。

    %macro cross_count(indata=, sibori=, weight=, row=, row_label=, col=, col_label=, prefix=out, outdata=);
    
        ///// 途中省略 /////
    
    	/*不要データの削除*/
    	proc datasets lib=work noprint;
    		delete _cross_count_:;
    	quit;
    
    %mend cross_count;
    

    「_マクロ名_」という接頭辞をデータセットに付けておけば、略記法で不要なデータセットを一括削除することができます。

    また、マクロ外で生成されたデータセット名と被る可能性も低いので、余程のことがないかぎり、必要なデータセットを誤って削除してしまうこともないでしょう。