Date: Thu, 9 Dec 2004 21:45:29 -0600
Reply-To: Rob Rohrbough <Rob@ROHRBOUGH-SYSTEMS.COM>
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: Rob Rohrbough <Rob@ROHRBOUGH-SYSTEMS.COM>
Subject: Re: Assembled Macro Variables
In-Reply-To: <s1b8a03d.099@SLCM02.firsthealth.com>
Content-Type: text/plain; charset="us-ascii"
Ian, Jack,
Jack, I wish your solution worked as well on my machine as on both of yours.
Perhaps there is a hotfix for 8.2 out that you have but I don't?
The value passed as "junk" in my example is a system time stamp in my
production macros. I use it to compute elapsed time. I will confess I have
no code in them to account for the passing of midnight. It hasn't been an
issue for the several years the macro has been in production. I am adding
the constructed macro variable name to allow me to nest these macros which
are used to time multiple steps in a process.
I too believe in useful whitespace. I will try to use more when I post.
Ian, I hope that this is the case and that %SYMDEL is as flexible as %GLOBAL
and &LET. As to the need for %SYMDEL, I just wanted to keep the number of
defined global macro variables as low as possible - I suppose to minimize
confusion. Isn't this the reason for not using global macro variables
unless really needed? Perhaps Toby is the one who wants to avoid them at
all costs.
Thanks to both of you,
Rob
-----Original Message-----
From: Jack Hamilton [mailto:JackHamilton@firsthealth.com]
Sent: Thursday, December 09, 2004 7:58 PM
To: SAS-L@LISTSERV.UGA.EDU; Rob@ROHRBOUGH-SYSTEMS.COM
Subject: Re: [SAS-L] Assembled Macro Variables
When I follow Dennis's suggestion, I don't get any error messages:
=====
27 %macro one(x);
28 %global one&x;
29 %let one&x=junk;
30 %mend;
31
32 %macro two(x);
33 %put &&one&x;
34 %symdel one&x;
35 %mend;
36
37 %one(test);
38
39 %two(test);
junk
=====
Is "junk" what you wanted to print? I get the same results in 8.2 under
Windows and 9.1.3 under Tru64 Unix.
By the way, it's much easier to follow code when you add meaningful white
space.
--
JackHamilton@FirstHealth.com
Manager, Technical Development
Metrics Department, First Health
West Sacramento, California USA
Coelum, non animum mutant, qui trans mare currunt.
>>> "Rob Rohrbough" <Rob@ROHRBOUGH-SYSTEMS.COM> 12/09/2004 5:49 PM >>>
Dennis,
Thanks, I thought tried every combination of ampersands. Here is what I got
with your suggestion:
1 %macro one(x);
2 %global one&x;
3 %let one&x=junk;
4 %mend;
5 %macro two(x);
6 %put &&one&x;
7 %symdel one&x;
8 %mend;
9 %one(test);
10 %two(test);
junk
WARNING: Attempt to delete macro variable ONE failed. Variable not found.
ERROR: Macro variable name & must start with a letter or underscore.
WARNING: Attempt to delete macro variable X failed. Variable not found.
11 %put &onetest;
junk
12 %symdel onetest;
It appears that the reference in the %PUT statement works. However, what
works for the &GLOBAL and &LET statements does not work for the %SYMDEL
statement. I would expect the same syntax to work for the &SYMDEL statement
since the ampersand is not required in any of the three statements. I don't
know if this is intended behavior or if SI just made a mistake implementing
the newer statement. I will put the question to the Institute.
Thanks again,
Rob
-----Original Message-----
From: Dennis Diskin [mailto:diskin@snet.net]
Sent: Thursday, December 09, 2004 6:32 PM
To: Rob Rohrbough; SAS-L@LISTSERV.UGA.EDU
Subject: Re: Assembled Macro Variables
Hi Rob,
I've often gotten confused myself, but I think your problem is in the
%put &one&&x;
You should use
%put &&one&x;
to generate the indirect reference. Thgik of it as &(&one&x) although the
parens won't work.
HTH,
Dennis Diskin
Rob Rohrbough <Rob@ROHRBOUGH-SYSTEMS.COM> wrote:
Here is one for you macro mavens:
I would like to pass a value from one macro to another in a global macro
variable generated with a parameter the user passes. Thankfully I can
generate the macro variable. However, I can read it only via a SYMGET
function from a datastep in the second macro. I will show you two logs, the
first of which works as a work-around:
23 %macro one(x);
24 %global one&x;
25 %local onotes;
26 %let onotes=%sysfunc(getoption(notes, keyword));
27 options nonotes;
28 data _null_;
29 call symput("one&x", "junk");
30 run;
31 options &onotes;
32 %mend;
33 %macro two(x);
34 %local onotes;
35 %let onotes=%sysfunc(getoption(notes, keyword));
36 options nonotes;
37 data _null_;
38 length x $10;
39 x = symget("one&x");
40 put x=;
41 run;
42 options &onotes;
43 %mend;
44 %one(test);
45 %two(test);
X=junk
Notice that I can assemble the name not only in the datastep call routine
and function, but also in the %GLOBAL statement. Without being able to
assemble it in the %GLOBAL statement, I do not believe this would work; the
first datastep would produce a local macro variable. I hope that still works
in v9! Here is what I would like to be able to do:
61 %macro one(x);
62 %global one&x;
63 %let one&x=junk;
64 %mend;
65 %macro two(x);
66 %put &one&&x;
67 %symdel one&x;
68 %mend;
69 %one(test);
70 %two(test);
WARNING: Apparent symbolic reference ONE not resolved.
&onetest
WARNING: Attempt to delete macro variable ONE failed. Variable not found.
ERROR: Macro variable name & must start with a letter or underscore.
WARNING: Attempt to delete macro variable X failed. Variable not found. 71
%put &onetest; junk 72 %symdel onetest;
As you can see, syntax similar to the %GLOBAL statement works for the %LET
statement. However, I cannot come up with syntax that works to reference the
generated variable in the %PUT and %SYMDEL statements. As you can see from
the hard-coded %PUT and %SYMDEL statements in open code, the macro
definition worked. However, to generalize the second macro, I cannot
hard-code the global macro variable name. Can you help?
TIA,
Rob
Rob Rohrbough, Consultant Rohrbough Systems Design, Inc.
SAS Certified Professional V6/V8 A SAS Alliance Consulting Partner
robREMOVECAPS@FORNOSPAMrohrbough-systems.com Omaha, NE
"MMS <firsthealth.com>" made the following annotations.
----------------------------------------------------------------------------
--
This message, including any attachments, is intended solely for the use of
the named recipient(s) and may contain confidential and/or privileged
information. Any unauthorized review, use, disclosure or distribution of
this communication(s) is expressly prohibited. If you are not the intended
recipient, please contact the sender by reply e-mail and destroy any and all
copies of the original message. Thank you.
===========================================================================
==