Go Back   Rhinocerus > Newsgroup > Newsgroup comp.soft-sys.sas

Reply
 
Thread Tools Display Modes
  #1 (permalink)  
Old 12-13-2005, 04:33 PM
Terjeson, Mark
Guest
 
Posts: n/a
Default LayPerson's-Macro 101: Re: Passing by reference

Sure.

The SAS macro facility is unlike macro facilities
in other languages where others are more like
subroutines or callable subroutines during execution.

The SAS macro stuff, once described, may seem much
less sophisticated, but is actually much more powerful
in the long run.

The easiest way to get a grip on SAS macro stuff is
to think of it as "text-substitution". Creating and
troubleshooting SAS macro goodies is far easier if
not 100% if you remember text-substitution.

Disclaimer:
My apologies to all of the purists for not utilizing
all the technical/proper terminology but I find most
people learning don't have all that lingo down yet
and they are desirous of understanding how to get
themselves productive with the knowledge base they
have. So it is okay to learn *how* to use macros well
and let some the terminology and the esoteric descriptions
come a little later. While specifics and exactness may
not abound in the discussion to follow, I find most folks
learning SAS macros become very effective (creating and
troubleshooting) with this lay person's approach.

Thus, this is entitled LayPerson's-Macro 101.

Prior to sending the SAS code to the compiler/runtime
for execution (or whatever terminology works for you)
the text that you submit gets run through the macro
parser/compiler/preprocessor (or whatever terminology
works for you). i.e. macro goodies (usually notated
with & or % etc. are found in the chunk of text you
have submitted and those references resolve which
means what they resolve to is text and that text is
substituted into your original text in the internal
copy. One tricky but powerful feature is that the
text will be processed through the macro parser as
many times as necessary until ALL of the macro stuff
has been resolved, and THEN the substituted text is
sent to the datastep compiler/runtime that you may
normally think of.

The macro variables and the sas macros are merely
resolved and saved-off text that can be recalled
later for text replacement(substitution) and then
the resulting text as mentioned gets run.

I will enclose a description I wrote a long time
ago. It is not intended to be an exact technical
description of exactly how everything is really
designed, but it is intended for a different view
of how to grasp SAS macro concepts. It helps grant
a picture of what you frequently hear mentioned as
"timing issues".



So here goes,

SAS macro stuff may seem overwhelming. So the first step
is to get rid of the big black cloud. The best way to
understand SAS macro stuff is to think of it as very, very,
very simple...

okay, ya ready...

"Text substitution".

That's it.

Everything to do with SAS macro stuff is text substitution.

The only other thing to know is that there are two passes
that your text code goes through. First, it goes through
a macro parser that ignores all of your regular sas code.
Yes, ignores the text that looks like regular sas code.
As it streams through all of your text it only looks for
% and & items. When it finds a % or & it takes the
following token and goes and finds the text that has been
previously save off to the side, and merely substitutes
the text. When this pass has completed, if there were
any % or & the text will have been modified with the
text substitutions. The second, this resultant text is
submitted to the SAS compiler/runtime just as you
normally perceive.


Example, no macro stuff,


data temp1;
a=1;
run;


When you submit this code, the first pass, the macro
parser looks through all of the three lines of text and
finds NO % or & and so does nothing. Then the text
is sent to the second pass, for execution and it runs
the
data temp1;
a=1;
run;
just as you would expect.



Now for example, let's try this,



%macro xxx;
hello
%mend;


When this is submitted, the first pass macro
parser finds a % character followed by MACRO.
All that is done at this time is that *all* of the
text found between these two lines:
%macro xxx;
%mend;
is saved off to the side and that chunk of save
text is given the name 'xxx'.

That's it. No more. No less.

See I told ya it was simple. har har
Let's keep going.... )


If we have in our code this line,

%xxx

the first pass macro parser finds the % and it
then looks at the next token word and finds XXX.
It first looks through it's library of macro statement
word tokens, such as MACRO, MEND, etc. and
it does not find a match. It assumes therefore that
it must be a chunk of text that you have previously
saved. So it goes and looks for XXX. If you had
previously submitted the XXX macro, it will find the
XXX where it had save the text.

All that to say it goes and retrieves the chunk of
text labeled XXX. And guess what, all it does is
merely do text substitution.

%xxx

in the first pass gets replaced with

hello

which was the text that was saved off.


That's it. That's what macro stuff is all about in
SAS. Why is it so simple. Because sometimes
the most simple can become the most powerful!!!


Making it more powerful,

Someone had the bright idea that if, during the
first pass, it could do some conditional checks
on what code text to change/substitute, then
that could be pretty handy. Note that we are
not talking about changing the sas code that
will execute per se, we are talking about changing
the text that will *become* the sas code that then
gets executed. Boggle the mind? Let try something.


Let's go back to just the simple text-substitution.

If we had some regular sas code such as,


* copy dataset from one library to another ;
data bbb.myfile1;
set aaa.incomingfile1;
run;

* copy dataset from one library to another ;
data bbb.myfile2;
set aaa.incomingfile2;
run;

* copy dataset from one library to another ;
data bbb.myfile3;
set aaa.incomingfile3;
run;


This looks normal. The code text was replicated
three times and only the suffix number on our incoming
and outgoing datasets is changed each time.

We can implement the pure text substitution as
described above like this,


%macro cpyfile(thenum);
* copy dataset from one library to another ;
data bbb.myfile&thenum;
set aaa.incomingfile&thenum;
run;
%mend;

%cpyfile(1)
%cpyfile(2)
%cpyfile(3)



During the first pass macro parser--------

This text found between %macro and %mend is saved off to
the side internally for use later and given the name 'cpyfile'.

Then when it finds %cpyfile, it knowd that there was one
passed argument called 'thenum'. On the first line,

%cpyfile(1)

it takes the text characters in the parentheses () which
is "1". It does not care if it is a number character or alpha
character, it just grabs the characters. At this point "1" is
saved off to the side and called 'thenum'. Just like the other
macro text above was saved off.

Then it goes and retrieves the saved off chunk of text
called 'cpyfile' which is just as we left it, the four lines below,

* copy dataset from one library to another ;
data bbb.myfile&thenum;
set aaa.incomingfile&thenum;
run;

See it has not changed, it is just as it was saved off.
After retrieving the text it looks for % or & characters.
It finds a & character with the token 'thenum' after it. So
the macro parser goes and looks for saved off text called
'thenum' and it finds it. It takes all of the retrieved text
and replaces all the the retrieved text for the "&thenum".
In this case, the 'thenum' saved text consists of just one
character, "1". So when the all of the occurances of
*&thenum get text substitution performed, the original

* copy dataset from one library to another ;
data bbb.myfile&thenum;
set aaa.incomingfile&thenum;
run;

now looks like

* copy dataset from one library to another ;
data bbb.myfile1;
set aaa.incomingfile1;
run;


Pretty tricky huh? Guess what, all that has gone on to
this point is
1) save off chunks of text
2) retrieve chunks of text
3) replace text

See what I mean, very, very simple tasks. And easy to
understand too. Just like simple building blocks that can
be stacked up in a very complex design.


Therefore the code


%cpyfile(1)
%cpyfile(2)
%cpyfile(3)



turns into




* copy dataset from one library to another ;
data bbb.myfile1;
set aaa.incomingfile1;
run;

* copy dataset from one library to another ;
data bbb.myfile2;
set aaa.incomingfile2;
run;

* copy dataset from one library to another ;
data bbb.myfile3;
set aaa.incomingfile3;
run;




and only using the three simple tasks describe thus far.
It looks just like the original code we manually wrote!


So far, just text substitution.




Now, what if we had 500 of these to do?


We could manually write 500 lines like this,


%cpyfile(1)
%cpyfile(2)
%cpyfile(3)
%cpyfile(4)
%cpyfile(5)
%cpyfile(6)
Reply With Quote
Alt Today
Advertising
 
and become member of Rhinocerus
Standard Sponsored Links

Reply

Popular Tags in the Forum
101, laypersonmacro, passing, reference

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Macro Quoting Question Kevin Morgan Newsgroup comp.soft-sys.sas 1 07-06-2007 02:47 AM
Re: How to reference a macro vatiable generated from a macro toby dunn Newsgroup comp.soft-sys.sas 0 10-17-2006 07:49 PM
SCL Joe (was RE: macro structure) Gregg P. Snell Newsgroup comp.soft-sys.sas 0 06-27-2006 07:59 PM
Re: Understanding How Macro Processor Works Terjeson, Mark Newsgroup comp.soft-sys.sas 0 03-24-2006 11:00 PM
Re: MAcro Design was (Re: Macro quoting essentials) Ian Whitlock Newsgroup comp.soft-sys.sas 3 12-11-2005 11:18 PM



All times are GMT. The time now is 06:51 PM.


Copyright ©2009

LinkBacks Enabled by vBSEO 3.3.0 RC2 © 2009, Crawlability, Inc.