Search code examples
sassas-macrodatastep

Macro execution inside data step


I have the following macro which I will use inside a data step:

%global var3;

%macro add(var1,var2);
    %let var3 = %eval(&var1+&var2);
%mend;

I don't understand the results of the following data step:

%let var3 = 2;

data test;
    put "The value of var3 is &var3";
    x = 3 - &var3;
    %add(7,3);
    %put &=var3;
run;

From what I understand, macro statements are executed before compilation of a data step. So in this case macro %add is executed first and then %put statement. However, the value of x is 1, not -7. And also put statement prints The value of var3 is 2, instead of 10. I am confused.


Solution

  • Let's look at what happens.

     69         %global var3;
     70         
     71         %macro add(var1,var2);
     72             %let var3 = %eval(&var1+&var2);
     73         %mend;
     74         
     75         %let var3 = 2;
     76         options symbolgen mprint;
     77         data test;
     SYMBOLGEN:  Macro variable VAR3 resolves to 2
     78             put "The value of var3 is &var3";
     79             x = 3 - &var3;
     SYMBOLGEN:  Macro variable VAR3 resolves to 2
     80             %add(7,3);
     SYMBOLGEN:  Macro variable VAR1 resolves to 7
     SYMBOLGEN:  Macro variable VAR2 resolves to 3
     81             %put &=var3;
     SYMBOLGEN:  Macro variable VAR3 resolves to 10
     VAR3=10
     82         run;
     
     The value of var3 is 2
    

    So, SAS goes to run the macro pass, as you say before data step compilation, and turns the code into this...

    data test;
      put "The value of var3 is 2";
      x = 3 - 2;
      %let var3 = %eval(7+3);
      %put 10;
    run;
    

    You're right that SAS does handle the macro language before compilation, but that doesn't mean it happens before SAS begins to prepare the data step for compilation. The macro language pass creates the final data step, but it still happens sequentially - so SAS looks at line 77, sees no macro variables, finalizes it; it looks at line 78, sees &var3, turns it into 2, finalizes that line; looks at line 79, etc.