実行しているプログラムファイル名の取得

[OS] ALL
[リリース] SAS System 8, 9
[キーワード] program file name, dectionary table

[質問]

実行しているプログラムファイルの名前を、マクロ変数として取得したいのですが、どうすれば可能でしょうか。
たとえば、「ABC.SAS」というプログラムを実行した際、「ABC.SAS」という値をマクロ変数として格納するには、どうしたらよいでしょうか。

[回答]

SQLプロシジャで dictionary.extfiles ディクショナリを検索することにより、最後に開かれたファイル名を取得することができます。
dictionary.extfilesには、以下のようなパターンでファイル名が記録されています。


  OBS  fileref   xpath                                         xengine

  1   #LN00004   TERMINAL
  2   #LN00005   C:¥filename.sas
  3   #LN00001   C:¥Program Files¥SAS Institute¥SAS¥V8¥NLS¥ja¥sasmsg
  4   #LN00001   C:¥Program Files¥SAS Institute¥SAS¥V8¥core¥sasmsg

  .
  .
  .


  (以下略)

ファイル名は、変数 xpath に格納されています。また fileref は、新しいファイルが開かれるたびに番号が上がっていきます。
つまり、fileref の番号が最も大きいものが、最後に参照されたファイルと考えることができます。
この機能を利用して、最後に参照されたファイルの名前を取得するサンプルプログラムを以下に示します。


  PROC SQL NOPRINT;
    SELECT xpath INTO :filename
      FROM (
        SELECT INPUT(SUBSTR(fileref,4),5.) AS file_number, xpath
          FROM dictionary.extfiles
            WHERE UPCASE(SCAN(xpath,-1,'.')) = 'SAS'
        )
        HAVING file_number=MAX(file_number);
  QUIT;
                /* フルパスからファイル名のみを取得(Windowsの場合) */
  %LET filename=%SCAN(&filename,-1,'¥');

                                               /* ファイル名の出力 */
  %PUT "このファイルは &filename です。";

SQLプロシジャでは、まず fileref の値のうち先頭4文字目以降をSUBSTR関数で取り出し、INPUT関数で数値型の値に変換しています。
またこのとき xpath の値を「.」を区切り文字として末尾が「SAS」であるものだけを抽出します。
ここから、さらに fileref の値を数値変換したものが最大である行の、xpath を取得します。これが最後に開いたファイル名となります。

ファイル名はINTO句によってマクロ変数filenameに格納されます。ただしこれはフルパスで記述されています。
上記の例では、ファイル名のみを取り出すことを想定し、%SCAN関数で「¥」を区切り文字とした最後の部分をファイル名として抽出しています

※ Windows環境での例です。UNIX環境の場合は、「¥」の代わりに「/」を指定します。

なお、このプログラムで得られるのは、正確には「最後に開いたファイル名」です。したがって、このプログラムを実行する前に別のファイルを開いてしまうと、後から開いた方のファイル名を取得することになってしまいますのでご注意ください。