BookmarkSubscribeRSS Feed
jojo
Obsidian | Level 7

I need to call a macro( B ) in another macro(A). in macro A, two variables x1, x2 are created and used as parameters for macro B.  Thanks for your help in advance.

%macro B (param1, param2);

Code;

%mend B;

%macro A(x,y);

     Code… to create x1, x2;

     %B(x1,x2);    

%mend A;

%A(n1,n2);

7 REPLIES 7
ballardw
Super User

How you create x1 and x2, and possibly what they look like such as a single numeric, single string or multiple numerics or strings are likely to have an impact on how you get the values ready for the call to %B. Will X1 and X2 be in a data set? If so will it have multiple rows and does %B need to be called for each set of values?

Reeza
Super User

Did that give you errors?

Tom
Super User Tom
Super User

Two dataset variables or two macro variables.

To reference the value of macro variable you need to preface the name with an ampersand (&).

Also your code will probably by clearer if you use the parameter names in the macro call (note that you can reference positional parameters by name in a macro call).

So in your example the call to macro B would probably look like:  %B(param1=&x1,param2=&x2)

And then when B is running any reference to &PARAM1 will be replaced with the value that that was supplied when B was called.

jojo
Obsidian | Level 7

two dataset variables. the following code gives errors.

%macro B (param1, param2);

   Code;

%mend B;

%macro A(param1,param2);

     Code…  ***  here to create a dataset and several variables. two sets of dataset varibles x1, x2, y1, y2 (numerical value) are used for macro B;

     %B(x1,x2);  *** call macro B twice;

     %B(y1,y2);  

%mend A;

%A(param=n1,param2=n2);

LinusH
Tourmaline | Level 20

You cannot call a macro using % with values from a table.

Attaching the the full code/log would make this clear.

To call a macro using values from a table, use call execute.

Data never sleeps
ballardw
Super User

Within your macro A you need to decide how to pass the values to macro B. The two most likely candicates are to create macro variables in a dataset and pass them to the macro hard coded or in a more flexible approach use Call execute.

Assuming the data set that has the data values to pass is called HAVE and the variables in HAVE with the values you want to pass are named A and b. Then the last part of your macro A might look like:

Data _null_;

     set Have;

     /* this assumes that there are only 2 records in Have. You can place an IF clause to make the call conditional such as "IF Z > 3 then " if you only wanted to call macro B when the value of hypothetical variable was  greater than 3, which is what makes this aproach very flexible.*/

     call execute ('%b(' A ||','|| B || ')' );

run;

Note that the part within the parantheses of Call Execute is just a string. The string could be created in any manner of ways. Also this uses the default formatting for A and B, which you haven't provided a default will be a Bestw.

Tom
Super User Tom
Super User

It really depends on what type code macro B is generating. If it is just part of a statement or a few statements then you can call the macro within a data step and it will generate statements that will become part of that data step.  In that case you could pass in the variable NAMES to the macro and the generated code will reference the variable names, so when that code is run as part of a data step the values of the named variables will be used.

A trivial example:


%macro sum(a,b); &a+&b %mend sum;

data x ; set y(keep=n1 n2);

   z=%sum(n1,n2);

run;

Also if the macro is only executing macro code and does not generate any SAS statements at all then you could call it from within a data step using the RESOLVE() function. In that case you would pass in the values of the dataset variables.

Example:

%macro sum(a,b); %eval(&a+&b) %mend sum;

data x ; set y(keep=n1 n2);

   z=input(resolve('%sum('||catx(','n1,n2),')'),best.);

run;

But if the macro is generating complete steps (proc or data) then you cannot call it within a data step.  You might want to push the macro call onto the stack to execute after the current step ends using CALL EXECUTE.  Or perhaps generate the call as code in an output file and then %INC the generated code.

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 7 replies
  • 6658 views
  • 0 likes
  • 5 in conversation