公司要求QC側(cè)程序的運(yùn)行要在Source側(cè)之后,目前沒(méi)有專門(mén)的工具檢查程序運(yùn)行時(shí)間,只能人工核查。但人工核查不僅繁瑣,還難免會(huì)有疏漏。
于是,我打算寫(xiě)個(gè)宏程序來(lái)完成這項(xiàng)工作。基于模塊化考慮,我先介紹獲取文件修改時(shí)間的宏程序,后續(xù)的時(shí)間比較在另行操作。宏程序代碼附在文章末尾。
獲取文件修改時(shí)間的主要思路是,通過(guò)電腦的CMD指令獲取文件的修改時(shí)間,然后將指令的返回結(jié)果讀入SAS數(shù)據(jù)集。
1. CMD指令獲取文件修改時(shí)間
以Win10系統(tǒng)為例,進(jìn)行演示。Linux系統(tǒng)操作可能不同,后續(xù)研究再介紹。
首先,在搜索欄輸入CMD,打開(kāi)命令提示符。

獲取文件夾的所用的命令是dir,我們可以輸出dir /?查看該命令的幫助文檔。
dir /?

在文檔中可以發(fā)現(xiàn),查看文件的時(shí)間相關(guān)信息,使用的是/t選項(xiàng)。選項(xiàng)有3個(gè)參數(shù),分別對(duì)應(yīng)創(chuàng)建時(shí)間、上次訪問(wèn)時(shí)間以及上次寫(xiě)入時(shí)間。
我測(cè)試了下,省略參數(shù)時(shí),默認(rèn)輸出是上次寫(xiě)入時(shí)間,也就是想要獲取的文件修改時(shí)間。
我新建了個(gè)Test文件夾,文件夾中包含SAS程序和SAS log文件。

獲取該文件夾下所有Log文件的修改時(shí)間的命令如下:
dir /t E:\99_Test\SDTM\*.log
*為通配符,可以匹配所有后綴為.log的文件。
命令的輸出結(jié)果如下:

該文件夾中,所有Log文件的修改時(shí)間都顯示出來(lái)了,后面需要將這些結(jié)果讀入到SAS中。
2. 將CMD返回結(jié)果導(dǎo)入SAS數(shù)據(jù)集
在SAS中,可以使用filename語(yǔ)句建立一個(gè)文件引用,與CMD指令的輸出結(jié)果相關(guān)聯(lián)。同時(shí),必須使用pipe選項(xiàng),SAS才能訪問(wèn)訪問(wèn)CMD指令的輸出結(jié)果。
*Create a fileref for the files Modified datetime;
filename cmd pipe "dir /t E:\99_Test\SDTM\*.log";
文件引用建立好之后,在Data步中使用infile語(yǔ)句進(jìn)行讀取。考慮到輸出結(jié)果中有4列內(nèi)容,提前設(shè)置好保存這些結(jié)果的變量長(zhǎng)度,避免截?cái)唷?/p>
*Read the fileref;
data tmp;
length date $20 time $20 size $200 filenam $20 ;
infile cmd;
input date $ time $ size $ filenam $;
run;

從結(jié)果中可以出,有一些多余的信息出現(xiàn)在讀入數(shù)據(jù)集中前兩行,和后兩行。我們可以在Data步中進(jìn)行移除,同時(shí)進(jìn)行變量處理, 方便結(jié)果查看。
*Keep useful datetime information;
data tmp1;
length folder $200 type $20;
set tmp nobs = nobs;
*remove useless information;
if 2<_n_<nobs-2;
format modifydt e8601dt.;
modifydt = input(strip(date)||"T"||strip(time),e8601dt.);
folder = "E:\99_Test\SDTM\";
type = "log";
keep folder type filenam modifydt;
run;
整理結(jié)果如下,該文件夾下的Log文件的修改時(shí)間輸出完畢。

3. 匯總宏程序
流程跑通之后,將程序整理成宏。
宏程序與前面代碼相比,多了對(duì)路徑宏參數(shù)的處理。因?yàn)檩斎肼窂綍r(shí),并非所有人都習(xí)慣以斜杠\結(jié)尾,所以直接將斜杠寫(xiě)在Filename語(yǔ)句的路徑中。
如果輸入的宏參數(shù)多了斜杠,直接在宏程序的開(kāi)頭移去。這樣就避免了路徑輸入不統(tǒng)一對(duì)宏運(yùn)行的影響。
%macro modifydt(folder=,type=, outdt=);
*Remove trailing slash;
%if %substr(&folder.,%length(&folder.),1)=\ %then %let folder=%substr(&folder.,1,%length(&folder.)-1);
*Create a fileref for the files Modified datetime;
filename cmd pipe "dir /t &folder.\*.&type.";
*Read the fileref;
data &outdt.1;
length date $20 time $20 size $200 filenam $20 ;
infile cmd;
input date $ time $ size $ filenam $;
run;
*Keep useful datetime information;
data &outdt.;
length folder $200 type $20;
set &outdt.1 nobs = nobs;
*remove useless information;
if 2<_n_<nobs-2;
format modifydt e8601dt.;
modifydt = input(strip(date)||"T"||strip(time),e8601dt.);
folder = "&folder.";
type = "&type.";
keep folder type filenam modifydt;
run;
%mend modifydt;
%modifydt(
folder=%str(E:\99_Test\SDTM\)
,type=log
,outdt=log
);
總結(jié)
文章介紹了,通過(guò)SAS讀取CMD命令的返回結(jié)果,獲取文件夾中特定類型文件的修改時(shí)間。
目前以上程序適用于win10系統(tǒng),如果電腦系統(tǒng)語(yǔ)言為中文,指令輸出結(jié)果中包含中文字符。如果當(dāng)前SAS編碼環(huán)境不支持中文,則會(huì)導(dǎo)入錯(cuò)誤。
最后貼一下,我演示用的SAS中文的編碼設(shè)置:
%put %sysfunc(getoption(encoding));
%put %sysfunc(getoption(locale));

英文版的編碼設(shè)置如下,可以正常導(dǎo)入CMD結(jié)果。

SAS EG編碼設(shè)置如下,無(wú)法正常導(dǎo)入CMD指令結(jié)果:


感謝閱讀!若有疑問(wèn),歡迎評(píng)論區(qū)交流!