BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Luonas
Calcite | Level 5

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

1 ACCEPTED SOLUTION

Accepted Solutions
Fraktalnisse
SAS Employee

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)');

View solution in original post

4 REPLIES 4
Patrick
Opal | Level 21

To give you an answer without seeing the code or the log would be pure guesswork.

Luonas
Calcite | Level 5

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###########*/

Fraktalnisse
SAS Employee

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)');

Luonas
Calcite | Level 5

Thanks a lot - it was something along your answer I was hoping for Smiley Happy

//Luonas

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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
  • 5370 views
  • 3 likes
  • 3 in conversation