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 (November 2010, week 1)Back to main SAS-L pageJoin or leave SAS-L (or change settings)ReplyPost a new messageSearchProportional fontNon-proportional font
Date:   Tue, 2 Nov 2010 07:27:14 -0400
Reply-To:   Søren Lassen <s.lassen@POST.TELE.DK>
Sender:   "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From:   Søren Lassen <s.lassen@POST.TELE.DK>
Subject:   Re: Please critique: Macro to UPCASE multiple macro variables at the same time
Comments:   To: Chang Chung <chang_y_chung@HOTMAIL.COM>
Content-Type:   text/plain; charset=ISO-8859-1

Chang, very good idea, but I think that the solution should be able to work with just about any macro variable names (preferably all but SYSPBUFF, which is always local). My suggestion is to make a macro call qDoOver, which does the same thing as your %DoOver, except that the output is quoted: %macro qDoOver(list, phrase=?, between=%str( )); %local i item; %let i = 1; %let item = %scan(&list, &i); %do %while (&item^=); %do;%qsysfunc(tranwrd(&phrase, ?, &item))%end; %let i = %eval(&i + 1); %let item = %scan(&list, &i); %if (&item^=) %then %do;&between%end; %end; %mend qDoOver;

I took the liberty of replacing your ingenious, but hard to fathom, use of "%*;" to remove spurious blanks in the macro output, and instead imbedded the macro output in "%do;....%end;", otherwise the only change from your %DoOver is the use of %qsysfunc rather than %sysfunc.

%qDoOver is used thus in the %MACUP macro: %macro macup / parmbuff; %unquote(%qDoOver(%scan(&syspbuff,1,()), phrase=%nrstr(%let ?=%upcase(&?);), between=)) %mend;

I did not make a special macro to avoid error messages when trying to upcase non-existing variables - I think such error messages can save quite a lot of debugging time.

Submitting %let item=test; %let phrase=test2; %let i=hoopla; %macup(item phrase i); %put &item &phrase &i;

writes "TEST TEST2 HOOPLA" in the log, in other words the global, rather than the local, variables got upcased, just as I wanted.

I really like this approach, I also think it is much better than my own original suggestion.

Regards, Søren

On Mon, 1 Nov 2010 14:38:25 -0400, Chang Chung <chang_y_chung@HOTMAIL.COM> wrote:

>On Fri, 29 Oct 2010 20:34:49 -0400, Tyler Lonczak <lonczakt@GMAIL.COM> >wrote: >... >>I recently wrote a macro to UPCASE multiple macro vars at the same >>time. The code is below. I would appreciate any feedback on it. >> >>%MACRO MacUp(Vars); >> %LOCAL I J; >> %DO I = 1 %TO %SYSFUNC(COUNTC(&vars,' '))+1; >> %LET J = &%SCAN(&vars,&I); >> %LET %SCAN(&vars,&I) = %UPCASE(&J); >> %END; >>%MEND; >> >>%LET Admin = 1; >>%LET State = ME; >>%LET Replevel = Dis; >> >>%PUT &admin &state &replevel; >>%MACUP(admin state replevel); >>%PUT &admin &state &replevel; >> >Hi, Tyler, > >Welcome to the wonderful world of sas macros! > >An interesting possibility to improve upon your macro is to separate the >looping (over a blank delimited list of words) part out into its own macro, >so that you don't have to code that part again. For another example, see >http://tinyurl.com/bk843m or >http://www.listserv.uga.edu/cgi-bin/wa?A2=ind0806D&L=sas-l&P=R21977&D=1&O=D >Hope this helps a bit. >Cheers, >Chang > >%macro doOver(list, phrase=?, between=%str( )); > %local i item; > %let i = 1; > %let item = %scan(&list, &i); > %do %while (&item^=); > %*;%sysfunc(tranwrd(&phrase, ?, &item)) > %let i = %eval(&i + 1); > %let item = %scan(&list, &i); > %if (&item^=) %then %*;&between; > %end; >%mend doOver; > >%*-- given a name of a macro var, upcase the content --*; >%macro myUpcase(_mvar); > %if not %symexist(&_mvar) %then %return; > %let &_mvar = %upcase(&&&_mvar); >%mend myUpcase; > >%*-- check --*; >%let admin = 1; >%let state = me; >%let replevel = Dis; > >%*-- upcase the values of the macro vars. --*; >%doOver(admin state replevel, phrase=%nrstr( > %myUpcase(?) >)) > >%put &admin &state &level; >%*-- on log >1 ME DIS >--*;


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