現在実行しているプログラムのパスを取得する方法をご紹介します。
パスの手入力は避けるべきです
誤入力を避ける
外部データをSASに読み込む際、パスを指定します。
その際、手入力すると面倒ですし、うち間違えるとエラーになります。
それを避けるためにも上手に取得する必要があります。
相対パスで指定したいけど…。
私はあるプロジェクトの解析をする場合、そのプロジェクト名をつけたフォルダを一つ作り、関連するデータや書類はすべてそのフォルダに格納しています。
フォルダ構造の例
root(project name)/
├── datasets/
│ ├── dataset1.csv
│ ├── dataset2.csv
│ └── dataset3.csv
└── doc/
│ ├── hoge.pdf
│ └── hogehoge.pdf
├── analysis1.sas
└── analysis2.sas
例えばこの場合、analysis1.sasでdataset1.csvのパスを指定する場合は、
「./datasets/dataset1.csv」
と言ったように相対パスで指定をしたいわけです。
相対パスで指定したプログラムであれば、フォルダを丸ごと移動したとしてもファイルの位置関係は維持されるためエラーになりません。
また、職場と自宅のパソコンをOne driveなどで同期して、パスが違ったとしても実行できる…なんてこともできるわけです。
ただ、いろいろ探しても、SASで相対パスを指定してデータ読み込みをする方法がわかりませんでした。
(私が知らないだけ?かも知れませんので、ご存知の方がいればぜひご教示ください!)
C#とかだとすっごく簡単なんですけどね。
実行しているプログラムのファイル名を取得する
SAS_EXECFILEPATH
SAS_EXECFILEPATHを使って取得することができます。
SASプログラム
たとえば次のようなコードで確認できます。
SAS_EXECFILEPATHからパスを取得
%let path= %sysget(SAS_EXECFILEPATH);
%put &path;
SAS_EXECFILEPATHからパスを取得(マクロの場合)
%qsysfunc(sysget(SAS_EXECFILEPATH));
DictionaryテーブルのExtFilesを利用
一部改変していますが、SASサポートに掲載されていた方法です。
SASプログラム
DictionaryテーブルのExtFilesを利用してパスを取得
proc sql noprint;
select xpath into: path
from(
/* サブクエリ */
select
input(substr(fileref,4),5.) as file_number, /* Fileref=>"#LN12345" */
xpath
from dictionary.extfiles /* 実行された順にパス(ディレクトリのみを含む)が格納されている */
where upcase(scan(xpath, -1, '.'))= 'SAS' /* 拡張子がSASのみに限定 */
)
having file_number= max(file_number); /* 最大値=最後に実行されたファイルと考える */
quit;
%put &path;
注意!
たとえば、A.sas, B.sasの順にファイルを開いた場合、A.sas内でこのコードを実行してもB.sasのパスが取得されてしまうため注意が必要です。
Dictionaryテーブルについては、こちらで紹介しています。
パスからファイル名、拡張子、ディレクトリ等の情報を取得する
パスからファイル名、拡張子、ディレクトリ、ディレクトリ名、ルートの情報を取得する方法はこちらで紹介しています。