BookmarkSubscribeRSS Feed
newhand
Calcite | Level 5

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(&param);

    &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(&param);

    &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.

8 REPLIES 8
CTorres
Quartz | Level 8

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,

newhand
Calcite | Level 5

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(&param);

    &c;

%mend sub;

%macro main(exp);

    data _null_;

    var=%sub(&exp);

    put var=;

    run;

%mend main;

%main(1+2)

/****************** Third Program ******************/

Quentin
Super User

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(&param);
74     %put Inside SUB: param=&param 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.

BASUG is hosting free webinars Next up: Mike Sale presenting Data Warehousing with SAS April 10 at noon ET. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
abcd123
Fluorite | Level 6

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?

Quentin
Super User

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(&param);
110    %put Inside SUB: param=&param 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

BASUG is hosting free webinars Next up: Mike Sale presenting Data Warehousing with SAS April 10 at noon ET. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
abcd123
Fluorite | Level 6

Thank you very much. Your answer is very informative!

Tom
Super User Tom
Super User

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;

CTorres
Quartz | Level 8

Then you should eliminate the line &a; in the sub macro.

what do you need the &a variable for in this macro?

Regards,

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

Register now!

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 8 replies
  • 1226 views
  • 1 like
  • 5 in conversation