Post by David L CassellPost by J S HuangI have a question on how to distinguish between SAS statement and macro
language element. Specifically I want to know when CALL EXECUTE is
executed at the next DATA step boundary and when it is executely
"resolves its argument and executes the resolved value at the next step
boundary (if the value is a SAS statement) or immediately (if the value is
a macro language element)."
I have my doubts about this explanation. I don't see the distinction
between resolving the argument and immediately executing the resolved value
if it is a macro language element. Where does the former end and the latter
begin? Also, the resolved value may not be a SAS statement. It could be a
fragment of a statement. It could be gibberish (in which case it will raise
an error, but that's not CALL EXECUTE's issue).
I would say something like "resolves its argument and queues any generated
text at the next step boundary, following any text similarly generated
earlier in the current step."
Try
data _null_;
call execute('proc');
call execute('options');
call execute(';run;');
run;
Post by David L CassellFirst, I have to admit that SAS docs read as if they were written for
people
Post by David L Cassellwho
already know the material. That does take some work.
But the meaning is actually straightforward. Work out what the thing
inside
Post by David L Cassellthe CALL EXECUTE() parentheses is, by doing any macro variable parsing or
text substitution needed, along with filling in anything from the data set.
Now
look at it.
Is it a regular SAS statement or a series of them, like a proc step or a
new
Post by David L Casselldata
step? If so, then slap it on a queue, and execute all those things once
you
Post by David L Cassellhave
passed the step boundary (like that RUN statement at the end of your DATA
step).
Is it a macro call, or some macro code? Then it gets executed immediately,
without waiting for the next step boundary.
Which may be just what you DON'T want to happen. Lots of times we want
the series of macro calls to execute right *after* the step, so you can put
the
macro call inside single quotes to get that effect.
I don't agree. In the absence of single quotes (or some thing else to hide
the macro call from the compiler), the macro code will be processed at
compile time. Try
%macro helloworld;
%put Hello World -- &more;
%mend;
%let more=Compile time;
data _null_;
call symput('more','Before CALL EXECUTE at runtime');
call execute("%helloworld");
call symput('more','After CALL EXECUTE at runtime');
run;
You get
5 %let more=Compile time;
6 data _null_;
7 call symput('more','Before CALL EXECUTE at runtime');
8 call execute("%helloworld");
Hello World -- Compile time
9 call symput('more','After CALL EXECUTE at runtime');
10 run;
NOTE: DATA statement used (Total process time):
NOTE: CALL EXECUTE routine executed successfully, but no SAS statements
were generated.
Incidentally, those double quotes really don't have to contain the macro
call. Their role is to give CALL EXECUTE an argument after the macro
processor eats everything else between the parentheses. Without them,
something bad happens:
12 %let more=Compile time;
13 data _null_;
14 call symput('more','Before CALL EXECUTE at runtime');
15 call execute(%helloworld);
Hello World -- Compile time
15 call execute(%helloworld);
-------
252
ERROR 252-185: The EXECUTE subroutine call does not have enough arguments.
16 call symput('more','After CALL EXECUTE at runtime');
17 run;
NOTE: The SAS System stopped processing this step because of errors.
It's equally satisfactory to put the quotes before or after the macro
invocation, as in:
19 %let more=Compile time;
20 data _null_;
21 call symput('more','Before CALL EXECUTE at runtime');
22 call execute(""%helloworld);
Hello World -- Compile time
23 call symput('more','After CALL EXECUTE at runtime');
24 run;
NOTE: DATA statement used (Total process time):
NOTE: CALL EXECUTE routine executed successfully, but no SAS statements
were generated.
Now let's get back to single quotes, as in:
%let more=Compile time;
data _null_;
call symput('more','Before CALL EXECUTE at runtime');
call execute('%helloworld');
call symput('more','After CALL EXECUTE at runtime');
run;
The quotes hide the macro code at compile time. At execution time, the
literal inside the quotes (or, more generally, the result of evaluating the
expression inside the parentheses) is passed to the EXECUTE routine and
processed. Since there is a macro invocation, it is resolved at that time.
Evidence:
26 %let more=Compile time;
27 data _null_;
28 call symput('more','Before CALL EXECUTE at runtime');
29 call execute('%helloworld');
30 call symput('more','After CALL EXECUTE at runtime');
31 run;
Hello World -- Before CALL EXECUTE at runtime
NOTE: DATA statement used (Total process time):
NOTE: CALL EXECUTE routine executed successfully, but no SAS statements
were generated.
Offhand, I don't know how to generate a macro call via CALL EXECUTE yet
defer its processing until after a step boundary. If it's possible, it
involves some more exotic type of quoting. If such a technique is exercised
against my example, the "Hello World" line would appear *after* the end-of-
step NOTEs and would be followed by the words "After CALL EXECUTE at
runtime".
Post by David L CassellThere's a section on
these
sorts of timing issues in Art Carpenter's macro book, and I highly
recommend
Post by David L Cassellthat you take a look there for more detail and some examples.
HTH,
David
--
David L. Cassell
mathematical statistician
Design Pathways
3115 NW Norwood Pl.
Corvallis OR 97330
_________________________________________________________________
Dont just search. Find. Check out the new MSN Search!
http://search.msn.click-url.com/go/onm00200636ave/direct/01/