我想将宏存储在目录中。这样做可以让许多宏只与一个文件共享,并且与用户引入一定程度的分离。
要存储我的宏,我运行一个程序,如
/* 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
的目录?
答案 0 :(得分:3)
至少在使用SAS 9.4的Unix上,您可以使用SASAUTOS选项指向使用ZIP引擎的FILEREF,以便将所有宏定义存储在单个ZIP文件中。
一个"技巧"是你需要更改ZIP文件中的成员文件的名称。通常在unix上,SASAUTOS要求使用小写的宏名称以.sas
扩展名(helloworld.sas
)命名源文件。但是,对于SASAUTOS使用ZIP文件,成员应使用大写的宏名称命名,并且没有扩展名(HELLOWORLD
)。
filename mymacros zip '~/mymacros.zip';
options insert=(sasautos=(mymacros)) ;
修改强>
不幸的是,这种方法导致SAS在ZIP文件中找不到宏源文件时生成错误:消息,即使它最终在SASAUTOS选项搜索路径中的另一个文件中找到。
答案 1 :(得分: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();
现在 - 我认为这可能是矫枉过正;我没有理由以这种方式拥有单独的宏目录。如果您喜欢单独包含文件的想法,您可能需要考虑自动调用宏(您不会将它们存储在已编译的位置,而是存储它们的源代码并按需编译);无论如何,真正编译宏的成本几乎没有任何成本。但是如果你喜欢使用存储编译的宏,这种方法可能是最好的方法。
当然,我认为更简单的方法是保留目录SASMACR.SAS7BCAT
并使用目录名来确定它是什么,然后将librefs附加到sasmstore
选项值。
答案 2 :(得分: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;