Hello,
I have following 3 programs. The 1st and 2nd program ran without error message.
/****************** First Program ******************/
%macro sub(param);
%let a=99;
&a;
%mend sub;
%macro main(exp);
data _null_;
var=%sub(&exp);
put var=;
run;
%mend main;
%main(1+2)
/****************** First Program ******************/
/****************** Second Program ******************/
%macro sub(param);
%let c = %eval(¶m);
&c;
%mend sub;
%macro main(exp);
data _null_;
var=%sub(&exp);
put var=;
run;
%mend main;
%main(1+2)
/****************** Second Program ******************/
however,when I ran third program (which is a combination of 1st and 2nd program) , I got error message:
ERROR 180-322: Statement is not valid or it is used out of proper order.
/****************** Third Program ******************/
%macro sub(param);
%let a=99;
&a;
%let c = %eval(¶m);
&c;
%mend sub;
%macro main(exp);
data _null_;
var=%sub(&exp);
put var=;
run;
%mend main;
%main(1+2)
/****************** Third Program ******************/
What mistake did I make in the 3rd program? Thank you very much for your help.
You can use the options MPRINT MLOGIC and SYMBOLGEN to debug your macros.
In program3 the main and sub macros generate the following SAS program that contains a syntax error:
data _null_;
var=99;
3;
put var=;
run;
Regards,
Thanks.
Consider the third program (as following), how should I write the program if I want to assign the value of macro variable c (which is 3) to variable var, without deleting macro variable a in macro sub(param)?
/****************** Third Program ******************/
%macro sub(param);
%let a=99;
&a;
%let c = %eval(¶m);
&c;
%mend sub;
%macro main(exp);
data _null_;
var=%sub(&exp);
put var=;
run;
%mend main;
%main(1+2)
/****************** Third Program ******************/
Hi,
Your macro %SUB still has the problem of extraneous semicolons. I'm not sure where you are headed, but here are a couple thoughts.
1. Your macro %SUB looks like a macro function, which will return a value. Macro functions should typically not generate any SAS semicolons. I'm assuming you just want to return &c (not &a and &c).
2. The macro variables you created inside the definition of %sub are local to %sub. Typically, it's good to declare the scope of macro variables, so that you ensure they are local to the macro, and avoid collisions with other scopes.
Which leads me to below revisions to your code.
70 %macro sub(param); 71 %local a c; 72 %let a=99; 73 %let c = %eval(¶m); 74 %put Inside SUB: param=¶m a=&a c=&c; 75 &c /*return this value*/ 76 %mend sub; 77 78 %macro main(exp); 79 data _null_; 80 var=%sub(&exp); 81 put var=; 82 run; 83 %mend main; 84 85 %main(1+2) Inside SUB: param=1+2 a=99 c=3 var=3
HTH,
--Q.
Thank you very much. I am trying to understand how I can transfer variables between different SAS macros. Your answer really helps me.
As you have mentioned, this example assumes only one value is returned; may I ask, what if I want to return two values (both a and c) so that variable "var" in MAIN become an array, i.e., var(1)=3, var(2)=99? is it easy to do?
Hi,
The job of the macro language is (mostly) to generate SAS code, so that you (the programmer) don't have to type it.
In the above example, there is no transfer of variables between the SAS macros.
The macro %SUB returns a text value.
When writing a macro, you need to think about what SAS code you are trying to generate. In your new example, if you would be happy to have %MAIN generate a data step like:
data _null_; array var {2} (99 3); put var1= var2=; run;
Then you could change the macro sub so that it returns: 99 3
106 %macro sub(param); 107 %local a c; 108 %let a=99; 109 %let c = %eval(¶m); 110 %put Inside SUB: param=¶m a=&a c=&c; 111 &a &c /*return this value*/ 112 %mend sub; 113 114 %macro main(exp); 115 data _null_; 116 array var {2} (%sub(&exp)); 117 put var1= var2=; 118 run; 119 %mend main; 120 121 %main(1+2) Inside SUB: param=1+2 a=99 c=3 var1=99 var2=3
Thank you very much. Your answer is very informative!
If you want to return a value from a sub macro to the calling environment you could create a global macro variable and hard code the macro to store its return value there.
But it is more flexible if you can avoid that. You could:
1) Use function style macro. Works only if macro does not generate any actual SAS code.
2) Pass the name of the variable as a parameter to the macro.
Example:
Definition: %macro sub(arg1,arg2,mvar);
.... %let &mvar = <return value> ;
Usage: %let score=0;
%sub(5,6,mvar=score);
%put score=&score;
Then you should eliminate the line &a; in the sub macro.
what do you need the &a variable for in this macro?
Regards,
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.