如何告诉 SAS 在每次调用宏时编译它而不是手动执行

use*_*080 2 sas sas-macro

上下文:我们使用SAS 9.4Enterprise Guide 7.15。目前,我们正在实施一些新的宏,当然在此过程中必须进行很多更改。有时较小,有时较大的变化。问题是,为了使更改生效,SAS需要我们手动编译宏代码或重新启动会话,这有点乏味。

这是我们主文件中的当前设置(调用所有宏):

/* Macro options */
     MAUTOSOURCE  sasautos = "<path to macro>" mlogic mlogicnest mprint mprintnest MRECALL
Run Code Online (Sandbox Code Playgroud)

在使用该MAUTOSOURCE */ sasautos =""选项时,是否可以告诉SAS每次调用宏时实际上也编译宏而不是使用会话存储的宏?理想情况下,宏只会在主文件(MAUTOSOURCE */ sasautos =""等)中的整行代码被执行时才被编译,否则它应该在会话中保留一个编译版本。

我发现这篇论文(SAS for Windows Environment 中的 Autocall Macro Facility)在结论中指出

之后 SAS 将使用已经编译的代码。如果对宏进行了更改,则必须在更改生效之前再次编译它。

我希望这并不意味着我必须手动完成。是否有任何宏选项可以设置?

Tom*_*Tom 5

在 SAS 9.3 中,他们添加了%SYSMACDELETE宏功能。因此,如果您只想让自动调用重新定义单个宏,请使用它来删除当前定义。

%symacdelete mymacro;
Run Code Online (Sandbox Code Playgroud)

这是一个实用程序宏,它将查询 SASHELP.VCATALG 视图以在 WORK 库中查找已编译的宏并删除它们。它可以选择列出要删除或保留的宏名称。请注意,普通 SAS 会话使用 WORK.SASMACR 来存储已编译的宏。但是 SAS/Studio 和 EG(也许还有其他运行 SAS 的方式)使用 WORK.SASMAC1 代替。

https://github.com/sasutils/macros/blob/master/macdelete.sas

%macro macdelete(delete,keep);
/*----------------------------------------------------------------------------
Remove compiled macros using %SYSMACDELETE macro statement.

Use DELETE parameter to list macro names to delete.
Use KEEP parameter to list macro names to NOT delete.
Calling it with no values will delete all macros not currently running.
----------------------------------------------------------------------------*/
%local libname memname objname objtype fid i;
%do i=1 %to %sysmexecdepth;
  %let keep=%sysmexecname(&i) &keep;
%end;
%if %length(&delete) %then %let delete=and findw("&delete",objname,',','sit');
%let fid=%sysfunc(open( sashelp.vcatalg(keep=libname memname objname objtype
 where=(libname='WORK' and objtype='MACRO' and memname like 'SASMAC_'
   and not findw("&keep",objname,',','sit') &delete))));
%if (&fid) %then %do;
  %syscall set(fid);
  %do %while(0=%sysfunc(fetch(&fid)));
    %put %sysfunc(compbl(Removing &objname from &libname catalog &memname));
    %sysmacdelete &objname;
  %end;
  %let fid=%sysfunc(close(&fid));
%end;
%else %put %qsysfunc(sysmsg());
%mend macdelete;
Run Code Online (Sandbox Code Playgroud)

例子:

3348  %macro test1; %mend;
3349  %macro test2; %mend;
3350  %macro test3; %mend;
3351  %macro test4; %mend;
3352  %macdelete(test1 test3);
Removing TEST1 from WORK catalog SASMACR
Removing TEST3 from WORK catalog SASMACR
3353  %macdelete(keep=test2);
Removing TEST4 from WORK catalog SASMACR
Run Code Online (Sandbox Code Playgroud)

运行 SAS/Studio 或 Enterprise Guide 时的示例:

 97         %macro test1; %mend;
 98         %macro test2; %mend;
 99         %macro test3; %mend;
 100        %macro test4; %mend;
 101        %macdelete(test1 test3);
 Removing TEST1 from WORK catalog SASMAC1
 Removing TEST3 from WORK catalog SASMAC1
Run Code Online (Sandbox Code Playgroud)