SAS-从变量创建宏名称

SAS-从变量创建宏名称,sas,sas-macro,Sas,Sas Macro,我想知道如何从变量设置宏名称 像这样: %Macro test(name); ... %Macro new_&name; ... %Mend; ... %Mend test 或者,如果不可能: %macro one(name); %let mname=&name; %mend one; %macro two_&name; ...

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

像这样:

    %Macro test(name);
      ... 
      %Macro new_&name;
        ... 
      %Mend;
      ... 
    %Mend test
或者,如果不可能:

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

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

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

是的,你可以做这样的事情:

%macro macroFunc();
    %put hi there;
%mend;
%macro macroCall(macroName);
    %&macroName.();
%mend;
%mcr2(macroFunc);
但我真的很好奇这在什么情况下有意义。
似乎很快就会导致编码混乱。

是的,您可以这样做:

%macro macroFunc();
    %put hi there;
%mend;
%macro macroCall(macroName);
    %&macroName.();
%mend;
%mcr2(macroFunc);
但我真的很好奇这在什么情况下有意义。
似乎它很快就会导致编码混乱。

我从来都不知道不能在%宏语句中使用变量……但事实似乎就是这样。正如SAS文档()中所述,“不能使用文本表达式在%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);

我从来不知道你不能在%宏语句中使用变量……但事实似乎就是这样。正如SAS文档()中所述,“不能使用文本表达式在%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);

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

我想这正是你想要的:

%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来构建宏。然后包括该fileref

我想这正是你想要的:

%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;

我想你的建议会奏效……你试过了吗?但你为什么要做这样的事?我看不到应用程序。你好,ESmith,我当然测试了我的建议,但两者都不起作用。我有一个问题,它利用了嵌套非常深的程序片段。为了使它们更具可读性和可用性,我必须用宏名生成宏,我可以设置为可编程,而不是每手。希望这能让问题变得更清楚:)我想你的建议会奏效……你试过了吗?但你为什么要做这样的事?我看不到应用程序。你好,ESmith,我当然测试了我的建议,但两者都不起作用。我有一个问题,它利用了嵌套非常深的程序片段。为了使它们更具可读性和可用性,我必须用宏名生成宏,我可以设置为可编程,而不是每手。希望这能让问题更清楚一点:)我在开发需要“插件”的系统时经常使用它。给定一个声明的签名,创建N个宏来做事情(通常适合不同类型的经济计量模型)。然后有一个数据驱动系统来适应模型。它类似于OO语言中的接口。嗨,Shorack,谢谢你的帮助。对我来说,不清楚你的程序如何解决我的问题。我从您的程序中了解到:1)定义一个名为macrofunc的宏。除了将消息写入日志外,此处不执行任何操作。2) 定义名为macroCall的宏。这里提交一个参数(宏名称)。然后将参数宏名称连接到大括号。所以这个大括号应该替换为后面宏的名称。例如,%和macroName.new;或者像我的示例中的%new\macroName;3) 调用尚未定义的宏?希望您能帮上忙。@DomPazz如果您经常使用这个,请您提交您对这个问题的解决方案。很多人都很感激。您不仅需要动态获取要调用的名称,还需要动态创建宏名称。在这种情况下,它实际上对你没有帮助(@PeterSamuelson,我的评论来自Shorack的评论,他所做的没有意义。我重新阅读了你的问题、评论,并将不得不思考如何最好地解决问题。我经常在开发需要“插件”的系统时使用这一点。给定一个声明的签名,创建N个宏来完成任务(通常适合不同类型的经济计量模型)。然后使用数据驱动系统来适应模型。这类似于OO语言中的界面。嗨,Shorack,谢谢你的帮助。对我来说,不清楚你的程序如何解决我的问题。我从你的程序中了解到:1)定义一个名为macrofunc的宏。除了将消息写入日志外,此处不执行任何操作。2)定义一个名为macroCall的宏。这里提交一个参数(宏名称)。然后将参数宏名称连接到大括号。所以这个大括号应该替换为后面宏的名称。例如,%和macroName.new;或者像我的示例中的%new\macroName;3) 调用尚未定义的宏?希望您能帮上忙。@DomPazz如果您经常使用这个,请您提交您对这个问题的解决方案。很多人都很感激。您不仅需要动态获取要调用的名称,还需要动态创建宏名称。在这种情况下,它实际上对你没有帮助(@PeterSamuelson,我的评论来自Shorack的评论,他所做的没有意义。我重新阅读了你的问题、评论,并将不得不考虑如何