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 1998, week 2)Back to main SAS-L pageJoin or leave SAS-L (or change settings)ReplyPost a new messageSearchProportional fontNon-proportional font
Date:         Tue, 10 Nov 1998 11:41:08 -0500
Sender:       "SAS(r) Discussion" <SAS-L@UGA.CC.UGA.EDU>
Subject:      Re: Can do this by 'one step' ?
Comments: To: Chenglong Han <hanc@CALIB.COM>
Content-Type: text/plain; charset=US-ASCII

Subject: Can do this by 'one step' ? Summary: In one macro invocation, yes. A simple and then a user friendly solution is given. Respondent: Ian Whitlock <>

Chenglong Han <hanc@CALIB.COM> asks:

> I want to invoke a sas macro, for example, MABC, for multiple > times. Can I do this just by invoking once ? For example, > > %MACRO MABC ( VAR); ....... %MEND; > > Instead of doing this by %MABC ( X1); %MABC (X2); ....... %MABC > (Xn); > > Can I do this by some way like %MABC (X1-XN);

One, could easily achieve the objective by changing the parameter list. For example:

%macro mabc ( var= ) ; %put macro mabc exectuing with var=&var ; %mend mabc ;

%macro drvrmabc ( root= , strt= , stop= ) ; %local i ;

%if %quote(&stop) = %str() %then %let stop = &strt ; %do i = &strt %to &stop ; %mabc ( var = &root&i ) %end ; %mend drvrmabc ;

%drvrmabc ( root=xyz12a, strt=43 ) %drvrmabc ( root=xyz12a, strt=43, stop=45 )

Of course, one could replace the call to %MABC in the macro DRVRMABC with the code of MABC and then change the name of the macro to MABC, if desired. Note DRVRMABC is callable anywhere MABC is.

I interpreted the question as a more interesting one. Can one preserve the parameter and notation as asked for? Again I have used a separate driving macro and a key word parameter. (I don't write macros with positional parameters except in unusual circumstances.) Here is the code. It demonstrates a big advantage given by the ability to execute DATA step functions within macro.

%macro drvrmabc ( var= x1 - x5 ) ; %local temp strt stop root1 root2 i x ; %let temp = %scan(&var, 1 , - ) ; %let temp = %sysfunc(reverse(&temp)) ; %let x = %sysfunc(verify(&temp,0123456789)) ; %let strt = %sysfunc(reverse(%substr(&temp,1,&x-1))) ; %let root1 = %sysfunc(reverse(%substr(&temp,&x))) ;

%let temp = %scan(&var, 2 , - ) ; %if %quote(&temp) = %str() %then %do ; %let stop = &strt ; %let root2 = &root1 ; %end ; %else %do ; %let temp = %sysfunc(reverse(&temp)) ; %let x = %sysfunc(verify(&temp,0123456789)) ; %let stop = %sysfunc(reverse(%substr(&temp,1,&x-1))) ; %let root2 = %sysfunc(reverse(%substr(&temp,&x))) ; %end ;

%if &root1 = &root2 and &strt <= &stop %then %do ; %do i = &strt %to &stop ; %mabc ( var = &root1&i ) %end ; %end ; %else %do ; %put ERROR(drvr): Cannot parse, halting. VAR=&var ; %end;

%mend drvrmabc ;

%drvrmabc ( var=xyz12a43 ) %drvrmabc ( var=xyz12a43-xyz12a45 ) %drvrmabc ( var=xyz12a43-xy12a45 )

Again the driving macro may be called anywhere the original macro can be called. The code is a good deal harder, but this is the price of friendliness.

None of the above assumes one is in a DATA step and VAR names a variable or group of variables in a SAS data set. If this is the case then one could have the driver

%macro drvrmabc ( data = &syslast , var=a -- b c1 - c5 d ) ;

The code for the driver now gets a good deal more difficult to do correctly, and I will not present it. However, I am interested in pursuing the question of whether the parameter DATA can be eliminated. Does anyone know of a method of finding out what data sets have been opened in compiling a DATA step so that the DATA parameter would be superfluous? Then, of course, I would also like access to the PDV, but I am certain this is not yet possible.

Ian Whitlock

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