SAS:重命名宏目录
SAS: Rename a Macro Catalog
我想将宏存储在目录中。这样做允许许多宏仅与一个文件共享,并引入了与用户一定程度的分离。
为了存储我的宏,我 运行 一个程序,例如
/* 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;
这会在 HelloWorld.sas
所在的目录中创建一个 sasmacr.sas7bcat
文件。然后我可以将该文件移动到另一个目录,例如 C:\myMacros
和 运行 以下程序:
/* CallHelloWorld.sas */
libname myMacros 'C:\myMacros';
option mstored sasmstore=myMacros;
%HelloWorld();
调用宏 HelloWorld()
没有错误。
但是,如果我想将 HelloWorld()
宏视为 "HelloWorld" 宏套件的一部分,我不能简单地将 Windows Explorer 中的目录名称从 sasmacr.sas7bcat
到 HelloWorld.sas7bcat
。当我这样做并再次尝试 运行ning 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
不同的名称?
我认为您不能将目录重命名为远离 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
选项值。
至少在带有 SAS 9.4 的 Unix 上,您可以使用 SASAUTOS 选项指向使用 ZIP 引擎的 FILEREF,以便所有宏定义都存储在一个 ZIP 文件中。
一个"trick"是您需要更改ZIP文件中成员文件的名称。通常在 unix 上,SASAUTOS 要求源文件使用小写的宏名称和 .sas
扩展名 (helloworld.sas
) 命名。但是要让 SASAUTOS 使用 ZIP 文件,成员应该使用大写的宏名称命名,没有扩展名 (HELLOWORLD
)。
filename mymacros zip '~/mymacros.zip';
options insert=(sasautos=(mymacros)) ;
编辑
不幸的是,当在 ZIP 文件中找不到宏源文件时,此方法会导致 SAS 生成 ERROR: 消息,即使最终在 SASAUTOS 选项搜索路径中的另一个文件中找到它也是如此。
来自 DATA_NULL_ 我收到了关于如何使用不同名称的现有目录的答案。使用 CATNAME 语句。因此,如果您有目录 TEST.CAT1 和 TEST.CAT2,则可以使用 CATNAME 语句使 TEST.SASMACR 成为两个宏的串联。
CATNAME test.sasmacr
(test.cat1 (ACCESS=READONLY)
test.cat2 (ACCESS=READONLY)
)
;
您现在可以将 SASMSTORE 选项指向 TEST 库引用。
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;
我想将宏存储在目录中。这样做允许许多宏仅与一个文件共享,并引入了与用户一定程度的分离。
为了存储我的宏,我 运行 一个程序,例如
/* 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;
这会在 HelloWorld.sas
所在的目录中创建一个 sasmacr.sas7bcat
文件。然后我可以将该文件移动到另一个目录,例如 C:\myMacros
和 运行 以下程序:
/* CallHelloWorld.sas */
libname myMacros 'C:\myMacros';
option mstored sasmstore=myMacros;
%HelloWorld();
调用宏 HelloWorld()
没有错误。
但是,如果我想将 HelloWorld()
宏视为 "HelloWorld" 宏套件的一部分,我不能简单地将 Windows Explorer 中的目录名称从 sasmacr.sas7bcat
到 HelloWorld.sas7bcat
。当我这样做并再次尝试 运行ning 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
不同的名称?
我认为您不能将目录重命名为远离 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
选项值。
至少在带有 SAS 9.4 的 Unix 上,您可以使用 SASAUTOS 选项指向使用 ZIP 引擎的 FILEREF,以便所有宏定义都存储在一个 ZIP 文件中。
一个"trick"是您需要更改ZIP文件中成员文件的名称。通常在 unix 上,SASAUTOS 要求源文件使用小写的宏名称和 .sas
扩展名 (helloworld.sas
) 命名。但是要让 SASAUTOS 使用 ZIP 文件,成员应该使用大写的宏名称命名,没有扩展名 (HELLOWORLD
)。
filename mymacros zip '~/mymacros.zip';
options insert=(sasautos=(mymacros)) ;
编辑
不幸的是,当在 ZIP 文件中找不到宏源文件时,此方法会导致 SAS 生成 ERROR: 消息,即使最终在 SASAUTOS 选项搜索路径中的另一个文件中找到它也是如此。
来自 DATA_NULL_ 我收到了关于如何使用不同名称的现有目录的答案。使用 CATNAME 语句。因此,如果您有目录 TEST.CAT1 和 TEST.CAT2,则可以使用 CATNAME 语句使 TEST.SASMACR 成为两个宏的串联。
CATNAME test.sasmacr
(test.cat1 (ACCESS=READONLY)
test.cat2 (ACCESS=READONLY)
)
;
您现在可以将 SASMSTORE 选项指向 TEST 库引用。
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;