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 2010, week 1)Back to main SAS-L pageJoin or leave SAS-L (or change settings)ReplyPost a new messageSearchProportional fontNon-proportional font
Date:         Thu, 7 Jan 2010 10:56:09 -0500
Reply-To:     Chang Chung <chang_y_chung@HOTMAIL.COM>
Sender:       "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From:         Chang Chung <chang_y_chung@HOTMAIL.COM>
Subject:      Re: Issue with %let
Comments: To: Ian Whitlock <iw1sas@GMAIL.COM>

On Wed, 6 Jan 2010 16:46:24 -0500, Ian Whitlock <iw1sas@GMAIL.COM> wrote:

... >Indirection such as > > %let macvar - modelvars ; > %let &macvar = x y z ; > %put &&&macvar ; > >can be very useful and is an important pattern for >exporting local variables to an external environment. >However, > > %let myvar = %nrstr(%let modelvars =) ; > %unquote(&myvar) x y z ; > %put &modelvars ; > >is just very obscure code. In general, macro can be good >for generating SAS code, but it is a very poor language for >generating macro code. ... Hi,

I agree with Ian that the macro language is poor for generating macro code.

On exporting values to an external environment, there are several techniques. Most popular seems to be the one Ian mentions. Suppose that your macro, zero, wants to return a value(0) to the environment, then what you do is to pass your macro variable *name* to your macro. Your macro, then assign the return value to the &name. (shown in %zero below). An old timer may stick to the convention of naming by-name macro parameters starting with an underscore(_), in order to distinguish them from the usual by-value parameters.

One may accomplish the same thing using the %global statement inside the macro (as macro %one below does), but it has been pointed out many, many times that using the global macro variable for this purpose is not a good practice and should be avoided.

Many different ways have proposed, then, to avoid the global macros, and one way was returning a %let statement as a whole, macro quoted, so that it can be %unquoted in the environment as shown in macro %two below. Richard Devenezia calls this technique "RESOLVE" and utilizes in his elaborate %split macro, http://devenezia.com/downloads/sas/macros/index.php?m=split

By the way, the difference between %str() and %nrstr() functions is that the latter quotes the macro triggers % and &, while the former does not. In some cases, however, you can find a creative way of using %str() to do what %nrstr() does, as demonstrated in the macro %three below -- with a warning though :-(

Below ran on 9.2 (TS1M0) on W32_VSPRO. Hope this helps a bit.

Cheers, Chang

%*-- using a by-name (not by-value) parameter --*; %let r=; %macro zero(_out=); %let &_out=0; %mend zero; %*-- check --*; %put before: r=&r; %zero(_out=r) %put after: r=&r; %*-- on log before: r= after : r=0 --*;

%*-- global macro to return some values. should be avoided --*; %let r=; %macro one; %global r; %let r= 1; %mend one; %*-- check --*; %put before: r=&r; %one %put after : r=&r; %*-- on log before: r= after : r=1 --*;

%*-- return a value without global macros. requires unquoting --*; %macro two; %nrstr(%let r=2;) %mend two; %*-- check --*; %symdel r; %put before: r=&r; %unquote(%two) %put after : r=&r; %*-- on log WARNING: Apparent symbolic reference R not resolved. before: r=&r after : r=2 --*;

%*-- a creative way of using %str() to quote macro triggers --*; %macro three; %str(%%l)et r=3; %mend three; %symdel r; %put before: r=&r; %unquote(%three) %put r=&r;


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