Discussion:
Call Execute
(too old to reply)
J S Huang
2005-12-17 03:35:40 UTC
Permalink
Hi!

I 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
immediately as described in help window:

"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)."

Thanks in advance.

J S Huang
David L Cassell
2005-12-17 03:55:24 UTC
Permalink
Post by J S Huang
I 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)."
First, I have to admit that SAS docs read as if they were written for people
who
already know the material. That does take some work.

But the meaning is actually straightforward. Work out what the thing inside
the 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
data
step? If so, then slap it on a queue, and execute all those things once you
have
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. There's a section on
these
sorts of timing issues in Art Carpenter's macro book, and I highly recommend
that 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

_________________________________________________________________
Don’t just search. Find. Check out the new MSN Search!
http://search.msn.click-url.com/go/onm00200636ave/direct/01/
David L Cassell
2005-12-19 05:42:37 UTC
Permalink
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;
Well, I have noticed that you can convey more information than the SAS docs.
Lay on, MacDuff!
Post by David L Cassell
But the meaning is actually straightforward. Work out what the thing
inside
Post by David L Cassell
the CALL EXECUTE() parentheses is, by doing any macro variable parsing or
text substitution needed, along with filling in anything from the data
set. Now
Post by David L Cassell
look at it.
Is it a regular SAS statement or a series of them, like a proc step or a
new data
Post by David L Cassell
step? If so, then slap it on a queue, and execute all those things once
you have
Post by David L Cassell
passed the step boundary (like that RUN statement at the end of your DATA
step).
Post by David L Cassell
Is it a macro call, or some macro code? Then it gets executed
immediately,
Post by David L Cassell
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
Post by David L Cassell
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: 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,
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
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: CALL EXECUTE routine executed successfully, but no SAS statements
were generated.
%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.
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: 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".
But it is still possible to feed SAS some text which causes any code to be
put
on some manner of queue, so that the execution is performed after the data
step. I don't know exactly what SAS evaluates to make the decision, but
apparently if it ends up with something which looks like additional steps of
code, it queues them up. (As you already know.)


data t17 t24 t38;
do x = 1 to 3;
t = 17*x; output t17;
t = 24*x; output t24;
t = 38*x; output t38;
end;
run;

%macro dreck(num=1);
proc print data=t&NUM noobs; run;
%mend;

options mprint;

data schmutz;
do record = 17, 24, 38; output; end;
run;

data trafe;
set schmutz;
call execute('%DRECK(num=' || record || ')' );
run;


Now the CALL EXECUTE function stacks up the resulting procs, and runs
each of them in turn, after the data step completes:


34 data trafe;
35 set schmutz;
36 call execute('%DRECK(num=' || record || ')' );
37 run;

NOTE: Numeric values have been converted to character values at the places
given by:
(Line):(Column).
36:33
MPRINT(DRECK): proc print data=t17 noobs;
MPRINT(DRECK): run;
MPRINT(DRECK): proc print data=t24 noobs;
MPRINT(DRECK): run;
MPRINT(DRECK): proc print data=t38 noobs;
MPRINT(DRECK): run;
NOTE: There were 3 observations read from the data set WORK.SCHMUTZ.
NOTE: The data set WORK.TRAFE has 3 observations and 1 variables.
NOTE: DATA statement used:
real time 0.04 seconds
cpu time 0.03 seconds

NOTE: CALL EXECUTE generated line.
1 + proc print data=t17 noobs; run;

NOTE: There were 3 observations read from the data set WORK.T17.
NOTE: PROCEDURE PRINT used:
real time 0.07 seconds
cpu time 0.00 seconds

2 + proc print data=t24 noobs; run;

NOTE: There were 3 observations read from the data set WORK.T24.
NOTE: PROCEDURE PRINT used:
real time 0.09 seconds
cpu time 0.00 seconds

3 + proc print data=t38 noobs; run;

NOTE: There were 3 observations read from the data set WORK.T38.
NOTE: PROCEDURE PRINT used:
real time 0.04 seconds
cpu time 0.00 seconds


So SAS is acting in some way as if the intent of the documentation is
actually
taking place. It 'recognizes' in some way, after resolving the macro, that
it
has SAS code rather than just macro components, and queues those chunks
up for processing after the data step completes.

Have I completely missed your point?

David
--
David L. Cassell
mathematical statistician
Design Pathways
3115 NW Norwood Pl.
Corvallis OR 97330

_________________________________________________________________
Express yourself instantly with MSN Messenger! Download today - it's FREE!
http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/
toby dunn
2005-12-19 19:53:26 UTC
Permalink
jiann,

Short answer to your post is no no no....


call execute( '%helloworld' ) ;

Gets executed at data step execute time because the single quotes hide the %
sign. Thus it gets executed executed and resolved at data step execute
time.

call execute( %nrstr('%helloworlde') ) ;

looks great in concept except for the fact that %nrstr works at macro
execute and compile time not data step hence it will do nothing here.


Call execute( '%nrstr(%helloworld)' ) ;

Hides the % sign's and also places the %nrstr in the right spot since it
will work after the code has been passed off to the macro processor to be
resolved and executed. So the single quotes says dont resolve at macro
compile and execution time but at data step execution time. So then at data
step execution time it hits this line and passes it off to the macro
processor and it hits the %nrstr which effectively shuts it down from
resolving it any further, and it gets passed to the stack where it will get
resolved after the and executed after the data step finishes.

call execute( "%helloworld" ) ;



Toby Dunn





From: Jiann-Shiun Huang <Jiann-***@AMERUS.COM>
Reply-To: Jiann-Shiun Huang <Jiann-***@AMERUS.COM>
To: SAS-***@LISTSERV.UGA.EDU
Subject: Re: Call Execute
Date: Mon, 19 Dec 2005 12:03:08 -0600

Howard:

From the responses that you and Fred made, I made some test runs and
draw the following conclusion:
(1) if
call execute(%nrstr('%helloworld'));
is replaced by
call execute('%helloworld');
there will be no difference in result. The reason, I believe, is
string inside single quote will not be resolved by either macro or macro
variable. Hence %nrstr has no effect on the string %helloworld.

(2) if
call execute(%nrstr('%helloworld'));
is replaced by
call execute("%helloworld');
then the execution will be at compile time, and the log shows the
following:

21 %macro helloworld;
22 %put Hello World -- &more;
23 %mend helloworld;
24
25 %let more=Compile time;
26 data _null_;
27 call symput('more','Before CALL EXECUTE at runtime');
28 call execute("%helloworld");
Hello World -- Compile time
29 call symput('more','After CALL EXECUTE at runtime');
30 run;

My conclusion about call execute is this:
(1) if double quote is used in the parenthesis of execute it is
executed by macro processor when word scanner detects it.
(2) if single quote is used, then the call execute statement will be
placed in Data Step compiler till the end of the Data step. At that
time macro is called to execute in the sequence it appears in Data
step.




NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds





J S Huang
1-515-557-3987
fax 1-515-557-2422
12/19/2005 11:20:04 AM >>>
On Mon, 19 Dec 2005 10:09:19 -0500, Fehd, Ronald J <***@CDC.GOV>
wrote:

[snip]
'macro language element'
is anything with percent sign in front of it.
if that is a macro call: %DoThis
then you do -not- want that to 'happen' immediately
but to be happen after the next step boundary.
call execute(%nrstr('%DoThis(parm=X)'));
But when I submit

%macro helloworld;
%put Hello World -- &more;
%mend;

%let more=Compile time;
data _null_;
call symput('more','Before CALL EXECUTE at runtime');
call execute(%nrstr('%helloworld') );
call symput('more','After CALL EXECUTE at runtime');
run;

I get

32 %let more=Compile time;
33 data _null_;
34 call symput('more','Before CALL EXECUTE at runtime');
35 call execute(%nrstr('%helloworld') );
36 call symput('more','After CALL EXECUTE at runtime');
37 run;

Hello World -- Before CALL EXECUTE at runtime
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.01 seconds

I want/expect the "Hello World" to appear after the end-of-step NOTEs
and
to include the word "After" from the last CALL SYMPUT.
we have had long threads on this quirk in the past
my keywords/phrase: macro with complexity
http://www.listserv.uga.edu/archives/sas-l.html
search for: macro with complexity
since: Dec 2002
the Dec 11 2002 post addresses how to debug programs that use call
execute
Ron Fehd the macro maven CDC Atlanta GA USA RJF2 ata cdc d0t g0v
Fehd, Ronald J
2005-12-19 19:51:05 UTC
Permalink
add complexity: %If or %do or call symput within HelloWorld

it will not work correctly without being called w/%nrstr
because the -macro- code is expanded
before push onto the SAS tokenizer stack
and you want it expanded -after- pop from the stack
Ron
-----Original Message-----
From: Howard Schreier <hs AT dc-sug DOT org>
Sent: Monday, December 19, 2005 12:20 PM
Subject: Re: Call Execute
On Mon, 19 Dec 2005 10:09:19 -0500, Fehd, Ronald J
[snip]
'macro language element'
is anything with percent sign in front of it.
if that is a macro call: %DoThis
then you do -not- want that to 'happen' immediately
but to be happen after the next step boundary.
call execute(%nrstr('%DoThis(parm=X)'));
But when I submit
%macro helloworld;
%put Hello World -- &more;
%mend;
%let more=Compile time;
data _null_;
call symput('more','Before CALL EXECUTE at runtime');
call execute(%nrstr('%helloworld') );
call symput('more','After CALL EXECUTE at runtime');
run;
I get
32 %let more=Compile time;
33 data _null_;
34 call symput('more','Before CALL EXECUTE at runtime');
35 call execute(%nrstr('%helloworld') );
36 call symput('more','After CALL EXECUTE at runtime');
37 run;
Hello World -- Before CALL EXECUTE at runtime
real time 0.00 seconds
cpu time 0.01 seconds
I want/expect the "Hello World" to appear after the
end-of-step NOTEs and
to include the word "After" from the last CALL SYMPUT.
we have had long threads on this quirk in the past
my keywords/phrase: macro with complexity
http://www.listserv.uga.edu/archives/sas-l.html
search for: macro with complexity
since: Dec 2002
the Dec 11 2002 post addresses how to debug programs that use call
execute
Ron Fehd the macro maven CDC Atlanta GA USA RJF2 ata cdc d0t g0v
Howard Schreier <hs AT dc-sug DOT org>
2005-12-17 21:32:30 UTC
Permalink
Post by David L Cassell
Post by J S Huang
I 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 Cassell
First, I have to admit that SAS docs read as if they were written for
people
Post by David L Cassell
who
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 Cassell
the 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 Cassell
data
step? If so, then slap it on a queue, and execute all those things once
you
Post by David L Cassell
have
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 Cassell
There's a section on
these
sorts of timing issues in Art Carpenter's macro book, and I highly
recommend
Post by David L Cassell
that 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
_________________________________________________________________
Don’t just search. Find. Check out the new MSN Search!
http://search.msn.click-url.com/go/onm00200636ave/direct/01/
Howard Schreier <hs AT dc-sug DOT org>
2005-12-18 03:18:58 UTC
Permalink
On Sat, 17 Dec 2005 17:20:04 -0600, Jiann-Shiun Huang <Jiann-
Thank you for your response. I tried your code and I have some
We are discussing the situation where the "parameter" is a macro invocation.
(1) If parameter of Call Execute is enclosed in double quotes, then it
is executed at compile time as you mentioned and it is only executed
once even if there is a multiple iteration in DATA step.
Yes. Actually it does not make sense to do this. If you want such behavior,
just place the macro call before the DATA step. I only placed it in the
position of a CALL EXECUTE argument to draw contrast and to demonstrate the
need for single quotes.
(2) If parameter of Call Execute is enclosed in single quotes, then it
is executed at DATA step boundary.
No. During DATA step execution the CALL EXECUTE argument is evaluated as a
SAS expression (of which a simple character constant is a special case) and
the result passed to the CALL EXECUTE routine, where macro code (direct and
indirect) is resolved and processed. That happens immediately. However, any
text which is generated gets stacked up at the step boundary.

Try this:

%macro helloworld;
%put Hello World -- &more;
%mend;

%macro indirect;
%helloworld
%mend;

%let more=Compile time;
data _null_;
call symput('more','Before CALL EXECUTE at runtime');
call execute(trim('%indirect');
call symput('more','After CALL EXECUTE at runtime');
run;

It produces:

23 %let more=Compile time;
24 data _null_;
25 call symput('more','Before CALL EXECUTE at runtime');
26 call execute('%indirect');
27 call symput('more','After CALL EXECUTE at runtime');
28 run;

Hello World -- Before CALL EXECUTE at runtime
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.01 seconds


NOTE: CALL EXECUTE routine executed successfully, but no SAS statements
were generated.

If any macro processing were deferred until the step boundary, the "Hello
World" would appear after the NOTEs and would say "After" instead
of "Before".
It is executed for each iteration.
Yes.
Can you confirm the above observations? Thanks,
J S Huang
1-515-557-3987
fax 1-515-557-2422
12/17/2005 3:32:30 PM >>>
On Fri, 16 Dec 2005 19:55:24 -0800, David L Cassell
Post by David L Cassell
Post by J S Huang
I have a question on how to distinguish between SAS statement and
macro
Post by David L Cassell
Post by J S Huang
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
Post by David L Cassell
Post by J S Huang
boundary (if the value is a SAS statement) or immediately (if the
value is
Post by David L Cassell
Post by J S Huang
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 Cassell
First, I have to admit that SAS docs read as if they were written for
people
Post by David L Cassell
who
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 Cassell
the CALL EXECUTE() parentheses is, by doing any macro variable parsing
or
Post by David L Cassell
text substitution needed, along with filling in anything from the data
set.
Post by David L Cassell
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 Cassell
data
step? If so, then slap it on a queue, and execute all those things
once
you
Post by David L Cassell
have
passed the step boundary (like that RUN statement at the end of your
DATA
Post by David L Cassell
step).
Is it a macro call, or some macro code? Then it gets executed
immediately,
Post by David L Cassell
without waiting for the next step boundary.
Which may be just what you DON'T want to happen. Lots of times we
want
Post by David L Cassell
the series of macro calls to execute right *after* the step, so you
can put
Post by David L Cassell
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: 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,
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
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: CALL EXECUTE routine executed successfully, but no SAS
statements
were generated.
%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.
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: 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 Cassell
There's a section on
these
sorts of timing issues in Art Carpenter's macro book, and I highly
recommend
Post by David L Cassell
that 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
_________________________________________________________________
Don't just search. Find. Check out the new MSN Search!
http://search.msn.click-url.com/go/onm00200636ave/direct/01/
toby dunn
2005-12-19 19:12:55 UTC
Permalink
Okay I just came in on this thread but I still don't see what the big deal
is:

%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 execute( '%helloworld' ) ;
call execute( '%nrstr(%helloworld)' ) ;
call symput('more','After CALL EXECUTE at runtime') ;
run ;



call execute( "%helloworld" ) ;

Double quotes: Means that the macro processor will pick this up and execute
the SAS code at Compile time of the Data step.


call execute( '%helloworld' ) ;
Single quotes means that the macro processor wont pick it up and the
statements get executed at the data step execution time.


call execute( '%nrstr(%helloworld)' ) ;
Move the %nrstr inside of the single quotes means that it wont get executed
at Data step compile or excution time but that it will be held and executed
after the data step is finished. you have to move the %nrstr inside of the
quotes due to the fact that you need the macro processor which is what will
pick this thing up after SAS hits the call execute at execute time, to iggy
the % sign a tokien.

When you do

call execute( %nrstr('%helloworld') ) ;

Won't work because the %nrstr is being used before it gets passed off to the
macro processor.




Toby Dunn





From: Jiann-Shiun Huang <Jiann-***@AMERUS.COM>
Reply-To: Jiann-Shiun Huang <Jiann-***@AMERUS.COM>
To: SAS-***@LISTSERV.UGA.EDU
Subject: Re: Call Execute
Date: Mon, 19 Dec 2005 12:03:08 -0600

Howard:

From the responses that you and Fred made, I made some test runs and
draw the following conclusion:
(1) if
call execute(%nrstr('%helloworld'));
is replaced by
call execute('%helloworld');
there will be no difference in result. The reason, I believe, is
string inside single quote will not be resolved by either macro or macro
variable. Hence %nrstr has no effect on the string %helloworld.

(2) if
call execute(%nrstr('%helloworld'));
is replaced by
call execute("%helloworld');
then the execution will be at compile time, and the log shows the
following:

21 %macro helloworld;
22 %put Hello World -- &more;
23 %mend helloworld;
24
25 %let more=Compile time;
26 data _null_;
27 call symput('more','Before CALL EXECUTE at runtime');
28 call execute("%helloworld");
Hello World -- Compile time
29 call symput('more','After CALL EXECUTE at runtime');
30 run;

My conclusion about call execute is this:
(1) if double quote is used in the parenthesis of execute it is
executed by macro processor when word scanner detects it.
(2) if single quote is used, then the call execute statement will be
placed in Data Step compiler till the end of the Data step. At that
time macro is called to execute in the sequence it appears in Data
step.




NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds





J S Huang
1-515-557-3987
fax 1-515-557-2422
12/19/2005 11:20:04 AM >>>
On Mon, 19 Dec 2005 10:09:19 -0500, Fehd, Ronald J <***@CDC.GOV>
wrote:

[snip]
'macro language element'
is anything with percent sign in front of it.
if that is a macro call: %DoThis
then you do -not- want that to 'happen' immediately
but to be happen after the next step boundary.
call execute(%nrstr('%DoThis(parm=X)'));
But when I submit

%macro helloworld;
%put Hello World -- &more;
%mend;

%let more=Compile time;
data _null_;
call symput('more','Before CALL EXECUTE at runtime');
call execute(%nrstr('%helloworld') );
call symput('more','After CALL EXECUTE at runtime');
run;

I get

32 %let more=Compile time;
33 data _null_;
34 call symput('more','Before CALL EXECUTE at runtime');
35 call execute(%nrstr('%helloworld') );
36 call symput('more','After CALL EXECUTE at runtime');
37 run;

Hello World -- Before CALL EXECUTE at runtime
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.01 seconds

I want/expect the "Hello World" to appear after the end-of-step NOTEs
and
to include the word "After" from the last CALL SYMPUT.
we have had long threads on this quirk in the past
my keywords/phrase: macro with complexity
http://www.listserv.uga.edu/archives/sas-l.html
search for: macro with complexity
since: Dec 2002
the Dec 11 2002 post addresses how to debug programs that use call
execute
Ron Fehd the macro maven CDC Atlanta GA USA RJF2 ata cdc d0t g0v
Continue reading on narkive:
Loading...