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

Hi,

I am trying to create a loop which runs several programs multiple times using the %include function. These programs all use the macro variable CUST_ID and I would like to change this macro variable for every loop based on a list I specify. This is what I have so far but I can't manage to change the macro variable in the loop. Does anyone know how to do this?

 

/* specify list of values that have to be inserted into a macro variable*/
Data CUST_ID_LIST; input CUST_ID; datalines; 230419732 20476814 49500430 106808266 ; run;
/*calculate the length of the list to determine the number of iterations of the loop*/ proc sql; Select count(*) into: NO_CUST_ID from CUST_ID_LIST; run;
/* do the loop*/ data CUST_ID; do i = 1 to &NO_CUST_ID; set CUST_ID_LIST point = i; output CUST_ID ; %include "Program 1"; %include "Program 2"; %include "Program 3"; %include "Program 4"; end; stop; run;

 

1 ACCEPTED SOLUTION

Accepted Solutions
AMSAS
SAS Super FREQ

I think this example is what you are looking for

First I have 2 simple programs that I'm going to %include (program1.sas & program2.sas):

data _null_ ;
	put "This is program 1 with CUSTID=&custId" ;
run ;
data _null_ ;
	put "This is program 2 with CUSTID=&custId" ;
run ; 

Then I have this

filename inc1 "<path>\program1.sas" ;
filename inc2 "<path>\program2.sas" ;

data customerIds ;
	infile cards ;
	input custId $ ;
	call symput("custId"!!left(putn(_n_,"2.")),custId) ;
	call symput("count",putn(_n_,"2.")) ;
cards ;
Cust#001
Cust#002
;

%macro repeat ;
	%do i=1 %to &count ;
		%let custId=&&custId&i ;
		%include inc1 ;
		%include inc2 ;
	%end ;
%mend repeat ;

%let custId=Customer#001 ;

data _null_ ;
	%repeat ;
run ;

Here's the log:

272  %let custId=Customer 001 ;
273
274  filename inc1 "<Path>\program1.sas" ;
275  filename inc2 "<Path>\program2.sas" ;
276
277  data customerIds ;
278      infile cards ;
279      input custId $ ;
280      call symput("custId"!!left(putn(_n_,"2.")),custId) ;
281      call symput("count",putn(_n_,"2.")) ;
282  cards ;

NOTE: The data set WORK.CUSTOMERIDS has 2 observations and 1 variables.
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.01 seconds


285  ;
286
287  %macro repeat ;
288      %do i=1 %to &count ;
289          %let custId=&&custId&i ;
290          %include inc1 ;
291          %include inc2 ;
292      %end ;
293  %mend repeat ;
294
295  %let custId=Customer#001 ;
296
297  data _null_ ;
298      %repeat ;

NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds



This is program 1 with CUSTID=Cust#001
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.01 seconds



This is program 2 with CUSTID=Cust#001
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds



This is program 1 with CUSTID=Cust#002
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds



This is program 2 with CUSTID=Cust#002
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds


317  run ;

View solution in original post

7 REPLIES 7
PaigeMiller
Diamond | Level 26

I would like to change this macro variable for every loop based on a list I specify.

 

Show us (a representative portion of) the list. Also, where is this list stored? (SAS data set, text file, piece of paper, other?)

--
Paige Miller
Huub
Fluorite | Level 6

Hi,

I create the list in the datastep mentioned in the code:

 

/* specify list of values that have to be inserted into a macro variable*/
Data CUST_ID_LIST;
input CUST_ID;
datalines;
230419732
20476814
49500430
106808266
;
run;
PaigeMiller
Diamond | Level 26

Then I'm lost. Your code takes this list, and computes the value of 4 for macro variable &NO_CUST_ID, and your code should work properly. What is the problem? Please be specific and detailed, instead of assuming we can all see the problem you are seeing.

--
Paige Miller
Huub
Fluorite | Level 6
Ah I'm sorry. I mean the macro variable in the do loop called CUST_ID. Not the variable &NO_CUST_ID. I use &NO_CUST_ID to determine the number of iterations, but i want to change variable CUST_ID for every iteration of the loop, where I replace the value of variable CUST_ID with the value of the list CUST_ID_LIST where the rownumber matches the iteration number. Is this clearer?
PaigeMiller
Diamond | Level 26

@Huub wrote:
Ah I'm sorry. I mean the macro variable in the do loop called CUST_ID. Not the variable &NO_CUST_ID. I use &NO_CUST_ID to determine the number of iterations, but i want to change variable CUST_ID for every iteration of the loop, where I replace the value of variable CUST_ID with the value of the list CUST_ID_LIST where the rownumber matches the iteration number. Is this clearer?

Not a bit clearer. I still don't know what is wrong with the code you have written, even though I specifically asked that question.

--
Paige Miller
AMSAS
SAS Super FREQ

I think this example is what you are looking for

First I have 2 simple programs that I'm going to %include (program1.sas & program2.sas):

data _null_ ;
	put "This is program 1 with CUSTID=&custId" ;
run ;
data _null_ ;
	put "This is program 2 with CUSTID=&custId" ;
run ; 

Then I have this

filename inc1 "<path>\program1.sas" ;
filename inc2 "<path>\program2.sas" ;

data customerIds ;
	infile cards ;
	input custId $ ;
	call symput("custId"!!left(putn(_n_,"2.")),custId) ;
	call symput("count",putn(_n_,"2.")) ;
cards ;
Cust#001
Cust#002
;

%macro repeat ;
	%do i=1 %to &count ;
		%let custId=&&custId&i ;
		%include inc1 ;
		%include inc2 ;
	%end ;
%mend repeat ;

%let custId=Customer#001 ;

data _null_ ;
	%repeat ;
run ;

Here's the log:

272  %let custId=Customer 001 ;
273
274  filename inc1 "<Path>\program1.sas" ;
275  filename inc2 "<Path>\program2.sas" ;
276
277  data customerIds ;
278      infile cards ;
279      input custId $ ;
280      call symput("custId"!!left(putn(_n_,"2.")),custId) ;
281      call symput("count",putn(_n_,"2.")) ;
282  cards ;

NOTE: The data set WORK.CUSTOMERIDS has 2 observations and 1 variables.
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.01 seconds


285  ;
286
287  %macro repeat ;
288      %do i=1 %to &count ;
289          %let custId=&&custId&i ;
290          %include inc1 ;
291          %include inc2 ;
292      %end ;
293  %mend repeat ;
294
295  %let custId=Customer#001 ;
296
297  data _null_ ;
298      %repeat ;

NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds



This is program 1 with CUSTID=Cust#001
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.01 seconds



This is program 2 with CUSTID=Cust#001
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds



This is program 1 with CUSTID=Cust#002
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds



This is program 2 with CUSTID=Cust#002
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds


317  run ;
Tom
Super User Tom
Super User

If the number of values is small enough that they can fit into a single macro variable (65K bytes) then just modify your PROC SQL step.

 

Unless your %INCLUDE files all contain only statements that can run inside a the single data step you probably need to switch your DO loop to a %DO loop.

proc sql noprint;
select distinct cust_id 
  into :cust_id_list separated by '|'
  from cust_id_list
;
%let no_cust_id = &sqlobs;
quit;

%do index=1 to &no_cust_id;
  %let cust_id = %scan(&cust_id_list,&index,|);
		
%include "Program 1";
%include "Program 2";
%include "Program 3";
%include "Program 4";

%end;

hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!

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
  • 7 replies
  • 2011 views
  • 0 likes
  • 4 in conversation