|
|||
|
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) |
|
|
||||
|
||||
|
|
![]() |
| Popular Tags in the Forum |
| 101, laypersonmacro, passing, reference |
| Thread Tools | |
| Display Modes | |
|
|
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 |