1

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.

2
  • I imagine what you are suggesting would work...have you tried it? But why would you want to do something like this? I am failing to see the application. Commented Oct 31, 2013 at 13:29
  • 1
    Hello ESmith, of course I did test my suggestions and both are not working. I have an issue which makes use of very deeply nested program snippets. To get them more readable and useable I have to generate macros out of macros with macro-names I can set programeable and not per hand. Hope this makes the issue a bit clearer :) Commented Nov 4, 2013 at 7:43

4 Answers 4

1

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;
Sign up to request clarification or add additional context in comments.

1 Comment

Positive thing about this approach is that you can easily make the fileref a permanent file. That would allow you to see the generated code. Useful for debugging or later reuse.
1

Yes you can do such a thing:

%macro macroFunc();
    %put hi there;
%mend;
%macro macroCall(macroName);
    %&macroName.();
%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.

5 Comments

I've often used this when developing a system that needs "plug-ins." Given a stated signature, create N macros to do things (often fit a different type of econometric model). Then have a data driven system to fit models. It's analogous to an interface in an OO language.
Hi Shorack, thank you for your help. For me it is not clear how your program could resolve my issue. What I understand from your program is: 1) Defining a macro with the name macrofunc. Nothing is done here except a message is written to the log. 2) Defining a macro with the name macroCall. Here one parameter (macroname) is submitted. The parameter macroname is then concatenated to braces. So this braces should be replaced for the name I want for the later macro. Eg. %&macroName.new; or like in my example %new_&macroName; 3) Calling a macro which has not been defined? Hope you can help out.
@DomPazz if you often use this, would you be so kind and submit your solution for this problem. Many thanks
Hmm yes. You do not only need to dynamically get the name to call, but also dynamically create the macro name. In that case, it is not helping you indeed. :(
@PeterSamuelson, my comment was from Shorack's comment that what he was doing didn't make sense. I reread your question, comments and will have to think how to best solve the problem.
1

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

Comments

1
options mprint mlogic symbolgen nospool;

%let definition=abc;

%let mdef=macro &definition.;

%&mdef.;
    %put TEST;
%mend;


%abc;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.