将自动调用库转换为存储的编译宏
Converting autocall libraries to stored compiled macros
我想使用 MSTORE
工具编译几个自动调用库中的数百个宏。
问题是其中一些库在其他站点上使用 - 我们不想在每个定义中添加 /STORE
,因为那时 需要 使用 MSTORED
选项。
我想答案是在每个 %macro
语句的末尾添加 /* /STORE */
,这样 .sas 程序文件就可以用正则表达式(或其他一些文本替换技术)更新) 在每次重新部署时,但这似乎是一个混乱的解决方法。
是否有可能/以某种方式支持编译常规(未修改的)自动调用宏并存储定义?例如,通过 %inc
'ing 每个并保存工作宏目录,或类似的东西?
我不会明确地说这是不可能的,但我可以报告说我前段时间尝试做同样的事情并且卡在了同一点上。除了将 /store
添加到每个 %macro
语句之外,我也找不到任何方法可以做到这一点。
我依稀记得我能够将 work.sasmacr
目录从一个会话上传到同一台机器上的另一个会话(在首先编译一些自动调用宏来填充它之后),但另一个会话没有即使为使用存储的编译宏设置了适当的选项,也能识别传输目录中的宏定义。
我的动机与你不同 - 我正在寻找一种方法来在一个会话中定义一个宏并在另一个会话中执行它而不将其保存在自动调用文件夹中或 %including
在两个会话中 - 但是结论是一样的。
这是我编译的方法(当然还有很多替代方法)。要查询的位置可以从中提取:
%put %sysfunc(getoption(sasautos));
该方法依赖于使用 )/*/STORE SOURCE*/;
关闭的宏,如下所示:
%macro some_macro(var1=x, var2=y
)/*/STORE SOURCE*/;
SAS 代码必须是程序,因为您不能从宏内部创建存储的编译宏。
/* set mstore options */
options mstored sasmstore=yourlib;
/* get list of macros */
/* taken from macrocore library */
/*https://github.com/sasjs/core/blob/main/base/mp_dirlist.sas*/
%mp_dirlist(path=/location/one,outds=in1)
%mp_dirlist(path=/location/two,outds=in2)
/* set up a temporary fileref */
filename tmp temp;
/**
* write each source macro to the fileref
* and switch on the STORE option
*/
data want;
set in1 in2;
infile dummy filevar=filepath end=last ;
file tmp;
do until(last);
file tmp;
input;
if _infile_=')/*/STORE SOURCE*/;' then put ')/STORE SOURCE;';
else put _infile_;
end;
run;
%inc tmp; /* compile macros */
filename tmp clear; /* clear ref */
你遇到了什么问题?
首先编译所有的自动调用宏。假设您有一个名为 MYMACS 的文件引用,它指向包含源代码的目录。
%include mymacs(macro1,macro2,.....);
您可以使用程序搜索所有源文件,以便自动生成 %include 语句。或者您可以使用数据步骤并将所有源文件复制到一个临时文件中并包含它。
filename src temp;
data _null_;
infile "&inpath\*.sas" ;
file src ;
input;
put _infile_;
run;
%inc src ;
然后将WORK 目录复制到您的新位置。请注意,如果您在应用程序服务器上 运行ning SAS,名称会有所不同。在这种情况下,请尝试从 WORK.SASMAC1
而不是 WORK.SASMACR
.
复制
libname out base "&path";
proc catalog cat=work.sasmacr et=macro ;
copy out=out.sasmacr ;
run;
quit;
您可以通过清除当前工作宏目录来测试它是否有效,这样您就知道 SAS 没有在那里找到宏,并设置选项以指向已编译宏的新目录。
proc catalog cat=work.sasmacr kill force ;
quit;
options mrecall mstored sasmstore=out ;
然后尝试 运行 复制的编译宏之一。
现在启动一个新会话并尝试在该会话中使用已编译的宏。
我想使用 MSTORE
工具编译几个自动调用库中的数百个宏。
问题是其中一些库在其他站点上使用 - 我们不想在每个定义中添加 /STORE
,因为那时 需要 使用 MSTORED
选项。
我想答案是在每个 %macro
语句的末尾添加 /* /STORE */
,这样 .sas 程序文件就可以用正则表达式(或其他一些文本替换技术)更新) 在每次重新部署时,但这似乎是一个混乱的解决方法。
是否有可能/以某种方式支持编译常规(未修改的)自动调用宏并存储定义?例如,通过 %inc
'ing 每个并保存工作宏目录,或类似的东西?
我不会明确地说这是不可能的,但我可以报告说我前段时间尝试做同样的事情并且卡在了同一点上。除了将 /store
添加到每个 %macro
语句之外,我也找不到任何方法可以做到这一点。
我依稀记得我能够将 work.sasmacr
目录从一个会话上传到同一台机器上的另一个会话(在首先编译一些自动调用宏来填充它之后),但另一个会话没有即使为使用存储的编译宏设置了适当的选项,也能识别传输目录中的宏定义。
我的动机与你不同 - 我正在寻找一种方法来在一个会话中定义一个宏并在另一个会话中执行它而不将其保存在自动调用文件夹中或 %including
在两个会话中 - 但是结论是一样的。
这是我编译的方法(当然还有很多替代方法)。要查询的位置可以从中提取:
%put %sysfunc(getoption(sasautos));
该方法依赖于使用 )/*/STORE SOURCE*/;
关闭的宏,如下所示:
%macro some_macro(var1=x, var2=y
)/*/STORE SOURCE*/;
SAS 代码必须是程序,因为您不能从宏内部创建存储的编译宏。
/* set mstore options */
options mstored sasmstore=yourlib;
/* get list of macros */
/* taken from macrocore library */
/*https://github.com/sasjs/core/blob/main/base/mp_dirlist.sas*/
%mp_dirlist(path=/location/one,outds=in1)
%mp_dirlist(path=/location/two,outds=in2)
/* set up a temporary fileref */
filename tmp temp;
/**
* write each source macro to the fileref
* and switch on the STORE option
*/
data want;
set in1 in2;
infile dummy filevar=filepath end=last ;
file tmp;
do until(last);
file tmp;
input;
if _infile_=')/*/STORE SOURCE*/;' then put ')/STORE SOURCE;';
else put _infile_;
end;
run;
%inc tmp; /* compile macros */
filename tmp clear; /* clear ref */
你遇到了什么问题?
首先编译所有的自动调用宏。假设您有一个名为 MYMACS 的文件引用,它指向包含源代码的目录。
%include mymacs(macro1,macro2,.....);
您可以使用程序搜索所有源文件,以便自动生成 %include 语句。或者您可以使用数据步骤并将所有源文件复制到一个临时文件中并包含它。
filename src temp;
data _null_;
infile "&inpath\*.sas" ;
file src ;
input;
put _infile_;
run;
%inc src ;
然后将WORK 目录复制到您的新位置。请注意,如果您在应用程序服务器上 运行ning SAS,名称会有所不同。在这种情况下,请尝试从 WORK.SASMAC1
而不是 WORK.SASMACR
.
libname out base "&path";
proc catalog cat=work.sasmacr et=macro ;
copy out=out.sasmacr ;
run;
quit;
您可以通过清除当前工作宏目录来测试它是否有效,这样您就知道 SAS 没有在那里找到宏,并设置选项以指向已编译宏的新目录。
proc catalog cat=work.sasmacr kill force ;
quit;
options mrecall mstored sasmstore=out ;
然后尝试 运行 复制的编译宏之一。
现在启动一个新会话并尝试在该会话中使用已编译的宏。