一位讀者留言,遞交的程序需要把宏都解析出來(lái)(不管是公司的還是同事在程序里寫(xiě)的),怎么實(shí)現(xiàn)?

對(duì)于公司的宏程序,這個(gè)也算是公司的財(cái)產(chǎn),一般不會(huì)直接把宏程序發(fā)送給申辦方或者遞交給監(jiān)管機(jī)構(gòu),而是將所有的宏都解析成正常的data步發(fā)送給對(duì)方。同時(shí),目前只有器械項(xiàng)目需要遞交程序,如下:

所以自己臨時(shí)去搜索了相關(guān)的東西,并進(jìn)行了一些測(cè)試,首先我自己新建了兩個(gè)程序,程序里面有正常的data步,也有自己寫(xiě)的宏程序,
程序1: remacro.sas
data test;
set sashelp.class;
run;
data test2;
set sashelp.cars;
run;
%macro resolvema(name=,out=);
data cc_&out;
set test(where=(name="&name"));
run;
%mend;
%resolvema(name=Alfred,out=1);
%resolvema(name=Thomas,out=2);
data final;
set cc_:;
run;
程序2:remacro1.sas
data test;
set sashelp.class;
run;
data test2;
set sashelp.cars;
run;
%macro resolvema(name=,out=);
data zz_&out;
set test2(where=(make="&name"));
run;
%mend;
%resolvema(name=Acura,out=3);
%resolvema(name=Audi,out=4);
data final;
set zz_:;
run;
這兩個(gè)宏程序儲(chǔ)存在我的D:\Practice文件夾下,現(xiàn)在我需要去解析程序里面的宏,然后讓它們展示成正常的data步,輸出到我的Practice2文件夾下,SAS提供這樣一種方式
filename mprint '路徑\代碼名稱(chēng).sas';
options mprint mfile;
我自己寫(xiě)了一段程序,但是有點(diǎn)問(wèn)題,后面說(shuō)
%let path_1=D:\Practice;
%let path_2=D:\Practice2;
%macro resopa(name=);
/* options nomprint nomfile;*/
filename mprint "&path_2\&name..sas"; /*輸出解析后的宏程序文件*/
options mprint mfile; /*必須加上這個(gè)選項(xiàng),要不然文件夾里不會(huì)有文件*/
run;
%include "&path_1\&name..sas";
%mend resopa;
%resopa(name=remacro);
/*%resopa(name=remacro2);*/
這樣就能將解析后的宏程序輸出到對(duì)應(yīng)的路徑,看看效果,發(fā)現(xiàn)宏程序被正常解析出來(lái)了:

但是我接著去解析remacro2程序的時(shí)候,出了一點(diǎn)小問(wèn)題,它把options mprint mfile; 也寫(xiě)進(jìn)去了,因?yàn)檫@兩個(gè)選項(xiàng)是系統(tǒng)宏選項(xiàng),只要你在當(dāng)前程序里面運(yùn)行,就會(huì)一直起作用。

后面我想著那就加上options nomprint nomfile;像下面這樣,
%macro resopa(name=);
filename mprint "&path_2\&name..sas"; /*輸出解析后的宏程序文件*/
options mprint mfile; /*必須加上這個(gè)選項(xiàng),要不然文件夾里不會(huì)有文件*/
%include "&path_1\&name..sas";
options nomprint nomfile;
%mend resopa;
%resopa(name=remacro);
%resopa(name=remacro2);
這樣導(dǎo)致每個(gè)程序最后面都會(huì)加上這段話(huà),因?yàn)檫@都是在filename語(yǔ)句下,所以自然而然的也被輸出了。

相對(duì)來(lái)說(shuō),這個(gè)對(duì)程序的影響不大,而且還是關(guān)閉系統(tǒng)選項(xiàng)。所以如果你們公司使用%include一股腦batch run program的話(huà),建議修改一下batch的方式,如果都在同一個(gè)程序或者同一個(gè)線(xiàn)程下跑程序,程序與程序之間絕對(duì)是會(huì)有影響的,尤其是某個(gè)程序中加了一些系統(tǒng)選項(xiàng)的話(huà)!
但是我想把這句話(huà)給去掉,我在網(wǎng)上搜了一下,都是只有單個(gè)程序,沒(méi)有考慮運(yùn)行多個(gè)程序解析宏程序造成的影響。比如說(shuō)我們的table有幾十張,也就是你要解析幾十次,但是的話(huà)按照上面的寫(xiě)法肯定要出問(wèn)題的。
后面又在網(wǎng)上搜索相關(guān)東西,想法主要是讓filename在%include完之后就停止輸出代碼,了解到filename有這個(gè)用法:
filename mprint CLEAR;
這個(gè)clear可以實(shí)現(xiàn)讓filename停止輸出代碼,注意不是清空,后面我自己又完善了相關(guān)代碼
%macro resopa2(name=);
%macro resopa(name=);
options nomprint nomfile;
filename mprint "&path_2\&name..sas" ;
options mprint mfile;
%include "&path_1\&name..sas";
%mend resopa;
filename mprint CLEAR;
%resopa(name=&name);
%mend resopa2;
%resopa2(name=remacro);
%resopa2(name=remacro2);
需要注意的是,這個(gè)filename mprint CLEAR; 放的位置很重要,放在程序中的其他位置可能就導(dǎo)致輸出不了或者程序報(bào)錯(cuò)。
但是!有一個(gè)問(wèn)題,如果我一次一次單獨(dú)運(yùn)行%resopa2;程序能夠正確解析,而且也不會(huì)輸出filename mprint CLEAR;但是的話(huà),如果我直接點(diǎn)擊運(yùn)行,一下子把兩個(gè)%resopa2都運(yùn)行的話(huà),奇怪的是remacro會(huì)在程序最后面出現(xiàn)filename mprint CLEAR;
注意,先運(yùn)行的是%resopa2(name=remacro),然后還在remacro出現(xiàn)那句話(huà),按理說(shuō)你要是輸出filename mprint CLEAR,也應(yīng)該是在remacro2??!所以目前有兩個(gè)地方讓人百思不得其解。
你們可以自己去測(cè)試一下或者了解的話(huà),歡迎指教!