In the following two macro codes (Mtest1 and Mtest2), the process itself looks the same, but when I submit, the macro reference cannot be resolved in Mtest1.
%Macro Mtest1(XXX);
res=resolve('&XXX');
%Mend;
data _null_;
%Mtest1(abc);
run;
%Macro Mtest2(XXX);
data _null_;
res=resolve('&XXX');
run;
%Mend;
%Mtest2(abc);
I know how to resolve it.
All I have to do is change the single quotes to double quotes. (This may not be appropriate in this case, since it eliminates the need for the resolve function.)
Anyway. I don't understand why there is such a difference between executing a macro reference in the data step and in the open code.
Hello @japelin,
I think the MLOGIC system option helps to see what's going on: Macro parameters such as XXX are local macro variables, which exist only during macro execution. Therefore, the RESOLVE function in the DATA step can resolve '&XXX' only if it is executed during macro execution. With MLOGIC in effect, start and end of macro execution are documented in the log and we can see whether the DATA step execution occurs during macro execution. The RUN statement triggers DATA step execution. By putting the RUN statement into the macro as in your Mtest2 or in macro Mtest3 below we can ensure that the DATA step executes during macro execution. Macro Mtest4 below carries this to extremes by just providing the closing semicolon of the RUN statement.
2 options mlogic; 3 4 %Macro Mtest1(XXX); 5 res=resolve('&XXX'); 6 %Mend; 7 data _null_; 8 %Mtest1(abc); MLOGIC(MTEST1): Beginning execution. MLOGIC(MTEST1): Parameter XXX has value abc MLOGIC(MTEST1): Ending execution. 9 run; WARNING: Apparent symbolic reference XXX not resolved. NOTE: DATA statement used (Total process time): real time 0.00 seconds cpu time 0.01 seconds 10 11 %Macro Mtest2(XXX); 12 data _null_; 13 res=resolve('&XXX'); 14 run; 15 %Mend; 16 %Mtest2(abc); MLOGIC(MTEST2): Beginning execution. MLOGIC(MTEST2): Parameter XXX has value abc NOTE: DATA statement used (Total process time): real time 0.00 seconds cpu time 0.00 seconds MLOGIC(MTEST2): Ending execution. 17 18 %Macro Mtest3(XXX); 19 run; 20 %Mend; 21 22 data _null_; 23 res=resolve('&XXX'); 24 put res=; 25 %Mtest3(abc) MLOGIC(MTEST3): Beginning execution. MLOGIC(MTEST3): Parameter XXX has value abc res=abc NOTE: DATA statement used (Total process time): real time 0.00 seconds cpu time 0.00 seconds MLOGIC(MTEST3): Ending execution. 26 27 %Macro Mtest4(XXX); 28 ; 29 %Mend; 30 31 data _null_; 32 res=resolve('&XXX'); 33 put res=; 34 run MLOGIC(MTEST4): Beginning execution. 35 %Mtest4(abc) MLOGIC(MTEST4): Parameter XXX has value abc res=abc NOTE: DATA statement used (Total process time): real time 0.00 seconds cpu time 0.00 seconds MLOGIC(MTEST4): Ending execution.
Why are you using resolve? symget is the function to use if you want to resolve a macro-variable.
Do you understand now?
%Macro Mtest1(XXX);
length res $50;
res=resolve("&XXX");
put res=;
%Mend;
data _null_;
%Mtest1(abc);
run;
%Macro Mtest2(XXX);
data _null_;
length res $50;
res=resolve("&XXX");
put res=;
run;
%Mend;
%Mtest2(abc);
- Cheers -
ok so, depending of what you exactly want to do, you do not need to resolve if you want to append the values;
%let test=abc;
data _NULL_;
a='jfk';
b=cats(a,"&test.");
put b=;
run;
Besides that, you need to understand when a macro variable resolves and when not. Use the MLOGIC, MPRINT and SYMBOLGEN options to trace how SAS proceeds:
OPTIONS MLOGIC MPRINT SYMBOLGEN;
%Macro Mtest1(XXX);
res=resolve('&XXX');
%Mend;
data _null_;
%Mtest1(abc);
put res=;
run;
%SYMDEL XXX;
%Macro Mtest2(XXX);
data _null_;
res=resolve('&XXX');
put res=;
run;
%Mend;
%Mtest2(abc);
OPTIONS NOMLOGIC NOMPRINT NOSYMBOLGEN;
The macro functionality is processed first, that means that your first step is identical with:
data _null_;
res=resolve('&XXX');
put res=;
run;
Since XXX is not defined in your environment SAS yells a warning.
In your second step, the XXX already exist before it is processed by the datastep and therefore runs perfectly.
For advance data driven processing, check this blog
You may be especially interested in the combination of use of CALL EXECUTE and macro call.
- Cheers -
Hello @japelin,
I think the MLOGIC system option helps to see what's going on: Macro parameters such as XXX are local macro variables, which exist only during macro execution. Therefore, the RESOLVE function in the DATA step can resolve '&XXX' only if it is executed during macro execution. With MLOGIC in effect, start and end of macro execution are documented in the log and we can see whether the DATA step execution occurs during macro execution. The RUN statement triggers DATA step execution. By putting the RUN statement into the macro as in your Mtest2 or in macro Mtest3 below we can ensure that the DATA step executes during macro execution. Macro Mtest4 below carries this to extremes by just providing the closing semicolon of the RUN statement.
2 options mlogic; 3 4 %Macro Mtest1(XXX); 5 res=resolve('&XXX'); 6 %Mend; 7 data _null_; 8 %Mtest1(abc); MLOGIC(MTEST1): Beginning execution. MLOGIC(MTEST1): Parameter XXX has value abc MLOGIC(MTEST1): Ending execution. 9 run; WARNING: Apparent symbolic reference XXX not resolved. NOTE: DATA statement used (Total process time): real time 0.00 seconds cpu time 0.01 seconds 10 11 %Macro Mtest2(XXX); 12 data _null_; 13 res=resolve('&XXX'); 14 run; 15 %Mend; 16 %Mtest2(abc); MLOGIC(MTEST2): Beginning execution. MLOGIC(MTEST2): Parameter XXX has value abc NOTE: DATA statement used (Total process time): real time 0.00 seconds cpu time 0.00 seconds MLOGIC(MTEST2): Ending execution. 17 18 %Macro Mtest3(XXX); 19 run; 20 %Mend; 21 22 data _null_; 23 res=resolve('&XXX'); 24 put res=; 25 %Mtest3(abc) MLOGIC(MTEST3): Beginning execution. MLOGIC(MTEST3): Parameter XXX has value abc res=abc NOTE: DATA statement used (Total process time): real time 0.00 seconds cpu time 0.00 seconds MLOGIC(MTEST3): Ending execution. 26 27 %Macro Mtest4(XXX); 28 ; 29 %Mend; 30 31 data _null_; 32 res=resolve('&XXX'); 33 put res=; 34 run MLOGIC(MTEST4): Beginning execution. 35 %Mtest4(abc) MLOGIC(MTEST4): Parameter XXX has value abc res=abc NOTE: DATA statement used (Total process time): real time 0.00 seconds cpu time 0.00 seconds MLOGIC(MTEST4): Ending execution.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.