BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Ronein
Meteorite | Level 14

Hello

I want to create series of macro variables in form YYMM  from 2 months before &start until &end

In this example start=1901  end=1903 so I want to create series of macro varaibles:

m0=1811

m1=1812

m2=1901

m3=1902

m4=1903

However, in the following code I get all macro parameter values equal 1903.

What is the mistake in the logic please?

 

%let start=1901;
%let end=1903;


%let date_start=%sysfunc(inputn(&start.,yymmn4.));
%let date_end=%sysfunc(inputn(&end.,yymmn4.));
%put &date_start.  ;/*21550*/
%put &date_end. ; /*21609*/


data _null_;
n1=intck('month',&date_start.,&date_end.);
n2=n1+2;
call symput("n1",trim(left(n1)));
call symput("n2",trim(left(n2)));
run;
%put &n1;
%put &n2;

%macro months;
%do i=-2 %to &n1.;
%do j=0 %to &n2.;
m&j.=put(intnx('month',&date_start.,&i.),yymmn4.);
call symput("m&j",trim(left(m&j.)));
%end;
%end;
%mend;

data aaa;
%months;
run;

%put &&m&n2;
%put &m0;
1 ACCEPTED SOLUTION

Accepted Solutions
Kurt_Bremser
Super User

You are massively overcomplicating things by abusing the poor macro processor.

Such things are easily done in one simple data step:

%let start=1901;
%let end=1903;

data control;
start = intnx('month',input("&start",yymmn4.),-2,'b');
end = input("&end.",yymmn4.);
length month $4;
m = 0;
do until (start > end);
  month = put(start,yymmn4.);
  call symputx(cats('M',m),month);
  output;
  m + 1;
  start = intnx('month',start,1,'b');
end;
keep month;
run;

%put &m0 &m1 &m2 &m3 &m4;

proc print data=control noobs;
run;

Log excerpt:

42         %put &m0 &m1 &m2 &m3 &m4;
1811 1812 1901 1902 1903

Result of print:

month

1811 
1812 
1901 
1902 
1903 

I created the dataset because data has to be kept in datasets, not unwieldy macro variable lists. The control dataset can easily be used to create dynamic code with call execute.

View solution in original post

4 REPLIES 4
Kurt_Bremser
Super User

You are massively overcomplicating things by abusing the poor macro processor.

Such things are easily done in one simple data step:

%let start=1901;
%let end=1903;

data control;
start = intnx('month',input("&start",yymmn4.),-2,'b');
end = input("&end.",yymmn4.);
length month $4;
m = 0;
do until (start > end);
  month = put(start,yymmn4.);
  call symputx(cats('M',m),month);
  output;
  m + 1;
  start = intnx('month',start,1,'b');
end;
keep month;
run;

%put &m0 &m1 &m2 &m3 &m4;

proc print data=control noobs;
run;

Log excerpt:

42         %put &m0 &m1 &m2 &m3 &m4;
1811 1812 1901 1902 1903

Result of print:

month

1811 
1812 
1901 
1902 
1903 

I created the dataset because data has to be kept in datasets, not unwieldy macro variable lists. The control dataset can easily be used to create dynamic code with call execute.

Ronein
Meteorite | Level 14

Perfect solution.

Thank you.

I am still interested to know what is the error in my code

 

Kurt_Bremser
Super User

@Ronein wrote:

Perfect solution.

Thank you.

I am still interested to know what is the error in my code

 


Your use of two nested %do loops. When the outer loop reaches 1903, the inner loop overwrites all variables.

Even that logic does not need any macro code at all:

data aaa;
array m {%eval(&n2.+1)} m0-m&n2.;
format m0-m&n2. yymmn4.;
do i = 0 to &n2.;
  m{i+1} = intnx('month',&date_start.,i-2);
end;
drop i;
run;

Maxim 11

Maxim 11

Maxim 11

ballardw
Super User

I believe nearly 2 years ago when you started posting and were using "dates" in this form YYMM I mentioned that actually using a date value and using an appropriate format to display the date would be easier in the long run.

 

I am not sure but I suspect this is at least the 20th post you have regarding manipulating dates in this non-date form.

Note that the first thing you have to do each an every time is build a date value to increment or manipulate things.

 

I have not seen anything where use of YYMM appearing numeric values has made any of your tasks simpler or easier to follow.

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!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

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
  • 4 replies
  • 1122 views
  • 3 likes
  • 3 in conversation