我想在几个自动调用库中有数百个宏,我想使用MSTORE
工具进行编译。
问题是其中一些库在其他网站上使用 - 我们不想在每个定义中添加/STORE
,因为必需才能使用{ {1}}选项。
我想答案是在每个MSTORED
语句的末尾添加/* /STORE */
,以便可以使用正则表达式(或其他一些文本替换技术)更新.sas程序文件。每次重新部署,但这似乎是一个混乱的解决方法。
是否有可能/以某种方式支持编译常规(未修改)自动调用宏并存储定义?例如,通过%macro
每个人并保存工作宏目录,或类似的东西?
答案 0 :(得分:3)
我绝对不能说这是不可能的,但我可以报告说我前段时间试图做同样的事情并且卡在同一点上。除了将/store
添加到每个%macro
语句之外,我也无法找到任何其他方法。
我依稀记得我能够在同一台机器上将work.sasmacr
目录从一个会话上传到另一个会话(在首次编译几个自动调用宏以填充它之后),但另一个会话没有即使为使用存储的编译宏设置了适当的选项,也可以识别已传输目录中的宏定义。
我的动机与你的不同 - 我正在寻找一种方法在一个会话中定义宏并在另一个会话中执行它而不将其保存在autocall文件夹中或在%including
两个会话中保存它 - 但结论是相同。
答案 1 :(得分:2)
这是我采用的编译方法(当然还有很多替代方法)。要查询的位置可以从以下提取:
%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/macropeople/macrocore/blob/master/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 */
答案 2 :(得分:2)
你有什么问题?
首先编译所有自动调用宏。假设您有一个名为MYMACS的fileref,它指向包含源代码的目录。
%include mymacs(macro1,macro2,.....);
您可以使用程序搜索所有源文件,以便自动生成%include语句。或者您可以使用datastep并将所有源文件复制到一个临时文件中并包含该文件。
filename src temp;
data _null_;
infile "&inpath\*.sas" ;
file src ;
input;
put _infile_;
run;
%inc src ;
然后将WORK目录复制到新位置。请注意,如果在应用程序服务器上运行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 ;
然后尝试运行其中一个复制的编译宏。
现在启动一个新会话并尝试在该会话中使用已编译的宏。