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

Hi,

Please help me on this nested do loop issue:-

Below is the code:-

%macro update();

%do i=1 %to 12;

   %do j=9 %to 13;

%if %length(&i)=1 %then %let yr=200&i;

%else yr=20&i;

%if %length(&j)=1 %then %let mon=0&j.;

%else mon=&j.;

%let vname=&yr&mon;

%end;

%end;

%mend;

%update;

Thanks in Advance.

1 ACCEPTED SOLUTION

Accepted Solutions
Astounding
PROC Star

You have already gotten a number of good suggestions here.  Let me draw from them to summarize what you could do:

%macro update;

   %local i j;

   %do i=1 %to 12;

      %do j=9 %to 13;

         %let vname=20%sysfunc(putn(&j,z2))%sysfunc(putn(&i,z2));

      %end;

   %end;

%mend update;

Of course there must be more to your objective than this.  The way the code stands now, each time through the loop &VNAME gets replaced.  So the last value is the only one that could be used.

Good luck.

View solution in original post

17 REPLIES 17
damanaulakh88
Obsidian | Level 7

Ignore the earlier one:- This below is the updated code:-

%macro update();

%do i=9 %to 13;

   %do j=1 %to 12;

%if %length(&i)=1 %then %let yr=200&i;

%else yr=20&i;

%if %length(&j)=1 %then %let mn=0&j.;

%else mn=&j;

%let vname=&yr&mn;

%end;

%end;

%mend;

%update;

Keith
Obsidian | Level 7

You haven't described what issue you are having, however looking at the code I suspect it's where you assign the macro variable vname.

If you want to create a macro variable by combining 2 other macro variables then you need to use a double ampersand at the beginning.

%let vname=&&yr&mn;

damanaulakh88
Obsidian | Level 7

The issue is that it says apprent symbol not resolved.

I want the output as :-

200901

200902

200903

.

.

.

201312

Keith
Obsidian | Level 7

Have you tried the fix I suggested?

I've also just noticed that you've omitted %let from your %else statements.

damanaulakh88
Obsidian | Level 7

Yes, i tried, Its not working !

damanaulakh88
Obsidian | Level 7

%macro update();

data new1;

%do i=9 %to 13;

%do j=1 %to 12;

%if %length(&i)=1 %then %let yr=%eval(200&i);

%else %let yr=%eval(20&i);

%if %length(&j)=1 %then mnth=%str(0&j);

%else %let mnth=%eval(&j);

%let vname=&yr&mnth;

%put &vname.;

%end;

%end;

%mend;

%update;

ERROR:-

201312

NOTE 137-205: Line generated by the invoked macro "UPDATE".

690         mnth=0&j

            ____

            22

ERROR 22-322: Syntax error, expecting one of the following: !, !!, &, *, **, +, -, /, ;, <, <=, <>, =, >, ><, >=, AND, EQ, GE, GT,

              IN, LE, LT, MAX, MIN, NE, NG, NL, NOTIN, OR, ^=, |, ||, ~=. 

201312

201310

201311

132                                                        The SAS System                              09:51 Wednesday, June 5, 2013

201312

NOTE 137-205: Line generated by the invoked macro "UPDATE".

690         mnth=0&j

            ____

            22

ERROR 22-322: Syntax error, expecting one of the following: !, !!, &, *, **, +, -, /, ;, <, <=, <>, =, >, ><, >=, AND, EQ, GE, GT,

              IN, LE, LT, MAX, MIN, NE, NG, NL, NOTIN, OR, ^=, |, ||, ~=. 

691       

Keith
Obsidian | Level 7

Try also using the %strip command when creating the variables, to remove leading and trailing blanks.  When you concatenate numeric variables, SAS converts them to character values (of minimum length 8 I believe), meaning that it will include blanks after the numbers.

You're now missing a %let between %then mnth=.....

damanaulakh88
Obsidian | Level 7

That is ok but can you help me on this part:-

%if %length(&j)=1 %then mnth=%str(0&j);

%else %let mnth=%eval(&j);

As i want to have 0 been appended before a single digit to get 01, 02, 03...likewise..

so that i could append to the year like 200901, 200902..so on...

Hope you understand now!

damanaulakh88
Obsidian | Level 7

%macro update();

data new1;

%do i=9 %to 13;

%do j=1 %to 12;

%if %length(&i)=1 %then %let yr=%eval(200&i);

%else %let yr=%eval(20&i);

%if %length(&j)=1 %then mnth=%str(0&j);

%else %let mnth=%eval(&j);

%let vname=&yr&mnth;

%put &vname.;

%end;

%end;

%mend;

%update;

damanaulakh88
Obsidian | Level 7

This is also not working!

Keith
Obsidian | Level 7

Use the z2. format which will put in the leading zero without having to use the length statement.  Try something like the code below, I've used CATS instead of %strip so that the whole string can be created in 1 go.

(untested)

%let vname=%sysfunc(cats('20',%sysfunc(putn(&i.,z2.)),%sysfunc(putn(&j.,z2.))));

Patrick
Opal | Level 21

Not really sure what you actually want to achieve with your macro code. I hope below will give you some ideas/being of some help.

%macro update();

  data new1;
    %do i=9 %to 13;
      %do j=1 %to 12;
        %if %length(&i)=1 %then
          %let yr=%eval(200&i);
        %else %let yr=%eval(20&i);

        %if %length(&j)=1 %then
          %let mnth=%str(0&j);
        %else %let mnth=%eval(&j);
        %let vname=&yr&mnth;
        %put &vname;
        length yyyymm $6.;
        yyyymm="&vname";
        output;
      %end;
    %end;
  run;

%mend;

%update;

data new2;
  format date yymmn6.;
  date='01jan2009'd;
  length yyyymm $6;

  do until(date>'01dec2013'd);
    yyyymm=put(date,yymmn6.);
    output;
    date=intnx('month',date,1,'b');
  end;
run;

Astounding
PROC Star

You have already gotten a number of good suggestions here.  Let me draw from them to summarize what you could do:

%macro update;

   %local i j;

   %do i=1 %to 12;

      %do j=9 %to 13;

         %let vname=20%sysfunc(putn(&j,z2))%sysfunc(putn(&i,z2));

      %end;

   %end;

%mend update;

Of course there must be more to your objective than this.  The way the code stands now, each time through the loop &VNAME gets replaced.  So the last value is the only one that could be used.

Good luck.

ballardw
Super User

And I wonder why

%do j = 9 %to 13 would be preferable to %do year= 2009 %to 2013 or similar in the first place. The latter has a whole lot better of chance of working if your data ever includes values in the 1900's.

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!

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
  • 17 replies
  • 2174 views
  • 7 likes
  • 6 in conversation