Date: Thu, 4 Mar 1999 11:48:56 +1100
Reply-To: Thomas Rick <rthomas@WOOLWORTHS.COM.AU>
Sender: "SAS(r) Discussion" <SAS-L@UGA.CC.UGA.EDU>
From: Thomas Rick <rthomas@WOOLWORTHS.COM.AU>
Subject: Re: MACRO Invocation - Solution
Content-Type: text/plain
Thanks to Wolf, Thomas, Nancy B, Nancy P and Ian for their help in solving
my problem.
The problem was not one but two nested macros that created a macro variable
I. Neither was declared as local. Declaring the variables as local in all
the macros using %LOCAL fixed the problem.
I'm off to re-read the manual to get all this stuff about macro referencing
back into my head - I thought I knew it once :o)
Thanks again for the help - this list is great!
Regards,
Rick.
> -----Original Message-----
> From: WHITLOI1@westat.com [SMTP:WHITLOI1@westat.com]
> Sent: Thursday, March 04, 1999 2:46 AM
> To: Thomas Rick; SAS-L@UGA.CC.UGA.EDU
> Subject: Re:MACRO Invocation
>
> Subject: MACRO Invocation
> Summary: Declare local variables, use CALL EXECUTE for looping
> Respondent: Ian Whitlock <whitloi1@westat.com>
>
> Thomas Rick <rthomas@WOOLWORTHS.COM.AU> describes a classic problem.
> He has to invoke a macro a number of times
>
> > %BMB1P(SYSTEM1,DAILY RUN DURATION);
>
> He has coded
>
> > %MACRO GRAPHIT;
> > %DO I=1 %TO &SYCNT %BY 1;
> > %BMB1P(&&SYSNAM&I,DAILY RUN DURATION);
> > %END;
> > %MEND;
> >
> > %GRAPHIT;
>
> to do the job, but
>
> > The macro executes perfectly for SYSTEM1, then executes for
> > SYSTEM5, and then executes repeatedly for SYSTEM4 until I cancel
> > the job. The data is correctly sorted by system.
>
> This is a classic description of a clash in names of macro variables. The
> macro BMB1P has a macro variable I that is not
> declared local. Hence, when called by GRAPHIT, it uses the looping
> variable I of GRAPHIT. On the first call things work fine and I is
> set to 4. Bumped by the loop to 5 and executed resetting I to 3. Now I is
> repeatedly set to 3 and bumped to 4. So the same
> invocation is repeated until stopped.
>
> The best habit is declare all macro variable local. Add
>
> %local I ;
>
> to BMB1P to solve the problem. A poor solution would be to change the
> name of the looping variable in GRAPHIT until you found one that worked.
>
> Now let's consider the problem - how should BMB1P be invoked multiple
> times? Thomas' solution:
>
> > I have done is to read the input data and generate the following
> > macro variables;
> >
> > SYSNAM1......SYSNAMn containing each system name (SYSTEM1 ...
> > SYSTEMn). SYCNT containing the number of systems in the input
> > data (which is equal to n).
>
> and then writing is managing macro is a good old solution to the problem.
> I find it annoying that a lot of extra variables are
> generated and not explicitly described in the interface for GRAPHIT. With
> version 6.07+ one can do better with using CALL EXECUTE.
>
> data _null_ ;
> infile ... ;
> input @... system $char.... ;
>
> call execute ( '%BMB1P(' || SYSTEM
> || ",DAILY RUN DURATION)" ) ;
> run ;
>
> This solution will not work if BMB1P uses execution of a step to create a
> macro variable, e.g. CALL SYMPUT or PROC SQL. Otherwise it is the
> simplest solution to the looping problem.
>
> Note that Thomas' solution works without restrictions on the code in the
> called macro.
>
> > %MACRO GRAPHIT;
> > DATA _NULL_;
> > FILE FT15F002 NOTITLES LINESIZE=72;
> > %DO I=1 %TO &SYCNT %BY 1;
> > PUT @3 '%BMB1P('
> > @10 "&&SYSNAM&I,DAILY RUN DURATION)";
> > %END;
> > RUN;
> > %MEND;
> >
> > %GRAPHIT;
> >
> > %INCLUDE FT15F002;
>
> Why wasn't there a conflict with I's here? GRAPHIT finished executing
> before the %INCLUDE was executed, hence BMB1P used a local I and caused no
> problems. A system independent solution would use a temporary catalog to
> store the code generated.
>
> filename code catalog "work.temp.bmb1ps.source" ;
>
> Now reference CODE instead of FT15F002 in the preceding code.
>
> Ian Whitlock
**********************************************************************
CAUTION: This Message may contain confidential information intended
only for the use of the addressee named above. If you are not the
intended recipient of this message you are hereby notified that any
use, dissemination, distribution or reproduction of this message is
prohibited. If you received this message in error please notify
Mail Administrators immediately. Any views expressed in this
message are those of the individual sender and may not necessarily
reflect the views of Woolworths Ltd.
**********************************************************************
|