Do you know the amount of processing needed for each file? I don't, and I
did not want to assume it is small. As I stated in a previous message, I assumed
the sample code for %RunMe was just a stub to begin testing.
Then perhaps, small is not the really important point. From the parameter and it's use, it is clear that %RunMe is a viable block of code to be executed on one file, i.e. it could have a use of its own independent of any calling code. In this case I would not be quick to get rid of such a macro unless I knew much more about the real problem.
Finally, the subject line suggests that Sa wanted to know how to create a nested structure. In short, I do not see it as a "must solve" in minimal manner (where minimal means least structure or nesting possible) type of problem. Perhaps, it is just a prejudice of mine. If you are going to learn how to code with macros then
you better learn how to invoke a helping macro as soon as possible.
To back up this prejudice you might:
1) Prove that any macro A that calls another macro B could be written so that A
need not invoke any macros.
2) Quantify the cost in programming effort to take #1 too seriously.
-------------- Original message --------------
> I still have yet to figure out why a nested macro need be done at all in
> this case. One could whether writing only macro code or using data step
> code perform the same task without needing to nest macro's. I understand
> the need to explain why using call execute in Sa's case failed, but i fail
> to see why the design of the macro wasn't called into play also. Your
> reworking of his macro into macro code I admit is better suited to nesting
> macros than the data step solution but it seems that one can write roughly
> the same amount of code and get the same result without resorting to
> nesting. If one needed modularity I would say go for nesting but I don't
> see the need for it here. Perhaps I am missing something.
> Toby Dunn
> From: Ian Whitlock
> Reply-To: iw1junk@COMCAST.NET
> To: SAS-L
> Subject: Re: Problem with Nested Macros
> Date: Thu, 28 Apr 2005 18:27:50 +0000
> 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> %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