- Processing on disk occurred during summarization. Peak disk usage was approximately nnn Mbytes. Adjusting SUMSIZE may improve performance.
- NOTE: 要約化中にディスク処理が発生しました。 ディスクの最大使用はおよそ 2454 M バイトです。 SUMSIZE の調整によって、パフォーマンスを改善できるかもしれません。
SASプログラムとログを解析するユーティリティを開発するための備忘録です。This is a memo to develop utility that analyzes the SAS log.
2013年11月5日火曜日
NOTE: 要約化中にディスク処理が発生しました。
時間が出来たときに、ツールで以下のメッセージを捕捉するように修正する。
Calls a specific routine or module that resides in an external dynamic link library (DLL).
SASからWindowsのAPIを呼び出す方法を整理しています。
その理由を列挙しますと
VBScriptから制御する手もありますが、古いデータセットから順に移行したり、停止の制御を考えるとSAS1本でやるのが良さそうです。
基本はDLLを呼び出すためのI/Fを"The SASCBTBL Attribute Table"で定義して、MODULE関数で呼び出します。この仕組みが繊細で、定義を間違えるとSAS.EXEが落ちます。WinAPIの型を調べて、変数を割り当てるのは面倒な作業です。
その理由を列挙しますと
- SASのバージョンアップの作業で、Xステートメントが規制されている
- SASデータセットをCOPYプロシージャで移行するとタイムスタンプが維持できない
- タイムスタンプが変わると元ファイルが更新されたときに再転送が必要かわからない
- DOS窓からの実行だと遅い
VBScriptから制御する手もありますが、古いデータセットから順に移行したり、停止の制御を考えるとSAS1本でやるのが良さそうです。
基本はDLLを呼び出すためのI/Fを"The SASCBTBL Attribute Table"で定義して、MODULE関数で呼び出します。この仕組みが繊細で、定義を間違えるとSAS.EXEが落ちます。WinAPIの型を調べて、変数を割り当てるのは面倒な作業です。
2013年11月4日月曜日
SASからCopyFileAを呼び出して、ファイルをコピー
SASからWindowsのAPIをコールするサンプルコードです。バージョンアップによるデータの引越しで、今回はWinAPIを使ったツールを作る予定です。動作確認したのは、Windows7+SAS9.2です。
ネットにはいくつか見本が転がっていますが、PDFで文字が化けていたり、APIがまったく変わってしまったようなものもあります。素直に動くものが少ないので、いくつかの手本を元に作成しました。APIの定義をテキストで別に用意している例が多いのですが、カタログを使った例がまとまりが良いです。
ネットにはいくつか見本が転がっていますが、PDFで文字が化けていたり、APIがまったく変わってしまったようなものもあります。素直に動くものが少ないので、いくつかの手本を元に作成しました。APIの定義をテキストで別に用意している例が多いのですが、カタログを使った例がまとまりが良いです。
- /*
- *++
- * WinAPI(CopyFileA)を呼び出して、ファイルをコピー
- *--
- */
- filename winapi catalog 'WORK.Windows.WINAPI.SOURCE';
- data _null_;
- file winapi;
- input;
- put _infile_;
- cards4;
- routine CopyFileA
- module=KERNEL32
- minarg=3 maxarg=3 stackpop=called
- returns=ushort
- ;
- arg 1 input char format=$cstr200.; * FROM ;
- arg 2 input char format=$cstr200.; * TO ;
- arg 3 input num format=pib4. byvalue;
- * 1=Do Not Overwrite Existing ;
- * 0=Overwrite Existing File ;
- ;;;;
- run;
- filename winapi;
- filename sascbtbl catalog 'WORK.Windows.WINAPI.SOURCE';
- data _null_;
- rc = modulen('*e', 'CopyFileA', 'c:\temp\foo.txt', 'c:\temp\foo_copy.txt', 0);
- put _all_;
- run;
- filename sascbtbl clear;
/* *++ * WinAPI(CopyFileA)を呼び出して、ファイルをコピー *-- */ filename winapi catalog 'WORK.Windows.WINAPI.SOURCE'; data _null_; file winapi; input; put _infile_; cards4; routine CopyFileA module=KERNEL32 minarg=3 maxarg=3 stackpop=called returns=ushort ; arg 1 input char format=$cstr200.; * FROM ; arg 2 input char format=$cstr200.; * TO ; arg 3 input num format=pib4. byvalue; * 1=Do Not Overwrite Existing ; * 0=Overwrite Existing File ; ;;;; run; filename winapi; filename sascbtbl catalog 'WORK.Windows.WINAPI.SOURCE'; data _null_; rc = modulen('*e', 'CopyFileA', 'c:\temp\foo.txt', 'c:\temp\foo_copy.txt', 0); put _all_; run; filename sascbtbl clear;
SASからSetFileTimeを呼び出して、ファイルのタイムスタンプを設定
コードに間違いがあったので修正しました。
SASからWindowsのAPIをコールするサンプルコードです。バージョンアップによるデータの引越しで、今回はWinAPIを使ったツールを作る予定です。動作確認したのは、Windows7+SAS9.2です。ネットにはいくつか見本が転がっていますが、PDFでうまく転記できなかったり、APIがまったく変わってしまったようなものもありました。
SASからWindowsのAPIをコールするサンプルコードです。バージョンアップによるデータの引越しで、今回はWinAPIを使ったツールを作る予定です。動作確認したのは、Windows7+SAS9.2です。ネットにはいくつか見本が転がっていますが、PDFでうまく転記できなかったり、APIがまったく変わってしまったようなものもありました。
- /*
- *++
- * WinAPI(SetFileTime)を呼び出して、ファイルのタイプスタンプを更新
- *--
- */
- filename winapi catalog 'WORK.Windows.WINAPI.SOURCE';
- data _null_;
- file winapi;
- input;
- put _infile_;
- cards4;
- routine CreateFileA
- module=Kernel32
- minarg=7
- maxarg=7
- stackpop=called
- returns=long
- ;
- arg 1 char input format=$cstr260.; * LPCTSTR lpFileName;
- arg 2 num input format=pib4. byvalue; * DWORD dwDesiredAccess;
- arg 3 num input format=pib4. byvalue; * DWORD dwShareMode;
- arg 4 num input format=pib4. byvalue; * LPSECURITY_ATTRIBUTES lpSecurityAttributes (set to null,pass 0 byvalue);
- arg 5 num input format=pib4. byvalue; * DWORD dwCreationDispostion;
- arg 6 num input format=pib4. byvalue; * DWORD dwFlagsAndAttributes (set to zero);
- arg 7 num input format=pib4. byvalue; * HANDLE hTemplateFile (ignored);
- *-------------------------------------------------------------;
- routine CloseHandle
- module=Kernel32
- minarg=1
- maxarg=1
- stackpop=called
- returns=long
- ;
- arg 1 num input format=pib4. byvalue; * HANDLE hObject;
- *-------------------------------------------------------------;
- routine SystemTimeToFileTime
- minarg=9
- maxarg=9
- stackpop=called
- module=Kernel32
- returns=long
- ;
- arg 1 num input fdstart format=pib2.; * WORD wYear ;
- arg 2 num input format=pib2.; * WORD wMonth ;
- arg 3 num input format=pib2.; * WORD wDayOfWeek ;
- arg 4 num input format=pib2.; * WORD wDay ;
- arg 5 num input format=pib2.; * WORD wHour ;
- arg 6 num input format=pib2.; * WORD wMinute ;
- arg 7 num input format=pib2.; * WORD wSecond ;
- arg 8 num input format=pib2.; * WORD wMilliseconds ;
- arg 9 num output fdstart format=pib8.;
- *-------------------------------------------------------------;
- routine LocalFileTimeToFileTime
- minarg=2
- maxarg=2
- stackpop=called
- module=kernel32
- returns=long
- ;
- arg 1 input fdstart num format=pib8.; * lpLocalFileTime // converted file time;
- arg 2 output fdstart num format=pib8.; * lpFileTime, // UTC file time to convert;
- *-------------------------------------------------------------;
- routine SetFileTime
- minarg=4
- maxarg=4
- stackpop=called
- module=Kernel32
- returns=long
- ;
- arg 1 num input byvalue format=pib4.; * HANDLE hFindFile // file search handle ;
- arg 2 num input fdstart format=pib8.; * CONST FILETIME * lpCreationTime, // pointer to creation file time ;
- arg 3 num input fdstart format=pib8.; * CONST FILETIME * lpModifiedTime, // pointer to creation file time ;
- arg 4 num input fdstart format=pib8.; * CONST FILETIME * lpAccessedTime, // pointer to creation file time ;
- ;;;;
- run;
- filename winapi;
- filename sascbtbl catalog 'WORK.Windows.WINAPI.SOURCE';
- %macro touch(path=, year=);
- data _null_ ;
- GENERIC_READ = 080000100x; /* GENRIC_READ + FILE_WRITE_ATTRIBUTES(0x0100) */
- FILE_SHARE_READ = 1;
- OPEN_EXISTING = 3;
- length path $260;
- path = "&path";
- HANDLE = modulen('CreateFileA', path, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0,0);
- If HANDLE >= 1 Then Do;
- cdt_n = datetime();
- MINUTE = Minute( cdt_n);
- HOUR = Hour( cdt_n);
- DAY = DAY( DatePart( cdt_n) );
- DAYOFWK = WeekDay( DatePart( cdt_n) );
- MONTH = MONTH( DatePart( cdt_n) );
- YEAR = &year;
- SECONDS = 0;
- MSECONDS = 0;
- CREATED = .;
- CREATED1 = .;
- rc = ModuleN('SystemTimeToFileTime', YEAR, MONTH, DAYOFWK, DAY, HOUR, MINUTE, SECONDS, MSECONDS, CREATED);
- rc = ModuleN('LocalFileTimeToFileTime', CREATED, CREATED1);
- put rc= created= created1=;
- ACCESSE1 = CREATED1;
- WRITTEN1 = CREATED1;
- rc = ModuleN('SetFileTime', HANDLE, CREATED1, ACCESSE1, WRITTEN1);
- put rc=;
- rc = Modulen('CloseHandle', HANDLE);
- put rc=;
- end;
- run;
- %mend;
- %touch(path=c:\temp\foo.txt, year=2009);
- filename sascbtbl clear;
/* *++ * WinAPI(SetFileTime)を呼び出して、ファイルのタイプスタンプを更新 *-- */ filename winapi catalog 'WORK.Windows.WINAPI.SOURCE'; data _null_; file winapi; input; put _infile_; cards4; routine CreateFileA module=Kernel32 minarg=7 maxarg=7 stackpop=called returns=long ; arg 1 char input format=$cstr260.; * LPCTSTR lpFileName; arg 2 num input format=pib4. byvalue; * DWORD dwDesiredAccess; arg 3 num input format=pib4. byvalue; * DWORD dwShareMode; arg 4 num input format=pib4. byvalue; * LPSECURITY_ATTRIBUTES lpSecurityAttributes (set to null,pass 0 byvalue); arg 5 num input format=pib4. byvalue; * DWORD dwCreationDispostion; arg 6 num input format=pib4. byvalue; * DWORD dwFlagsAndAttributes (set to zero); arg 7 num input format=pib4. byvalue; * HANDLE hTemplateFile (ignored); *-------------------------------------------------------------; routine CloseHandle module=Kernel32 minarg=1 maxarg=1 stackpop=called returns=long ; arg 1 num input format=pib4. byvalue; * HANDLE hObject; *-------------------------------------------------------------; routine SystemTimeToFileTime minarg=9 maxarg=9 stackpop=called module=Kernel32 returns=long ; arg 1 num input fdstart format=pib2.; * WORD wYear ; arg 2 num input format=pib2.; * WORD wMonth ; arg 3 num input format=pib2.; * WORD wDayOfWeek ; arg 4 num input format=pib2.; * WORD wDay ; arg 5 num input format=pib2.; * WORD wHour ; arg 6 num input format=pib2.; * WORD wMinute ; arg 7 num input format=pib2.; * WORD wSecond ; arg 8 num input format=pib2.; * WORD wMilliseconds ; arg 9 num output fdstart format=pib8.; *-------------------------------------------------------------; routine LocalFileTimeToFileTime minarg=2 maxarg=2 stackpop=called module=kernel32 returns=long ; arg 1 input fdstart num format=pib8.; * lpLocalFileTime // converted file time; arg 2 output fdstart num format=pib8.; * lpFileTime, // UTC file time to convert; *-------------------------------------------------------------; routine SetFileTime minarg=4 maxarg=4 stackpop=called module=Kernel32 returns=long ; arg 1 num input byvalue format=pib4.; * HANDLE hFindFile // file search handle ; arg 2 num input fdstart format=pib8.; * CONST FILETIME * lpCreationTime, // pointer to creation file time ; arg 3 num input fdstart format=pib8.; * CONST FILETIME * lpModifiedTime, // pointer to creation file time ; arg 4 num input fdstart format=pib8.; * CONST FILETIME * lpAccessedTime, // pointer to creation file time ; ;;;; run; filename winapi; filename sascbtbl catalog 'WORK.Windows.WINAPI.SOURCE'; %macro touch(path=, year=); data _null_ ; GENERIC_READ = 080000100x; /* GENRIC_READ + FILE_WRITE_ATTRIBUTES(0x0100) */ FILE_SHARE_READ = 1; OPEN_EXISTING = 3; length path $260; path = "&path"; HANDLE = modulen('CreateFileA', path, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0,0); If HANDLE >= 1 Then Do; cdt_n = datetime(); MINUTE = Minute( cdt_n); HOUR = Hour( cdt_n); DAY = DAY( DatePart( cdt_n) ); DAYOFWK = WeekDay( DatePart( cdt_n) ); MONTH = MONTH( DatePart( cdt_n) ); YEAR = &year; SECONDS = 0; MSECONDS = 0; CREATED = .; CREATED1 = .; rc = ModuleN('SystemTimeToFileTime', YEAR, MONTH, DAYOFWK, DAY, HOUR, MINUTE, SECONDS, MSECONDS, CREATED); rc = ModuleN('LocalFileTimeToFileTime', CREATED, CREATED1); put rc= created= created1=; ACCESSE1 = CREATED1; WRITTEN1 = CREATED1; rc = ModuleN('SetFileTime', HANDLE, CREATED1, ACCESSE1, WRITTEN1); put rc=; rc = Modulen('CloseHandle', HANDLE); put rc=; end; run; %mend; %touch(path=c:\temp\foo.txt, year=2009); filename sascbtbl clear;
登録:
投稿
(
Atom
)