BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
BenConner
Pyrite | Level 9

Hi,

 

Came across something today that challenged my understanding of how I thought macro code worked vs the code the macro generates.

I've always though macro invocation completed prior to any of the code it generated getting run.  Apparently that isn't the case.

 

Here's the log from a simple test using sashelp.baseball.  Note that the 1st observation in the baseball dataset does have Cleveland as a value, so the team macro variable would be created at the end of the data step. 

I was under the impression though that the entire macro runs prior to any code it generates is run.  If that were the case, the team macro variable below would not exist prior to the %if checks after the macro was run.    What I'm seeing is the macro processor is feeding statements to the input stream of the SAS processor and running the code at each step boundary.    Am I reading this correctly?

 

Thanks!

 

--Ben

 

4715  %macro checkteam;

4716  data _null_;

4717  set sashelp.baseball;

4718  if team='Cleveland' then do;

4719    call symputx('team',team);

4720    stop;

4721    end;

4722  run;

4723

4724  %put &=team;

4725  %if &team=Oakland %then %put It was Oakdland;

4726  %if &team=Cleveland %then %put It was Cleveland;

4727  %mend;

 

4728  options mlogic symbolgen mprint;

4729

4730  %put &=team;

WARNING: Apparent symbolic reference TEAM not resolved.

team

4731  %checkteam;

MLOGIC(CHECKTEAM):  Beginning execution.

MPRINT(CHECKTEAM):   data _null_;

MPRINT(CHECKTEAM):   set sashelp.baseball;

MPRINT(CHECKTEAM):   if team='Cleveland' then do;

MPRINT(CHECKTEAM):   call symputx('team',team);

MPRINT(CHECKTEAM):   stop;

MPRINT(CHECKTEAM):   end;

MPRINT(CHECKTEAM):   run;

 

NOTE: There were 1 observations read from the data set SASHELP.BASEBALL.

NOTE: DATA statement used (Total process time):

      real time           0.00 seconds

      cpu time            0.01 seconds

 

 

MLOGIC(CHECKTEAM):  %PUT &=team

SYMBOLGEN:  Macro variable TEAM resolves to Cleveland

TEAM=Cleveland

SYMBOLGEN:  Macro variable TEAM resolves to Cleveland

MLOGIC(CHECKTEAM):  %IF condition &team=Oakland is FALSE

SYMBOLGEN:  Macro variable TEAM resolves to Cleveland

MLOGIC(CHECKTEAM):  %IF condition &team=Cleveland is TRUE

MLOGIC(CHECKTEAM):  %PUT It was Cleveland

It was Cleveland

MLOGIC(CHECKTEAM):  Ending execution.

 

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

As the macro emits SAS code the code is compiled and run the same way it would have run if that same code was hard coded into the source file. 

So when the macro finishes emitting a DATA step the data step runs.  When that step is finished the macro processor can continue emitting new code.

 

Where you might experience what you thought would happen is if you submit a macro call with CALL EXECUTE().  If you do not protect the macro call with %NRSTR() then the macro execute while CALL EXECUTE is storing the code onto the stack to run after the current data step runs.  So the data step does not actually have a chance to run (it is waiting for the step that submitted it to finish) so the macro logic executes before the data step runs.

 

To see this with your macro run these two data steps.

data _null_;
  call execute('%checkteam;');
run;
data _null_;
  call execute('%nrstr(%checkteam);');
run;

 

View solution in original post

2 REPLIES 2
Tom
Super User Tom
Super User

As the macro emits SAS code the code is compiled and run the same way it would have run if that same code was hard coded into the source file. 

So when the macro finishes emitting a DATA step the data step runs.  When that step is finished the macro processor can continue emitting new code.

 

Where you might experience what you thought would happen is if you submit a macro call with CALL EXECUTE().  If you do not protect the macro call with %NRSTR() then the macro execute while CALL EXECUTE is storing the code onto the stack to run after the current data step runs.  So the data step does not actually have a chance to run (it is waiting for the step that submitted it to finish) so the macro logic executes before the data step runs.

 

To see this with your macro run these two data steps.

data _null_;
  call execute('%checkteam;');
run;
data _null_;
  call execute('%nrstr(%checkteam);');
run;

 

BenConner
Pyrite | Level 9
Thanks, Tom. Good thing I never relied on that for code to work. Wow.

Best wishes,
Ben

SAS INNOVATE 2024

Innovate_SAS_Blue.png

Registration is open! SAS is returning to Vegas for an AI and analytics experience like no other! Whether you're an executive, manager, end user or SAS partner, SAS Innovate is designed for everyone on your team. Register for just $495 by 12/31/2023.

If you are interested in speaking, there is still time to submit a session idea. More details are posted on the website. 

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.

Get the $99 certification deal.jpg

 

 

Back in the Classroom!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 2 replies
  • 183 views
  • 0 likes
  • 2 in conversation