LISTSERV at the University of Georgia
Menubar Imagemap
Home Browse Manage Request Manuals Register
Previous messageNext messagePrevious in topicNext in topicPrevious by same authorNext by same authorPrevious page (January 2002, week 3)Back to main SAS-L pageJoin or leave SAS-L (or change settings)ReplyPost a new messageSearchProportional fontNon-proportional font
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
Comments: To: SAS-L@LISTSERV.VT.EDU
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 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