[prev in list] [next in list] [prev in thread] [next in thread] 

List:       sas-l
Subject:    Re: Avoiding file name collisions in macros
From:       Curt Seeliger <Seeliger.Curt () EPAMAIL ! EPA ! GOV>
Date:       2005-02-28 23:27:56
[Download RAW message or body]

Dennis wrote on 02/28/2005 11:17:42 AM:

> You could use the &sysindex automatic macro variable which contains
> the count of macros that have begun execution. Just prefix it with
> an underscore or two to make it a valid file name.

Sounds good, but this can fail silently  (thanks for showing me this,
I'd forgotten about it).

In the macros below, the temporary file created by %three() at the start
is intended to be read at the end, creating a file with a='three' and
b='three'.  Alas, &sysindex has changed during the execution of
%three(), and the final dataset uses the temporary data file from %two
as you can see from the proc print output.

The obvious fix here is to copy the value of &sysindex to a local macro
variable, and use that value as is done in %four().  This may be the
most elegant means currently available.  Providing data sets scoping
would be a tad more elegant, but would likely require a bit of macro
rethinking on the part of SAS.

%macro one;
  data __temp&sysindex; a='one  '; run;
  %put one      : sysindex=&sysindex;
%mend one;
%macro two;
  data __temp&sysindex; a='two  '; run;
  %put two      : sysindex=&sysindex;
%mend two;
%macro three(outf);
  %put three (1): sysindex=&sysindex;
  %one;
  data __temp&sysindex; a='three'; run;
  %put three (2): sysindex=&sysindex;
  %two;
  data &outf; set __temp&sysindex; b='three'; run;
  %put three (3): sysindex=&sysindex;
%mend three;

%macro four(outf);
  %local tpre;
  %let tpre=&sysindex;

  %put three (1): tpre=&tpre, sysindex=&sysindex;
  %one;
  data __temp&tpre; a='three'; run;
  %put three (2): tpre=&tpre, sysindex=&sysindex;
  %two;
  data &outf; set __temp&tpre; b='three'; run;
  %put three (3): tpre=&tpre, sysindex=&sysindex;
%mend four;

%three(foo);
proc print data=foo;
run;

SAS log follows:
three (1): sysindex=22

NOTE: The data set WORK.__TEMP23 has 1 observations and 1 variables.
NOTE: DATA statement used (Total process time):
      real time           0.01 seconds
      cpu time            0.01 seconds


one      : sysindex=23

NOTE: The data set WORK.__TEMP23 has 1 observations and 1 variables.
NOTE: DATA statement used (Total process time):
      real time           0.01 seconds
      cpu time            0.01 seconds


three (2): sysindex=23

NOTE: The data set WORK.__TEMP24 has 1 observations and 1 variables.
NOTE: DATA statement used (Total process time):
      real time           0.01 seconds
      cpu time            0.00 seconds


two      : sysindex=24

NOTE: There were 1 observations read from the data set WORK.__TEMP24.
NOTE: The data set WORK.FOO has 1 observations and 2 variables.
NOTE: DATA statement used (Total process time):
      real time           0.06 seconds
      cpu time            0.03 seconds


three (3): sysindex=24
118  proc print data=foo;
119  run;

NOTE: There were 1 observations read from the data set WORK.FOO.
NOTE: PROCEDURE PRINT used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds

cur - who'd answer calls to simplify the code by reverting to wet clay
and a sharp stick.

--
Curt Seeliger, Data Ranger
CSC, EPA/WED contractor
541/754-4638
seeliger.curt@epa.gov

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic