Date: Wed, 16 Jan 2002 08:59:28 -0500 Ian Whitlock "SAS(r) Discussion" Ian Whitlock Nested Macro Variables To: SAS-L@LISTSERV.VT.EDU text/plain; charset="iso-8859-1"

Subject: RE: Nested Macro Variables Summary: Macro Design Questions Respondent: Ian Whitlock <IanWhitlock@westat.com>

> 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 and K.

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 ; > k=12

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 ; %z()

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 [Susanne.Sardella@COGNIGENCORP.COM] asked:

> 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 April.

Ian Whitlock

Back to: Top of message | Previous page | Main SAS-L page