代码之家  ›  专栏  ›  技术社区  ›  Allan Bowe

将自动调用库转换为存储的编译宏

  •  2
  • Allan Bowe  · 技术社区  · 7 年前

    我们在几个自动调用库中有数百个宏,我想使用 MSTORE 设施

    问题是,其中一些库在其他网站上使用,我们不想添加 /STORE 必修的 MSTORED 选项

    我想答案是加上 /* /STORE */ 在每个 %macro 声明,使。sas程序文件可以在每次重新部署时使用正则表达式(或其他一些文本替换技术)进行更新,但这似乎是一个混乱的解决方法。

    是否可以/以某种方式支持编译常规(未修改)自动调用宏并存储定义?Eg由 %inc “保存每个工作宏目录,或者诸如此类的东西?

    3 回复  |  直到 7 年前
        1
  •  3
  •   user667489    7 年前

    我不会肯定地说这是不可能的,但我可以报告说,我前一段时间试图做同样的事情,但在同一点上卡住了。我也找不到除了添加 /store 致每一位 %macro 陈述

    我隐约记得我可以上传 work.sasmacr 在同一台机器上从一个会话到另一个会话的目录(在首先编译几个自动调用宏来填充它之后),但另一个会话无法识别传输目录中的宏定义,即使为使用存储的编译宏设置了适当的选项。

    我的动机与你的不同——我在寻找一种方法,在一个会话中定义宏,并在另一个会话中执行它,而不将其保存在自动调用文件夹或 %including 这两次会议的结论都是一样的。

        2
  •  2
  •   Tom    7 年前

    首先编译所有自动调用宏。假设您有一个名为MYMACS的fileref,它指向包含源代码的目录。

    %include mymacs(macro1,macro2,.....);
    

    您可以使用一个程序来搜索所有源文件,以便可以自动生成%include语句。或者可以使用datastep将所有源文件复制到一个临时文件中,并将其包括在内。

    filename src temp;
    data _null_;
      infile "&inpath\*.sas" ;
      file src ;
      input;
      put _infile_;
    run;
    %inc src ;
    

    然后将工作目录复制到一个新位置。请注意,如果您在应用程序服务器上运行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 ;
    

    然后尝试运行一个复制的编译宏。

    现在启动一个新会话,并尝试在该会话中使用编译的宏。

        3
  •  2
  •   Allan Bowe    4 年前

    这是我采用的编译方法(当然有很多替代方法)。要查询的位置可以从以下位置提取:

    %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 */