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;
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.
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?
%do i=2 %to 3;
&setnm = put(i, z2.) || '08' ;
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:
I think what you are trying to do might need to look more like:
%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 */
%end; /*i loop*/
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!