DATA Step, Macro, Functions and more

call a macro in another macro

Reply
Contributor
Posts: 50

call a macro in another macro

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

Super User
Posts: 11,343

Re: call a macro in another macro

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?

Super User
Posts: 19,815

Re: call a macro in another macro

Did that give you errors?

Super User
Super User
Posts: 7,050

Re: call a macro in another macro

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.

Contributor
Posts: 50

Re: call a macro in another macro

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

Super User
Posts: 5,429

Re: call a macro in another macro

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
Super User
Posts: 11,343

Re: call a macro in another macro

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.

Super User
Super User
Posts: 7,050

Re: call a macro in another macro

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.

Ask a Question
Discussion stats
  • 7 replies
  • 596 views
  • 0 likes
  • 5 in conversation