BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
MaxiHösi
Calcite | Level 5

Hello forum,

 

i have problems using loop statements outside of a data step.

 

I have this data step and want to run it several times (e.g. 8 times) :

 

data new_data;
      set test;
      first_result = find(number, &start, "i");
run;

My variable is &start and i want to define a macro with a range from e.g. 1-8.

 

I tried it like below, but it doesn't work:

%macro test(start=1, end=8)
     %local start end;
     %let start=&start;
     %let end=&end;
     %do &start %to &end;
            data new_data_&start;
                   set test;
                   first_result = find(number, &start, "i");
           run;
          %let start=&start+1;
     %end;
&mend test;
%test(start=1,end=8);

Thanks for your help in advance.

1 ACCEPTED SOLUTION

Accepted Solutions
Quentin
Super User

The below macro will generate example DATA step code I posted.  Still not sure this is what you want.  But for a test project, it makes sense to play around with this sort of macro looping.

 

data test ;
  input number $2. ;
  cards ;
00
01
12
;

%macro test(start=1, end=8);
  %local i;
  %do i=&start %to &end;
    data new_data_&i;
      set test;
      first_result = find(number, "&i", "i");
    run;
 %end;
%mend test;

options mprint ;
%test(start=1,end=8)
The Boston Area SAS Users Group (BASUG) is hosting our in person SAS Blowout on Oct 18!
This full-day event in Cambridge, Mass features four presenters from SAS, presenting on a range of SAS 9 programming topics. Pre-registration by Oct 15 is required.
Full details and registration info at https://www.basug.org/events.

View solution in original post

10 REPLIES 10
LinusH
Tourmaline | Level 20

The syntax for macro do loops:

%do var=start %to end;

%do i = &start %to &end;
Data never sleeps
MaxiHösi
Calcite | Level 5
Thx, but when i correct it, the code still runs just one time. The error sais "ERROR 180-322: Statement is not valid or it is used out of proper order" and something that the rows and columns couldnt't be found.
LinusH
Tourmaline | Level 20

Please post the log with

options mlogic mprint symbolgen;
Data never sleeps
MaxiHösi
Calcite | Level 5

      

 73         options mlogic mprint symbolgen;

74        

 75         %macro test (start=1, end=8);

76         %local start end;

77         %let start=&start;

78         %let end=&end;

79         %do i = &start %to &end;

80         data new_data_&start.;

81          set test;

82          first_result = find(number, &start, "i");

83         run;

84         &let start=&start+1;

85         %end;

86         %mend test;

87         %test(start=1, end=8);

MLOGIC(TEST):  Ausführung beginnt.

MLOGIC(TEST):  Parameter START besitzt Wert 1

MLOGIC(TEST):  Parameter END besitzt Wert 8

MLOGIC(TEST):  %LOCAL  START END

MLOGIC(TEST):  %LET (Variablenname ist START)

SYMBOLGEN:  Makrovariable START wird in 1 aufgelöst

MLOGIC(TEST):  %LET (Variablenname ist END)

SYMBOLGEN:  Makrovariable END wird in 8 aufgelöst

SYMBOLGEN:  Makrovariable START wird in 1 aufgelöst

SYMBOLGEN:  Makrovariable END wird in 8 aufgelöst

MLOGIC(TEST):  %DO Schleife startet; Indexvariable I; Startwert 1; Stoppwert 8; By-Wert 1. 

 SYMBOLGEN:  Makrovariable START wird in 1 aufgelöst

MPRINT(TEST):   data new_data_1;

MPRINT(TEST):   set test;

SYMBOLGEN:  Makrovariable START wird in 1 aufgelöst

MPRINT(TEST):   first_result = find(number, 1, "i");

MPRINT(TEST):   run;

 NOTE: Numeric values have been converted to character values at the places given by: (Line):(Column).

       11578:63   1:2       

 NOTE: Komprimierung für Datei WORK.NEW_DATA_1 deaktiviert, da Komprimierungsoverhead Dateigröße erhöhen würde.

NOTE: There were 100 observations read from the data set WORK.TEST.

NOTE: The data set WORK.NEW_DATA_1 has 100 observations and 3 variables.

NOTE:  Verwendet wurde: DATA statement - (Gesamtverarbeitungszeit):

       real time           0.01 seconds

       cpu time            0.00 seconds

      

 

 WARNING: Apparent symbolic reference LET not resolved.

180: ZEILE und SPALTE können nicht ermittelt werden.

NOTE: NOSPOOL is on. Rerunning with OPTION SPOOL might allow recovery of the LINE and COLUMN where the error has occurred.

ERROR 180-322: Statement is not valid or it is used out of proper order.

SYMBOLGEN:  Makrovariable START wird in 1 aufgelöst

MPRINT(TEST):   &let start=1+1;

 MLOGIC(TEST):  %DO Schleife Indexvariable I ist jetzt 2; Schleife wird wiederholt.

SYMBOLGEN:  Makrovariable START wird in 1 aufgelöst

MPRINT(TEST):   data new_data_1;

MPRINT(TEST):   set test;

SYMBOLGEN:  Makrovariable START wird in 1 aufgelöst

MPRINT(TEST):   first_result = find(number, 1, "i");

MPRINT(TEST):   run;

 NOTE: Numeric values have been converted to character values at the places given by: (Line):(Column).

       11583:64   1:2       

 NOTE: Komprimierung für Datei WORK.NEW_DATA_1 deaktiviert, da Komprimierungsoverhead Dateigröße erhöhen würde.

NOTE: There were 100 observations read from the data set WORK.TEST.

NOTE: The data set WORK.NEW_DATA_1 has 100 observations and 3 variables.

NOTE:  Verwendet wurde: DATA statement - (Gesamtverarbeitungszeit):

LinusH
Tourmaline | Level 20
Remove the code in line 84, it's no needed, the %do will augment &I automatically for each loop.
You now have a working loop.
Then it looks like you have data type problem, is your variable "number" character or numeric?
You can also skip the "i" modifier since you are only looking for numbers.
Also, you need to replace the &start in the function call with &i.
Data never sleeps
Quentin
Super User

When writing a macro, often it's helpful to start by writing working SAS code with no macro statements.  Then after you have that, you can work on writing a macro to generate that code.  I know your loop would run 8 times, but if you were going to write two DATA steps without any macro code, what would they look like? Something like:

 

data new_data_1;
  set test;
  first_result = find(number, "1", "i");
run;

data new_data_2;
  set test;
  first_result = find(number, "2", "i");
run;

?

 

I think the above is syntactically correct, but I doubt it's what you want.  It would make sense if your goal is to search a character variable named NUMBER, to see if it has a "1" or a "2" in it.

 

Before worrying about writing a macro, can you provide a small amount of example data, ideally a DATA step with the CARDS statement to make work.test? And also provide the DATA step code that is working to make the dataset you want. Also describe big picture / goal (what are you doing? why do you want to make 8 datasets?)

 

The Boston Area SAS Users Group (BASUG) is hosting our in person SAS Blowout on Oct 18!
This full-day event in Cambridge, Mass features four presenters from SAS, presenting on a range of SAS 9 programming topics. Pre-registration by Oct 15 is required.
Full details and registration info at https://www.basug.org/events.
MaxiHösi
Calcite | Level 5

If i am going to write two DATA steps without any macro code, it would exactly look like yours. It's exactly what i want. In the test-Data are just numbers and letters. Yet it's just a test project for me.

Quentin
Super User

The below macro will generate example DATA step code I posted.  Still not sure this is what you want.  But for a test project, it makes sense to play around with this sort of macro looping.

 

data test ;
  input number $2. ;
  cards ;
00
01
12
;

%macro test(start=1, end=8);
  %local i;
  %do i=&start %to &end;
    data new_data_&i;
      set test;
      first_result = find(number, "&i", "i");
    run;
 %end;
%mend test;

options mprint ;
%test(start=1,end=8)
The Boston Area SAS Users Group (BASUG) is hosting our in person SAS Blowout on Oct 18!
This full-day event in Cambridge, Mass features four presenters from SAS, presenting on a range of SAS 9 programming topics. Pre-registration by Oct 15 is required.
Full details and registration info at https://www.basug.org/events.
MaxiHösi
Calcite | Level 5

Your code was exactly what i want and it works well. Thanks a lot. 🙂

 

Reeza
Super User

Just a note that when you do this:

    data new_data_&i;
      set test;

Your starting point is always TEST so that your data from the previous iteration does not affect the new iteration. Sometimes that is what you want and sometimes it's not. 

 

  • Parameters within a macro by definition are local, so defining them as local and re-assigning is redundant
  • For the FIND function, put the second parameter in quotes as FIND requieres character/string parameters
  • DO loop needs to be fixed as others have suggested.

 

%macro test(start=, end=)
     %do i = &start %to &end;
            data new_data_&i;
                   set test;
                   first_result = find(number, "&i", "i");
           run;
     %end;
%mend test;
%test(start=1,end=8);

@MaxiHösi wrote:

Hello forum,

 

i have problems using loop statements outside of a data step.

 

I have this data step and want to run it several times (e.g. 8 times) :

 

data new_data;
      set test;
      first_result = find(number, &start, "i");
run;

My variable is &start and i want to define a macro with a range from e.g. 1-8.

 

I tried it like below, but it doesn't work:

%macro test(start=1, end=8)
     %local start end;
     %let start=&start;
     %let end=&end;
     %do &start %to &end;
            data new_data_&start;
                   set test;
                   first_result = find(number, &start, "i");
           run;
          %let start=&start+1;
     %end;
&mend test;
%test(start=1,end=8);

Thanks for your help in advance.


 

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

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
  • 10 replies
  • 1694 views
  • 1 like
  • 4 in conversation