BookmarkSubscribeRSS Feed
deleted_user
Not applicable
Hello --

Can anyone confirm how the system should be valuing the "setnm" macro variable below? What I expect to happen is "setnm" = 0208. Instead what appears to be happening is "setnm" = 0308. I'm not sure how this result is occurring from the code below. "Setnm" is a macro variable containing part of the dataset name.

Any ideas are appreciated. Thanks

do i = 2 to 2;
i_str = put(i, z2.) || '08';
call symput('setnm', i_str);
yrmonvalue = '2008' || put(i, z2.);
call execute ("data sue.comm;
set alex.comm&setnm;
...
17 REPLIES 17
deleted_user
Not applicable
I've fixed part of my problem. Now the issue I'm facing is that the "setnm" variable doesn't seem to change when "i" increases from 2 to 3 below.

I have a "DO" loop embedded in a _null_ data step. Included in the loop is a "call execute." I'm trying to have the "call execute" step run for each value of "i" as "i" increases in the loop.

data _null_;
do i = 2 to 3;
format i z2.;
i_str = put(i, z2.) || '08';
call symput('setnm', i_str);
call execute ("data sue.comm;
set alex.comm&setnm;
... etc.
sbb
Lapis Lazuli | Level 10 sbb
Lapis Lazuli | Level 10
Add something to your DATA step like PUTLOG _ALL_; to dump SAS variables with each DATA step pass. The SYMPUT is executing with each DATA step pass, but if you read the CALL EXECUTE discussion, it states that the code is not compiled until after the DATA step is finished. You will need to generate %LET statements to set the macro variable value, instead of the CALL SYMPUT approach. Then you will see the "generated" SAS code compiled and executed after completing your first DATA step.

Of course, another approach would be to output the SAS code to a "temp" FILENAME allocation using PUT statements, and then %INCLUDE the temp file "fileref". Less smoke-and-mirrors occurring that way.

Scott Barry
SBBWorks, Inc.
deleted_user
Not applicable
Thanks for that feedback Scott. What if I embed the DO loop within a macro? Essentially what I want to do is loop through dataset names and do some actions to each dataset. The dataset names are derivable from the loop counter.

So far I've started the following but getting errors. The "&setnm" statement is out of order, the log says. I know I could use a %let statement, but I need to use the loop counter to set the "setnm." Not sure how I could do that with a %let statement since it would have to be outside the loop? Or not?


%macro sortdata;
%do i=2 %to 3;
&setnm = put(i, z2.) || '08' ;
data work.comm;
set alex.comm&setnm;
sbb
Lapis Lazuli | Level 10 sbb
Lapis Lazuli | Level 10
Yes, it is possible with MACRO language - if you are comfortable with the language and can code/support it to suit your needs. The %LET assignment statement assigns a value which can then be used with ampersand substitution.

For the max diagnostics output, add to your SAS program the following line:

OPTIONS SOURCE SOURCE2 MACROGEN SYMBOLGEN MLOGIC;

Here's a SAS-hosted DOC link on the SAS support http://support.sas.com/ website:

SAS 9.2 Macro Language: Reference
http://support.sas.com/documentation/cdl/en/mcrolref/61885/HTML/default/titlepage.htm

Macro Language Elements
http://support.sas.com/documentation/cdl/en/mcrolref/61885/HTML/default/a002047059.htm


My suggestion is that you work with the DATA step approach, as previously commented.

Scott Barry
SBBWorks, Inc.
ballardw
Super User
I think what you are trying to do might need to look more like:

%macro sortdata;
%do i=2 %to 3;
%let setnm = %sysfunc(putn(&i, z2.))08;
/* the line above calls put to get the formatted value you want but you need */
/* to explicitly state you are putting a number. With the macro language the*/
/* concatenation is implicit, not explicit (unless you want to use a function */
/* so no spaces after the first part that resolves as needed using %sysfunc */
data work.comm;
set alex.comm&setnm;
...
run;
%end; /*i loop*/
deleted_user
Not applicable
Thanks much, ballardw, for your tip. I will try that out.

One last note on this thread Re: something Scott Barry said:

Will the %include statement execute with each loop iteration if I embed %include in a DO loop, which in turn is embedded in a data step? Or will the %include only execute AFTER the data step's DO loop is finished, even though %include is within the DO loop itself? The latter result is what happened with my "call execute" attempt, and I'm wondering if %include works the same way. I find that behavior misleading because there is nothing in the log that alerts you to the fact.

The SAS documentation is so lengthy that sometimes it's hard to find answers to specific processing questions. I did try to do my due diligence!

Thanks everyone --
deleted_user
Not applicable
ballardw -- FYI, I still get an error on the "set" statement.

Below is my code. How very frustrating! Side note: "alex" is a libname reference.

%macro sortdata;
%do i=2 %to 3;
%let setnm = %sysfunc(putn(&i, z2.))08;
data work.comm;
set alex.comm&setnm;
sbb
Lapis Lazuli | Level 10 sbb
Lapis Lazuli | Level 10
Again, use a DATA step approach to generate your SAS code with PUT statements out to a TEMP allocated FILENAME, and then %INCLUDE that once -- no macro coding at all.

Scott Barry
SBBWorks, Inc.
ballardw
Super User
What is the text of the error message?
Flip
Fluorite | Level 6
data _null_;
do i=2 to 3;
setnm = compress ('alex.comm'|| put(i, z2.) || '08') ;
call execute('data work.comm;');
call execute('set ' || setnm || ';');
call execute('run;');
end;
run;

Of course you are overwriting work.comm each time. I just rolled out a program with this sort of code using append.
deleted_user
Not applicable
Ballardw, error message is as follows: Statement is not valid or it is used out of proper order.
deleted_user
Not applicable
Although not necessarily related to your error message, it doesn't seem likely to me that you'd want to simply replace work.comm on each iteration.

Did you actually intend to SET multiple data sets into work.comm?

BTW, the last code you pasted wasn't complete (no closing macro %end statement, no %mend statement, etc.)
deleted_user
Not applicable
I was just posting the general concept, not the true code. The code to %mend was not included since the "set" statement was the problem child. Thanks
deleted_user
Not applicable
That's fine, but when I tried to replicate your error message, I did not run into a problem with the SET statement, so there's something "missing".

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

What is Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 17 replies
  • 2148 views
  • 0 likes
  • 5 in conversation