2016-10-25 196 views
2

我想將宏存儲在目錄中。這樣做可以讓許多宏只與一個文件共享,並且引入了與用戶分離的程度。SAS:重命名宏目錄

來存儲我的宏,我運行一個程序,如

/* HelloWorld.sas */ 
libname pwd ".";    /* assign current directory */ 
option mstored sasmstore=pwd; /* set pwd as storage directory */ 

%macro HelloWorld() 
    /store source;   /* store compiled macro along with its source */ 
    data _null_; 
    put "Hello, World!"; 
    run; 
%mend; 

這在目錄中創建一個sasmacr.sas7bcat文件,在其中HelloWorld.sas生活。然後我可以在文件移動到另一個目錄,如C:\myMacros和運行下面的程序:

/* CallHelloWorld.sas */ 
libname myMacros 'C:\myMacros'; 
option mstored sasmstore=myMacros; 

%HelloWorld(); 

HelloWorld()被稱爲沒有錯誤。但是,如果我想將HelloWorld()宏作爲「HelloWorld」宏套件的一部分,我不能簡單地將Windows資源管理器中的目錄名稱從sasmacr.sas7bcat更改爲HelloWorld.sas7bcat。當我這樣做並嘗試再次運行CallHelloWorld.sas(關閉並重新打開SAS後),宏未解析。

1 /* CallHelloWorld.sas */ 
2 libname myMacros 'C:\myMacros'; 
NOTE: Libref MYMACROS was successfully assigned as follows: 
     Engine:  V9 
     Physical Name: C:\myMacros 
3 option mstored sasmstore=myMacros; 
4 
5 %HelloWorld(); 
    - 
    180 
NOTE: The SAS System was unable to open the macro library referenced by the SASMSTORE = libref 
     MYMACROS. 
WARNING: Apparent invocation of macro HELLOWORLD not resolved. 

ERROR 180-322: Statement is not valid or it is used out of proper order. 

ERROR: Catalog MYMACROS.SASMACR does not exist. 
NOTE: The SAS System was unable to open the macro library referenced by the SASMSTORE = libref 
     MYMACROS. 
ERROR: An error occurred during the execution of the %COPY statement. 

如何更改包含宏的目錄的名稱,以便可以在各種程序中調用這些宏?是否可以預先命名目錄與sasmacr不同?

回答

2

我不認爲你可以將目錄從SASMACR重命名,並仍然直接使用它。但是,您可以使用PROC CATALOG來管理SASMACR目錄。

你想要做的是,當你想包括一個特定的宏,將它從proc catalog從其源位置複製到您選擇的SASMSTORE位置。

喜歡的東西:

libname myMacros 'C:\temp'; 
libname pwd '.'; 

options mstored sasmstore=pwd; 

proc catalog catalog=myMacros.HelloWorld; 
    copy out=pwd.sasmacr; 
run; 
quit; 


%HelloWorld(); 

現在 - 我建議這可能是矯枉過正;真的沒有理由以這種方式分開的宏目錄。如果您喜歡單獨包含文件的想法,您可能需要考慮Autocall宏(您不會將它們存儲爲已編譯,但存儲它們的源代碼和按需編譯);無論如何,真正編譯一個宏在SAS中幾乎沒有任何成本。但是如果使用存儲編譯的宏是你喜歡的,那麼這種方法可能是最好的方法。

當然,我認爲更簡單的方法是離開目錄SASMACR.SAS7BCAT並使用目錄名稱來確定它是什麼,然後將librefs附加到您的sasmstore選項值。

+0

我堅決主張在唯一命名的目錄中需要宏。關鍵是能夠與其他人分享項目特定的宏。目錄似乎是SAS認可的唯一容器。如果沒有目錄,宏必須在加載前的某個時刻作爲單個文件存在。這可能會造成損失,修改等情況。它會限制控制。此外,在使用同一人員處理多個項目時,單個目錄名稱會成爲問題。一個人可能有幾個'sasmacr'文件,每個文件對應不同的項目。解決方案是單獨的目錄名稱。 –

+0

從SAS:認證準備指南,第4部分,第12章,「使用存儲的編譯宏」一節中,「Sasmacr是唯一可以存儲編譯宏的目錄,您可以在任何SAS庫中創建一個名爲Sasmacr的目錄。不要重命名此目錄或其條目。「是否可以將'sasmacr'本身存儲在一個可能具有唯一名稱的目錄中? –

+0

解決方案有幾個不同的_folders_,至少據我可以告訴SAS你會這樣做。然後libname到每個文件夾。這就是你的第二個評論的答案:把每個文件夾放在一個唯一的文件夾中,然後將libname放到每個文件夾中,這實際上就是你所描述的所有意圖和目的。 – Joe

2

至少在使用SAS 9.4的Unix上,您可以使用SASAUTOS選項指向使用ZIP引擎的FILEREF,以便將所有宏定義存儲在一個ZIP文件中。

一個「訣竅」是,您需要更改ZIP文件中成員文件的名稱。通常在Unix上,SASAUTOS要求源文件使用小寫的宏名稱命名,其.sas擴展名(helloworld.sas)。但是,對於SASAUTOS使用ZIP文件,應該使用大寫字母的名稱以NO擴展名(HELLOWORLD)命名成員。

filename mymacros zip '~/mymacros.zip'; 
options insert=(sasautos=(mymacros)) ; 

EDIT

不幸的是這種方法會導致SAS生成錯誤:消息時在ZIP文件中沒有找到宏源文件,即使是在SASAUTOS選項另一個文件最終發現搜索路徑。

+1

像這樣的東西適用於Windows。一個可以發出 '文件名mymacros拉鍊 'C:\ myMacros \ HelloWorld.zip' fileext lowcase_memname;' '選項SASAUTOS =(mymacros sasautos);' 但是,您將無法運行'filename'語句的更多如下所示:http://support.sas.com/kb/31/540.html 我更改了基於http://support.sas.com/kb/44/791的'options'語句.html 而FILENAME ZIP有這裏給出的選項:http://support.sas.com/documentation/cdl/en/lestmtsref/68024/HTML/default/viewer.htm#n1dn0f61yfyzton1l2ngsa1clllr.htm –

+0

這非常漂亮!分享宏庫的好方法,或者存儲替代宏庫並指向它們。如果您可以使用寫入密碼鎖定.zip文件,這將是避免意外更改的簡單方法。這似乎是一種很好的方式來實現將宏存儲在單個文件中的目標。 – Quentin

+0

感謝您提供zip引擎選項的提示。在SASAUTOS中使用鎖定文件參數的「bug」已經存在很長時間了。當使用目錄存儲自動調用宏時,我總是使用SASAUTOS中的物理路徑而不是fileref,因此,要利用ZIP引擎,您需要使用fileref。如果您想要在單個會話中切換要引用的宏集,那麼您將需要創建唯一的文件提示,而不是嘗試重用常用fileref來指向不同的ZIP文件。 – Tom

1

從DATA_NULL_我已收到如何使用具有不同名稱的現有目錄的答案。使用CATNAME語句。所以如果你有目錄TEST.CAT1和TEST.CAT2,你可以使用CATNAME語句來使TEST.SASMACR成爲兩個宏的連接。

CATNAME test.sasmacr 
    (test.cat1 (ACCESS=READONLY) 
    test.cat2 (ACCESS=READONLY) 
) 
; 

您現在可以將SASMSTORE選項指向TEST libref。

option mstored sasmstore=test; 

這裏是你如何可以創建使用PROC CATALOG來複制已經被編譯成一個SASMACR目錄與名稱不同的目錄成員這樣的單獨目錄的例子。

libname templib '~/test/cat1'; 
libname permlib '~/test'; 
options mstored sasmstore=templib; 

%macro HelloWorld1()/store source; 
    data _null_; 
    put "Hello, World! &sysmacroname"; 
    run; 
%mend; 

%macro HelloWorld2()/store source; 
    data _null_; 
    put "Hello, World! &sysmacroname"; 
    run; 
%mend; 

proc catalog cat=templib.sasmacr ; 
    copy out=permlib.cat1; 
     select helloworld1 /et=macro; 
    run; 
    copy out=permlib.cat2; 
     select helloworld2 /et=macro; 
    run; 
quit; 

現在使用CATNAME命令將目錄鏈接在一起。

options mstored sasmstore=permlib; 
CATNAME permlib.sasmacr 
    (permlib.cat1 (ACCESS=READONLY) 
    permlib.cat2 (ACCESS=READONLY) 
); 

%helloworld1; 
%helloworld2;