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 (April 2005, week 4)Back to main SAS-L pageJoin or leave SAS-L (or change settings)ReplyPost a new messageSearchProportional fontNon-proportional font
Date:   Thu, 28 Apr 2005 18:27:50 +0000
Reply-To:   iw1junk@COMCAST.NET
Sender:   "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From:   Ian Whitlock <iw1junk@COMCAST.NET>
Subject:   Re: Problem with Nested Macros
Comments:   cc: Dennis Diskin <ddiskin@GMAIL.COM>, sa polo <solouga2@rediffmail.com>

Sa Polo now has his CALL EXECUTE version of code working, but complained about his current version of %RunMe

> Unfortunately the %if %sysfunc(fexist(srcfile)) statement > references only the last parameter passed in this > particular case c:\flags_fiveT1A_20050331.csv. > It seems to be some sort of macro resolution problem.

The code was

> %MACRO RunMe(xx); > %PUT xx=&xx; > FILENAME srcfile "c:\&xx"; > %if %sysfunc(fexist(srcfile)) %then > %put The file identified by the fileref srcfile exists.; > %else > %put %sysfunc(sysmsg()); > > %MEND;

to be called in a DATA step by

> CALL EXECUTE( '%RunMe('||yy||')');

In response Dennis suggested

dd> Yes there are some complexities in timing when using CALL dd> EXECUTE. I pefer to keep things simple, Change your runme dd> macro to only run cacro code: (use FILEEXIST instead of dd> FEXIST) dd> dd> %MACRO RunMe(xx); dd> %PUT xx=&xx; dd> %if %sysfunc(fileexist(c:\&xx)) %then dd> %put The file identified by the fileref srcfile exists.; dd> %else dd> %put %sysfunc(sysmsg()); dd> %MEND;

Perhaps it is worth pointing out what happened. In both cases the macro was executed immediately during execution of the DATA step, i.e. any SAS code to be generated was generated. In Dennis' case all the code is macro instructions and all were executed in sequence as expected.

In Sa's case, the macro code is executed at once, but the SAS code is passed to the input stack for later execution. In other words, all the FILENAME statements were executed after the step finished while all the macro code applying the fileref, SRCFILE, was applied before the relevant FILENAME statements were made. Why did Sa think it was the last file that was used? He must have tested interactively, created the filerefs and then tested again for some reason. At this point SRCFILE is pointing at the last file so that is the file whose existence is being tested.

Whether Dennis' fix is good enough or not depends on whether Sa is finished writing %RunMe or not, and if not what the future code looks like. To cover future complications Sa may want to enhance the CALL EXECUTE to

CALL EXECUTE( '%nrstr(%RunMe('||yy||'))');

In this case the macro is not invoked during execution of the DATA step, but afterward when there are no mysterious timing complexities or mysterious macro resolution problems.

I have often wondered why, when SI was adding so many new functions to version 9, they did not also add a CALL NRexecute routine to cover these problems. The biggest benefit might have been in the documentation explaining the difference between CALL EXECUTE and CALL NRexecute.

Ian Whitlock


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