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-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 17 replies
  • 1431 views
  • 7 likes
  • 6 in conversation