読者です 読者をやめる 読者になる 読者になる

SAS Excel一括変換するマクロ (1)

SAS Excel一括変換するマクロ (2)




昔(2006年頃)作ったマクロを改良してみました。
SASファイルがあるディレクトリ内のSASデータセットを一括でExcelファイルへと変換するマクロです。
SASファイルの実行パスを取得する方法SAS Faqに掲載されていたので参考にしました。
実行パスから自動的に処理するディレクトリを特定してSASデータセットを変換します。
データセットを大量にはき出したとき、SASのViewerで見るのはちょっと・・・・。なら、Excelに変換できたらラクだなと思いましてね。


マクロ本体

filename dlog1 dummy;
proc printto log = dlog1 print = dlog1; run;

/* get the submitted Path macro */
%let execpath = ' ';

%macro setexecpath;
  %let execpath = %sysfunc(getoption(sysin));
  %if %length(&execpath) = 0 %then
    %let execpath = %sysget(sas_execfilepath);
  data _null_;
    count = 0;
    do i = length("&execpath") to 1 by -1;
      if substr("&execpath", i, 1) = '\' & count = 0 then do;
        call symput('Path', substr("&execpath", 1, i));
        count = 1; j = i;
      end;
      else if substr("&execpath", i, 1) = '\' & count = 1 then do;
        call symput('Dir', substr("&execpath", i + 1, j - i - 1));
        stop;
      end;
      else do;
        call symput('Dir', 'file');
      end;
    end;
  run;
%mend setexecpath;

/* export macro */
%macro EXOut(
  mem = ,
  lib = ,
);

%if &ftype = csv %then
  %let filename = "&Path.&mem..csv";
%else %if &otype = 1 %then
  %let filename = "&Path.&mem..xls";
%else
  %let filename = "&Path.&Dir..xls";
%let libname = &lib..&mem;

proc export data = &libname
  outfile = &filename
  %if &ftype = csv %then %do;
    dbms = csv replace;
  %end;
  %else %do;
    dbms = excel replace;
    sheet = "&mem";
  %end;;
run;

%mend EXOut;

%macro MStart;

/* macro variable check */
%if %symexist(ftype) = 0 %then %let ftype = xls;
%if %symexist(otype) = 0 %then %let otype = 1;
%if %symexist(outfile) = 1 %then %let Dir = &outfile;
%if &ftype ^= csv & &ftype ^= xls %then %let ftype = xls;
%if &otype ^= 1 & &otype ^= all %then %let otype = 1;

/* get library informations */
proc datasets library = CONV;
  contents data=_all_ nods;
  ods output Members = Work.Mem;
quit;

/* get the number of datasets  */
%let dsid = %sysfunc(open(Work.Mem));
%let nobs = %sysfunc(attrn(&dsid,NOBS));
%let rc = %sysfunc(close(&dsid));

/* call export macro */
proc sql noprint;
  select Name into :name1 - :name&nobs from Work.Mem;
  %do i = 1 %to &nobs;
    %let toname = &&name&i;
    %EXOut(mem = &toname, lib = CONV);
  %end;
quit;

%mend MStart;

%setexecpath;
libname CONV "&Path";


実行部分

/* default: xls separate */
%MStart;

/* csv (separate) */
%let ftype = csv;
%MStart;

/* xls separate */
%let ftype = xls;
%MStart;

/* xls combine */
%let otype = all;
%MStart;

/* xls combine & filename */
%let otype = all;
%let outfile = filename;
%MStart;
  1. 実行部分は4種類のオプションあり(個々のcsv, 個々のxls, 一つのxls, ファイル名を指定して一つのxls)
  2. マクロ本体と実行部分を一つのSASファイルに保存する。
  3. 変換したいSASデータセットがあるディレクトリに↑のSASファイルをコピーする。
  4. バッチサブミットかプログラム内で%includeする。