|Date: ||Wed, 16 Jan 2002 08:59:28 -0500|
|Reply-To: ||Ian Whitlock <WHITLOI1@WESTAT.COM>|
|Sender: ||"SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>|
|From: ||Ian Whitlock <WHITLOI1@WESTAT.COM>|
|Subject: ||Nested Macro Variables|
|Content-Type: ||text/plain; charset="iso-8859-1"|
Subject: RE: Nested Macro Variables
Summary: Macro Design Questions
Respondent: Ian Whitlock <IanWhitlock@westat.com>
Amy Scheer [mailto:ascheer@ERAC.COM] asked:
> I have a line of text that is repeated multiple times and I want to
> create a macro variable to replace the text.
> %let kvar=%str(
> %let k = %sysfunc(putn(&j,z2.));
> Basically, I just want to execute "&kvar;"
> and have it replaced by "%let k = %sysfunc(putn(&j,z2.));"
Let me rephrase the question. You have declared macro variables J
You want to assign K the value of &J (a number between 0 and 99)
with a leading 0 if needed in the shortest form possible.
You have chosen &KVAR for your answer, but are having trouble defining
KVAR. Paul Dorfman [Paul.Dorfman@BCBSFL.COM] gave you an answer
changing the form to %UNQUOTE(&KVAR),
> 1 %let j = 12 ;
> 2 %let kvar= %nrstr ( %let k = %sysfunc(putn(&j,z2.)); ) ;
> 3 %unquote(&kvar)
> 4 %put k=&k ;
However, the macro variable solution to my statement of the problem is
not a good one for several reasons. The solution is hard to read
because a macro programmer does not expect macro code buried in a
macro variable. It is hard to read because a macro programmer would
expect the problem to be solved with macro. Macros have parameters
and can lead to a general solution. The macro variable solution
cannot be parameterized. It is a difficult, non general solution,
which could lead you down a path of writing poor macro code.
First let's go for the simplest answer. Get what you want with the
smallest amount of writing while maintaining a general solution.
*first declare k, then call the macro ;
Note that in this form there is less of a a readability problem. A
macro programmer would expect the call to Z to solve a problem. She
would still not know what Z is doing without reading the macro, but
that would be an easy task. Here is the macro.
%macro z (kvar=k,jvar=j,n=2) ;
%let &kvar = %sysfunc ( putn ( &&&jvar , z , &n ) ) ;
%mend z ;
Note that any variable can have any number of leading zeros with this
macro simply by changing the call. Hence it solves a more general
problem in a more readable fashion. However, I would not consider
it the best solution from the readability point of view. For that
I would prefer
%let k = %z(&j) ;
This solution involves a little more writing, but it is considerably
more readable. Any macro programmer can see that Z assigns a value to
K based on the value of J. The name, Z, might even lead her to
suspect some number of leading 0's. Note that in this case K does not
have to be previously declared. Thus it is a little easier to use,
albeit at the expense of writing a few more symbols. (Actually, I
would not write macros without variable declarations, hence this is not
really an issue for me.) Here is the macro.
%macro z ( v , n=2 ) ;
%sysfunc ( putn ( &v, z, &n ) )
%mend z ;
Several months ago Susanne Sardella
> Does anyone know of an article that includes hints for creating
> well constructed, easy to read macros?
In answer to that related question, I will be be presenting "SAS(r)
Macro Design Issues" in the Beginning Tutorial Section of SUGI in