Reputation: 13
I am wondering how I can set a macro-name from a variable.
Like this:
%Macro test(name);
...
%Macro new_&name;
...
%Mend;
...
%Mend test
Or if this is not possible:
%macro one(name);
%let mname=&name;
%mend one;
%macro two_&name;
...
%mend;
Any ideas? Many thanks.
Upvotes: 1
Views: 630
Reputation: 103
options mprint mlogic symbolgen nospool;
%let definition=abc;
%let mdef=macro &definition.;
%&mdef.;
%put TEST;
%mend;
%abc;
Upvotes: 1
Reputation: 12465
First thing that pops into my mind is to use a temporary fileref to build your macros. Then include that fileref.
I think this does what you are looking for:
%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;
Upvotes: 1
Reputation: 518
I never knew that you could not use a variable in a %MACRO statement...but that appears to be the case. As it says in the SAS documentation (http://support.sas.com/documentation/cdl/en/mcrolref/61885/HTML/default/viewer.htm#macro-stmt.htm) "you cannot use a text expression to generate a macro name in a %MACRO statement."
My next thought was that you might be able to create the %MACRO statement as a variable, but I couldn't find a way to mask %MACRO in the creation of the variable.
I finally figured out a work around, but it is likely not the best way to do this (and it may not work for what you're trying to do). I found that I could compile the macro statement in a data step. Unfortunately though, I could only run the macro from the variable when the entire macro code (from the %MACRO to the %MEND statement) was saved in the variable. See the code below.
%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);
Upvotes: 1
Reputation: 1283
Yes you can do such a thing:
%macro macroFunc();
%put hi there;
%mend;
%macro macroCall(macroName);
%¯oName.();
%mend;
%mcr2(macroFunc);
But I'm really curious in what context this makes sense. Seems like it will in no time result into a coding mess.
Upvotes: 1