【问题标题】:SAS - create macro-name from variableSAS - 从变量创建宏名
【发布时间】:2013-10-31 12:49:18
【问题描述】:

我想知道如何从变量中设置宏名称。

像这样:

    %Macro test(name);
      ... 
      %Macro new_&name;
        ... 
      %Mend;
      ... 
    %Mend test

或者如果这是不可能的:

    %macro one(name);
       %let mname=&name;
    %mend one;

    %macro two_&name;
      ...
    %mend;

有什么想法吗?非常感谢。

【问题讨论】:

  • 我想你的建议会奏效......你试过了吗?但是你为什么要做这样的事情呢?我没有看到应用程序。
  • 您好 ESmith,当然我确实测试了我的建议,但两者都不起作用。我有一个使用非常深嵌套的程序 sn-ps 的问题。为了使它们更具可读性和可用性,我必须从具有宏名称的宏中生成宏,我可以设置可编程而不是手动设置。希望这能让问题更清楚:)

标签: sas sas-macro


【解决方案1】:

我想到的第一件事是使用临时文件引用来构建宏。然后包含该文件引用。

我认为这可以满足您的需求:

%macro test(x,file);
data _null_;
file &file;
format outStr $2000.;

    outStr = ('%macro test_' || strip("&x") || "();");
    put outStr;
    put '%put hello world;';
    outStr =  '%put Passed in value is x:' || "&x and file: &file;";
    put outStr;
    put "proc means data=sashelp.class(obs=&x) mean; var age; run;";
    put '%mend;';
run;
%include &file;
%mend;

filename tempfile temp;
%test(2,tempfile);
%test_2;

filename tempfile clear;

【讨论】:

  • 这种方法的好处是您可以轻松地将 fileref 设为永久文件。这将允许您查看生成的代码。对调试或以后重用很有用。
【解决方案2】:

是的,你可以这样做:

%macro macroFunc();
    %put hi there;
%mend;
%macro macroCall(macroName);
    %&macroName.();
%mend;
%mcr2(macroFunc);

但我真的很好奇这在什么情况下是有意义的。 似乎它很快就会导致编码混乱。

【讨论】:

  • 我在开发需要“插件”的系统时经常使用它。给定一个声明的签名,创建 N 个宏来做事(通常适合不同类型的计量经济学模型)。然后有一个数据驱动的系统来拟合模型。它类似于 OO 语言中的接口。
  • 嗨 Shorack,感谢您的帮助。对我来说,不清楚您的程序如何解决我的问题。我从您的程序中了解到: 1)定义一个名为 macrofunc 的宏。除了将一条消息写入日志之外,这里什么都不做。 2) 定义一个名为macroCall 的宏。这里提交一个参数(宏名)。然后将参数宏名连接到大括号。所以这个大括号应该替换为我想要的后面宏的名称。例如。 %&macroName.new;或者像我的例子一样 %new_&macroName; 3) 调用尚未定义的宏?希望你能帮忙。
  • @DomPazz 如果你经常使用这个,你会这么好心并提交你对这个问题的解决方案。非常感谢
  • 嗯是的。您不仅需要动态获取要调用的名称,还需要动态创建宏名称。在那种情况下,它确实对你没有帮助。 :(
  • @PeterSamuelson,我的评论来自 Shorack 的评论,即他所做的事情没有意义。我重读了您的问题,cmets,并且将不得不考虑如何最好地解决问题。
【解决方案3】:

我从不知道您不能在 %MACRO 语句中使用变量...但似乎确实如此。正如 SAS 文档 (http://support.sas.com/documentation/cdl/en/mcrolref/61885/HTML/default/viewer.htm#macro-stmt.htm) 中所说,“您不能使用文本表达式在 %MACRO 语句中生成宏名称。”

我的下一个想法是,您也许可以将 %MACRO 语句创建为变量,但我找不到在创建变量时屏蔽 %MACRO 的方法。

我终于想出了一个解决方法,但这可能不是最好的方法(而且它可能不适用于您想要做的事情)。我发现我可以在数据步骤中编译宏语句。不幸的是,当整个宏代码(从 %MACRO 到 %MEND 语句)保存在变量中时,我只能从变量运行宏。请参阅下面的代码。

%MACRO test(name);
data test;
    *COMPILE MACRO STATEMENT;
    pct=%nrstr('%');
    name="new_&name";
    beginning=pct||'MACRO '||strip(name)||'();';

    *CODE TO BE INSIDE MACRO;
    /*Note: SAS will encounter errors if you try to assign text containing macro 
      functions (e.g., %PUT, %IF, etc.) to a variable. To get around this, you must
      put hide the % in the following syntax, %nrstr('%'), and concatenate/join the 
      syntax with the rest of the string */
    code=pct||'PUT HELLO!;';

    *COMPILE MEND STATEMENT;
    end=pct||'MEND;';

    call symput('MacroStatement',beginning||code||end); *Output var containing macro;
    call symput('Execute',pct||strip(name)||';'); *Output var containing statement to run macro;
    output;
run;

&MacroStatement
&Execute

%MEND;
%test(name1);

【讨论】:

    【解决方案4】:
    options mprint mlogic symbolgen nospool;
    
    %let definition=abc;
    
    %let mdef=macro &definition.;
    
    %&mdef.;
        %put TEST;
    %mend;
    
    
    %abc;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-04
      • 2013-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多