BookmarkSubscribeRSS Feed
braam
Quartz | Level 8

I use nested macro, upper-level and lower-level ones. As seen below (I modified the code a bit to display here), my lower-level macro take &xtr_var for its arguments, so I use %nrstr in the argument for %upper. But the issue I face now is that SAS can't resolve lower-level macro's arguments, i.e., listname and new. Could anybody help me to solve this issue?

 

 

%upper (statement= %nrstr(	
		%lower(listname=set_list, new= &xth_var);%put &set_list;
....
)
WARNING: Apparent symbolic reference LISTNAME not resolved.
&listname
WARNING: Apparent symbolic reference NEW not resolved.
&new

 

4 REPLIES 4
PaigeMiller
Diamond | Level 26

Show us a larger part of the code, including the definitions of the macros. Run the command

 

options mprint mlogic symbolgen;

and then show us the entire log (not just the errors and warnings).


Also the part you show has imbalanced parentheses.


Why use %NRSTR() here anyway? Why not call %LOWER inside %UPPER instead of using %NRSTR() to include %LOWER as an argument?

--
Paige Miller
braam
Quartz | Level 8

Thanks. The below is my code.

 

%macro loop3 (list1=, statement=);
	%if &list1=  %then %let N1= 1;	%else 
		%do; 	%let N1= %sysfunc(countw(&list1));	%end;
	%do x= 1 %to &N1;
		%let xth_var= %scan(&list1, &x);
		%unquote(&STATEMENT);
	%end;
%mend;

%macro let_cumulative (listname, new, RepeatedNo);
	%if &RepeatedNo= 1 %then 
		%do; %global &listname; %end; 
	%else			
		%do; %let &listname= &&&listname &new; %end;
/*	%put "list after=" &listname;*/
%mend;
		
option mlogic mprint symbolgen;
%symdel set_list;
%loop3 (list1= 1 2 3, statement= %nrstr(	
	%let_cumulative (listname=set_list, new= &xth_var,RepeatedNo=&x);%put &set_list;
	%put &listname;
	%put &new;
	%put &RepatedNo;
/*		%let addset= rcult.r_comp_&xth_var.;*/
/*		%let set_list= &set_list &addset;*/
	));
%put &set_list;

The below is printed in the log window.

6823
6824  %macro loop3 (list1=, statement=);
6825      %if &list1=  %then %let N1= 1;  %else
6826          %do;    %let N1= %sysfunc(countw(&list1));  %end;
6827      %do x= 1 %to &N1;
6828          %let xth_var= %scan(&list1, &x);
6829          %unquote(&STATEMENT);
6830      %end;
6831  %mend;
6832
6833  %macro let_cumulative (listname, new, RepeatedNo);
6834      %if &RepeatedNo= 1 %then
6835          %do; %global &listname; %end;
6836      %else
6837          %do; %let &listname= &&&listname &new; %end;
6838  /*  %put "list after=" &listname;*/
6839  %mend;
6840
6841  option mlogic mprint symbolgen;
6842  %symdel set_list;
6843  %loop3 (list1= 1 2, statement= %nrstr(
MLOGIC(LOOP3):  Beginning execution.
6844      %let_cumulative (listname=set_list, new= &xth_var,RepeatedNo=&x);%put &set_list;
6845      %put &listname;
6846      %put &new;
6847      %put &RepatedNo;
6848  /*      %let addset= rcult.r_comp_&xth_var.;*/
6849  /*      %let set_list= &set_list &addset;*/
6850      ));
MLOGIC(LOOP3):  Parameter LIST1 has value 1 2
MLOGIC(LOOP3):  Parameter STATEMENT has value      let_cumulative (listnameset_list new
      xth_varRepeatedNox)put set_list     put listname     put new     put RepatedNo
            
SYMBOLGEN:  Macro variable LIST1 resolves to 1 2
MLOGIC(LOOP3):  %IF condition &list1= is FALSE
MLOGIC(LOOP3):  %LET (variable name is N1)
SYMBOLGEN:  Macro variable LIST1 resolves to 1 2
SYMBOLGEN:  Macro variable N1 resolves to 2
MLOGIC(LOOP3):  %DO loop beginning; index variable X; start value is 1; stop value is 2; by value is
      1.
MLOGIC(LOOP3):  %LET (variable name is XTH_VAR)
SYMBOLGEN:  Macro variable LIST1 resolves to 1 2
SYMBOLGEN:  Macro variable X resolves to 1
SYMBOLGEN:  Macro variable STATEMENT resolves to      %let_cumulative (listname=set_list, new=
            &xth_var,RepeatedNo=&x);%put &set_list;     %put &listname;     %put &new;     %put
            &RepatedNo;
SYMBOLGEN:  Some characters in the above value which were subject to macro quoting have been unquoted
            for printing.
MLOGIC(LET_CUMULATIVE):  Beginning execution.
SYMBOLGEN:  Macro variable XTH_VAR resolves to 1
SYMBOLGEN:  Macro variable X resolves to 1
MLOGIC(LET_CUMULATIVE):  Parameter LISTNAME has value set_list
MLOGIC(LET_CUMULATIVE):  Parameter NEW has value 1
MLOGIC(LET_CUMULATIVE):  Parameter REPEATEDNO has value 1
SYMBOLGEN:  Macro variable REPEATEDNO resolves to 1
MLOGIC(LET_CUMULATIVE):  %IF condition &RepeatedNo= 1 is TRUE
MLOGIC(LET_CUMULATIVE):  %GLOBAL  &LISTNAME
SYMBOLGEN:  Macro variable LISTNAME resolves to set_list
MLOGIC(LET_CUMULATIVE):  Ending execution.
MPRINT(LOOP3):  ;
SYMBOLGEN:  Macro variable SET_LIST resolves to

WARNING: Apparent symbolic reference LISTNAME not resolved.
&listname
WARNING: Apparent symbolic reference NEW not resolved.
&new
WARNING: Apparent symbolic reference REPATEDNO not resolved.
&RepatedNo
MPRINT(LOOP3):   ;
MLOGIC(LOOP3):  %DO loop index variable X is now 2; loop will iterate again.
MLOGIC(LOOP3):  %LET (variable name is XTH_VAR)
SYMBOLGEN:  Macro variable LIST1 resolves to 1 2
SYMBOLGEN:  Macro variable X resolves to 2
SYMBOLGEN:  Macro variable STATEMENT resolves to      %let_cumulative (listname=set_list, new=
            &xth_var,RepeatedNo=&x);%put &set_list;     %put &listname;     %put &new;     %put
            &RepatedNo;
SYMBOLGEN:  Some characters in the above value which were subject to macro quoting have been unquoted
            for printing.
MLOGIC(LET_CUMULATIVE):  Beginning execution.
SYMBOLGEN:  Macro variable XTH_VAR resolves to 2
SYMBOLGEN:  Macro variable X resolves to 2
MLOGIC(LET_CUMULATIVE):  Parameter LISTNAME has value set_list
MLOGIC(LET_CUMULATIVE):  Parameter NEW has value 2
MLOGIC(LET_CUMULATIVE):  Parameter REPEATEDNO has value 2
SYMBOLGEN:  Macro variable REPEATEDNO resolves to 2
MLOGIC(LET_CUMULATIVE):  %IF condition &RepeatedNo= 1 is FALSE
SYMBOLGEN:  Macro variable LISTNAME resolves to set_list
MLOGIC(LET_CUMULATIVE):  %LET (variable name is set_list)
SYMBOLGEN:  && resolves to &.
SYMBOLGEN:  Macro variable LISTNAME resolves to set_list
SYMBOLGEN:  Macro variable SET_LIST resolves to
SYMBOLGEN:  Macro variable NEW resolves to 2
MLOGIC(LET_CUMULATIVE):  Ending execution.
MPRINT(LOOP3):  ;
SYMBOLGEN:  Macro variable SET_LIST resolves to 2
2
WARNING: Apparent symbolic reference LISTNAME not resolved.
&listname
WARNING: Apparent symbolic reference NEW not resolved.
&new
WARNING: Apparent symbolic reference REPATEDNO not resolved.
&RepatedNo
MPRINT(LOOP3):   ;
MLOGIC(LOOP3):  %DO loop index variable X is now 3; loop will not iterate again.
MLOGIC(LOOP3):  Ending execution.
6851  %put &set_list;
SYMBOLGEN:  Macro variable SET_LIST resolves to 2
2

 

 

PaigeMiller
Diamond | Level 26

SYMBOLGEN: Macro variable SET_LIST resolves to

SET_LIST resolves to

 

and then nothing is shown. You have not provided a value for SET_LIST, so nothing after that will work.

 

I still suspect you have overcomplicated the whole thing, and maybe something like this would be easier to code and debug and understand. I show the outline of the code only (and I have no idea what this code is supposed to do anyway):

 

%macro loop3(list1=,statement=,new=,repeatedno=);
%if &list1=  %then %let N1= 1;	
%else %do; 	
    %let N1= %sysfunc(countw(&list1));	
%end;
%do x= 1 %to &N1;
    %let xth_var= %scan(&list1, &x);
    %let_cumulative(listname=set_list,new=x&th_var,repeatedno=&x)
...
%mend;
%macro let_cumulative(listname=,new=,repeatedno=);
...
%mend;
    

As I said, I think it could be simplified even further, but I don't know what you are trying to do.

 

Lastly, I absolutely hate the idea of a macro whose name begins with %LET such as %LET_CUMULATIVE, because %LET is a command with a specific meaning is the macro processor.

--
Paige Miller
Tom
Super User Tom
Super User

What the heck are you actually trying to do?

 

Anyway the "statements" you are passing to LOOP3 three don't make much sense. You are trying to reference the parameters (like LISTNAME) to the %LET_CUMULATIVE() macro outside of that macro's scope.  Those are LOCAL macro variables to that macro and disappear when the macro is finished running.

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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
  • 4 replies
  • 547 views
  • 0 likes
  • 3 in conversation