BookmarkSubscribeRSS Feed
twenty7
Obsidian | Level 7

 

 

I'm trying to find a shorter way of creating a range of macro variables with dates

 

the code I would usually use is below but I'm finding this is getting longer and longer as I'm now going back 12 months +

 

DATA _null_;
CALL SYMPUT('THIS_MONTH',PUT(INTNX('Month',today(),0,'b'),monyy.));
CALL SYMPUT('MONTH1',PUT(INTNX('Month',today(),-1,'b'),monyy.));
...
CALL SYMPUT('MONTH26',PUT(INTNX('Month',today(),-1,'b'),monyy.));
run;
%put &THIS_MONTH;
%put &MONTH1;
...
%put &MONTH26;

 

 

I was hoping that the same would be possible using a do loop... something along the lines of 

 

 

data _null_;
do i=1 to i=5;
CALL SYMPUT('MONTH&i',PUT(INTNX('MONTH',today(),-&i.,'b'),monyy.));
end;
run;

%put &MONTH1;
%put &MONTH2;

 

 

the error I get in the log is 

85 data _null_;
86 do i=1 to i=5;
87 CALL SYMPUT('MONTH&i',PUT(INTNX('MONTH',today(),-&i.,'b'),monyy.));
_
386
200
WARNING: Apparent symbolic reference I not resolved.
ERROR 386-185: Expecting an arithmetic expression.
ERROR 200-322: The symbol is not recognized and will be ignored.
 
 
Is this to do with the CALL SYMPUT executing before the 1st iteration of the do loop has completed and therefore not knowing the value of &i?
 
Alternative suggestions would be much appreciated
 
Thank you!

 

3 REPLIES 3
Tom
Super User Tom
Super User

You can use a DO loop, but you need to reference the variable you are looping over when making the macro variable names.

Referencing some undefined macro variable is not going be very helpful.

data _null_;
  do i=1 to 5;
   CALL SYMPUTX(cats('MONTH',i),PUT(INTNX('MONTH',today(),-i,'b'),monyy.));
  end;
run;

Also make sure to use the newer CALL SYMPUTX() function instead of the old CALL SYMPUT() function.  Unless you really NEED to store non macro quoted trailing blanks into your macro variables.

Reeza
Super User
macro variables resolve in double quotes not single quotes.
You can loop, but change the first parameter to :

call symputx(catt('VAR', put(i, z2. -l)) , <your formula>);
ballardw
Super User

@twenty7 wrote:

 

 

I'm trying to find a shorter way of creating a range of macro variables with dates

 

the code I would usually use is below but I'm finding this is getting longer and longer as I'm now going back 12 months +

 

DATA _null_;
CALL SYMPUT('THIS_MONTH',PUT(INTNX('Month',today(),0,'b'),monyy.));
CALL SYMPUT('MONTH1',PUT(INTNX('Month',today(),-1,'b'),monyy.));
...
CALL SYMPUT('MONTH26',PUT(INTNX('Month',today(),-1,'b'),monyy.));
run;
%put &THIS_MONTH;
%put &MONTH1;
...
%put &MONTH26;

 

 

I was hoping that the same would be possible using a do loop... something along the lines of 

 

 

data _null_;
do i=1 to i=5;
CALL SYMPUT('MONTH&i',PUT(INTNX('MONTH',today(),-&i.,'b'),monyy.));
end;
run;

%put &MONTH1;
%put &MONTH2;

 

 

the error I get in the log is 

85 data _null_;
86 do i=1 to i=5;
87 CALL SYMPUT('MONTH&i',PUT(INTNX('MONTH',today(),-&i.,'b'),monyy.));
_
386
200
WARNING: Apparent symbolic reference I not resolved.
ERROR 386-185: Expecting an arithmetic expression.
ERROR 200-322: The symbol is not recognized and will be ignored.
 
 
Is this to do with the CALL SYMPUT executing before the 1st iteration of the do loop has completed and therefore not knowing the value of &i?
 
Alternative suggestions would be much appreciated
 
Thank you!

 


Several problems. A do loop is

do I = 1 to 5;

Not do I=1 to I=5;

 

You do not define a macro variable i. If you paste code and messages from the log the indicator underscore would be under the &i . Data step values aren't referenced with macro &. Second, you are attempting to create a macro variable 'month&i'. Within single quotes the &I would not resolve to values anyway and results in an improper macro variable name.

Solution: create a string variable to hold the macro variable name, build the name and then use that in the call symput

data _null_;
   length mvar $ 10;
   do i=1 to 5;
      mvar=cats('MONTH',i);
      CALL SYMPUTx(mvar,PUT(INTNX('MONTH',today(),-i,'b'),monyy.));
   end;
run;

if you are going to create many of these variables make sure the length of mvar is long enough to hold the longest.

 

 

Recommend using CALL SYMPUTX to prevent odd blanks appearing at the ends of values.

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

Mastering the WHERE Clause in PROC SQL

SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 3 replies
  • 6226 views
  • 6 likes
  • 4 in conversation