SAS:重命名宏目录

时间:2016-10-25 20:52:48

标签: macros sas 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;

这会在sasmacr.sas7bcat所在的目录中创建一个HelloWorld.sas文件。然后我可以将该文件移动到另一个目录,例如C:\myMacros并运行以下程序:

/* CallHelloWorld.sas */
libname myMacros 'C:\myMacros';
option mstored sasmstore=myMacros;

%HelloWorld();

调用宏HelloWorld()时没有错误。

但是,如果我想将HelloWorld()宏视为" HelloWorld"宏套件,我不能简单地将Windows资源管理器中的目录名称从sasmacr.sas7bcat更改为HelloWorld.sas7bcat。当我这样做并尝试再次运行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的目录?

3 个答案:

答案 0 :(得分:3)

至少在使用SAS 9.4的Unix上,您可以使用SASAUTOS选项指向使用ZIP引擎的FILEREF,以便将所有宏定义存储在单个ZIP文件中。

一个"技巧"是你需要更改ZIP文件中的成员文件的名称。通常在unix上,SASAUTOS要求使用小写的宏名称以.sas扩展名(helloworld.sas)命名源文件。但是,对于SASAUTOS使用ZIP文件,成员应使用大写的宏名称命名,并且没有扩展名(HELLOWORLD)。

filename mymacros zip '~/mymacros.zip';
options insert=(sasautos=(mymacros)) ;

修改

不幸的是,这种方法导致SAS在ZIP文件中找不到宏源文件时生成错误:消息,即使它最终在SASAUTOS选项搜索路径中的另一个文件中找到。

答案 1 :(得分:2)

我不认为您可以将目录重命名为远离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();

现在 - 我认为这可能是矫枉过正;我没有理由以这种方式拥有单独的宏目录。如果您喜欢单独包含文件的想法,您可能需要考虑自动调用宏(您不会将它们存储在已编译的位置,而是存储它们的源代码并按需编译);无论如何,真正编译宏的成本几乎没有任何成本。但是如果你喜欢使用存储编译的宏,这种方法可能是最好的方法。

当然,我认为更简单的方法是保留目录SASMACR.SAS7BCAT并使用目录名来确定它是什么,然后将librefs附加到sasmstore选项值。

答案 2 :(得分:1)

从DATA_NULL_我收到了如何使用具有不同名称的现有目录的答案。使用CATNAME语句。因此,如果您有目录TEST.CAT1和TEST.CAT2,则可以使用CATNAME语句使TEST.SASMACR成为两个宏的串联。

CATNAME test.sasmacr
  (test.cat1 (ACCESS=READONLY)
   test.cat2 (ACCESS=READONLY)
  )
;

现在,您可以将SASMSTORE选项指向TEST libref。

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;