2016-10-25 155 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;