Hello everybody, I use call execute to run a macro. Inside this I create a macro-variable(let's call it Max_year) that I then use in a later data step (still within the macro). Now, I get a warning because &Max_year don't resolve. But when I look at the table that is created by the macro it has de facto worked (output is conditional on &Max_year resolvning). Now I'm a bit perplexed to why this happens, I guess it's because I don't understand some part of the process (the nature of call execute perhaps?). Anybody got a clue? If it helps I create a dataset coulmn were every row has the value of &Max_year so the only part within the macro that I use &Max_year is in the beginning of a data step.
Regards,
Luonas
Hi!
When you use call execute inside a data step to generate a macro call, the macro will actually execute directly, before the data step finishes. I the macro generates sas code, this code will be sent to the input stack, but macro statements will execute immediately. Sas will also try to resolve macro variable references directly. Here is one example:
%symdel myvar;
%macro test;
/*Data step A*/
data _null_;
call symputx('myvar','Hello');
run;
/*Data step B*/
data table;
txt="&myvar";
run;
%mend;
/*Data step C*/
data _null_;
call execute('%test');
run;
When data step C executes, the macro will generate data step A and B, but the macro variable Myvar doesen't exist yet. We will get a warning in the log because the reference cannot resolve. Then datastep C is finished, and datastep A will execute, creating macro variable myvar. Then data step B will execute, and the reference to myvar will work fine.
Use nrstr to delay the execution of the macro
call execute('%nrstr(%test)');
To give you an answer without seeing the code or the log would be pure guesswork.
Yeah, sorry about that. Needed to edit the code first so that it was english only:
%Macro Load_table(ds,ar1,ar5,ar15);
Data data_&ds;
set sashelp.vmember(keep = memname libname
where=( libname='DUMMY' AND
Substr(Memname,1,length("&ds"))=upcase("&ds") AND
((Length(Memname) = length("&ds")+2 AND Length(Memname)>3) OR
(Substr(Memname,1,length("&ds"))='P' AND (Length(Memname) = length("&ds")+4))) AND
notdigit(substr(memname,length(memname)-1,2))=0));
Year = Substr(memname, length(memname)-1,2);
If Year <= '69' Then
year_num = Input(Compress("20"||Year),best4.);
If Year >='70' Then
year_num = Input(Compress("19"||Year),best4.);
Year_d1 = &ar1;
Year_d5 = &ar5;
Year_d15 = &ar15;
Drop libname;
run;
%If &ds^=p %Then
%Do;
Proc sql;
select max(year_num) into: Max_&ds
from data_&ds
;quit;
Data data1_&ds(keep= Memname year_num Max_ds Flag
where=( year_num = Max_ds OR
Flag=1));
set data_&ds;
Max_ds = &&Max_&ds; /*####### THIS part works but still get a resolve-error###########*/
Output;
If Year_d1 ^=. then do;
Do i=1 to &ar1;
If year_num = Max_ds-i then flag=1;
Else Flag = 0;
Output;
End;
End;
If Year_d5 ^=. then do;
Do i=1 to &ar5;
j=5*i;
If Substr(year,2,1) in('0','5') and year_num>= 2011-j then flag=1;
Else Flag = 0;
Output;
End;
End;
If Year_d15 ^=. then do;
Do i=1 to &ar15;
j=15*i;
If year_num = Max_ds-j-1 then flag=1;
Else Flag = 0;
Output;
End;
End;
If _N_ = 1 then do;
Call symputx('Max_master',Max_ds);
End;
run;
Proc sort data=data1_&ds(keep=Memname year_num) nodupkey;
by Memname year_num;
run;
Data _null_;
set data1_&ds;
ds="&ds";
Call Execute('%Merge('||Memname||','||Year_num||','||ds||')');
run;
%End;
%Mend %Load_table;
Data _null_;
set ani.infile_atabs(where= (id="&atab"));
If T2='' then do;
Call Execute('%Load_table('||T1||','||AR1||','||AR5||','||AR15||')');
End;
Run;
The last macro merge isn't included but the things that happen there have no influnce on the result.
I have marked the "false" error with: /*####### THIS part works but still get a resolve-error###########*/
Hi!
When you use call execute inside a data step to generate a macro call, the macro will actually execute directly, before the data step finishes. I the macro generates sas code, this code will be sent to the input stack, but macro statements will execute immediately. Sas will also try to resolve macro variable references directly. Here is one example:
%symdel myvar;
%macro test;
/*Data step A*/
data _null_;
call symputx('myvar','Hello');
run;
/*Data step B*/
data table;
txt="&myvar";
run;
%mend;
/*Data step C*/
data _null_;
call execute('%test');
run;
When data step C executes, the macro will generate data step A and B, but the macro variable Myvar doesen't exist yet. We will get a warning in the log because the reference cannot resolve. Then datastep C is finished, and datastep A will execute, creating macro variable myvar. Then data step B will execute, and the reference to myvar will work fine.
Use nrstr to delay the execution of the macro
call execute('%nrstr(%test)');
Thanks a lot - it was something along your answer I was hoping for
//Luonas
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.