232:如何解析宏并轉(zhuǎn)換成正常的代碼

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

image

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

image

所以自己臨時(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)了:


image

但是我接著去解析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ì)一直起作用。

image

后面我想著那就加上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ǔ)句下,所以自然而然的也被輸出了。


image

相對(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à),歡迎指教!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容