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;
ん、これ環境変えたら動かないので直します。
返信削除