Previous Page | Next Page

Controlling Program Flow

Using SCL DO Loops

There are four forms of the DO statement:

For more information about DO statements, in addition to the information in this documentation, refer to SAS Language Reference: Dictionary.


DO Statement

The DO statement designates a group of statements that are to be executed as a unit. The simplest form of the DO loop is

DO;
. . .SAS statements. . .
END;
This simple DO statement is often used within IF-THEN/ELSE statements to designate a group of statements to be executed if the IF condition is true. For example, in the following code, the statements between DO and END are performed only when YEARS is greater than 5.
if years>5 then
  do;
    months=years*12;
    put years= months=;
  end;


Iterative DO Loops

The iterative DO loop executes the statements between DO and END repetitively based on the value of an index variable.

DO index-variable = start TO stop <BY increment>;

Note:   In SCL applications, both start and stop are required, and start, stop, and increment must be numbers or expressions that yield a number. The TO and BY clauses cannot be reversed, and start cannot be a series of items separated by commas. You can use only one start TO stop specification (with or without the BY clause) in a DO loop.  [cautionend]

If increment is not specified, then index-variable is increased by 1. If increment is positive, then start must be the lower bound and stop must the be upper bound for the loop. If increment is negative, then start must be the upper bound and stop must be the lower bound for the loop.

The values of index-variable, stop, and increment are evaluated at each iteration of the loop. Any changes made to index-variable, stop, or increment within the DO group can affect the number of times that the loop executes. For example, if you change the value of index-variable inside of the DO group, then index-variable may never equal the value of stop, and the loop will not stop executing.

For more understanding of what DO LOOP elements are updated, examine the following code and the generated output:

INIT: 
  dcl num k=18 n=11; 
    do i=k+2 to n-1 by -2;  
      put i=;   
    end; 
  
  dcl num s=1 e=25;   
    do i = s to e;   
      e = e - 5;   
      s = s + 10;  
      put i= e= s=; 
    end;  
RETURN; 

i=20
i=18
i=16
i=14
i=12
i=10
i=1 e=20 s=11
i=2 e=15 s=21
i=3 e=10 s=31
i=4 e=5 s=41
i=5 e=0 s=51

The following code uses the DOPEN and DNUM functions to execute SAS statements once for each file in the current directory:

rc=filename('mydir','.');
dirid=dopen('mydir');
do i=1 to dnum(dirid);
   ...SAS statements...
end;
rc=dclose(dirid);


Using UNTIL and WHILE Clauses

You can add either an UNTIL clause or a WHILE clause to your DO statements.

DO index-variable = start TO stop <BY increment>
<WHILE (expression)> | <UNTIL (expression)>;
The UNTIL expression is evaluated after the statements in the DO loop have executed, and the WHILE expression is evaluated before the statements in the DO loop have executed. The statements in a DO UNTIL loop are always executed at least once, but the statements in a DO WHILE loop will not execute even once if the DO WHILE expression is false.

If index-variable is still in the range between start and stop, then if you specify an UNTIL clause, the DO group will execute until the UNTIL expression is true. If you specify a WHILE clause, the loop will execute as long as the WHILE expression is true.

The following example uses an UNTIL clause to set a flag, and then it checks the flag during each iteration of the loop:

flag=0;
do i=1 to 10 until(flag);
  ...SAS statements...
  if expression then flag=1;
end;

The following loop executes as long as I is within the range of 10 to 0 and MONTH is equal to JAN.

do i=10 to 0 by -1 while(month='JAN');
   ...SAS statements...
end;


DO WHILE Statement

The DO WHILE statement works like the iterative DO statement with a WHILE clause, except that you do not specify an index-variable or start, stop, or increment.

DO WHILE (expression);
. . .SAS statements. . .
END;
Whether the loop executes is based solely on whether the expression that you specify evaluates to true or false. The expression is evaluated before the loop executes, and if the expression is false, then the loop is not executed. If the expression is false the first time it is evaluated, then the loop will not execute at all.

For example, the following DO loop is executed once for each value of N: 0, 1, 2, 3, and 4.

n=0;
do while(n<5);
  put n=;
  n+1;
end;


DO UNTIL Statement

The DO UNTIL statement works like the iterative DO statement with an UNTIL clause, except that you do not specify an index variable nor start, stop, or increment.

DO UNTIL (expression);
. . .SAS statements. . .
END;

Whether the loop executes is based solely on whether the expression that you specify evaluates to true or false. The loop is always executed at least once, and the expression is evaluated after the loop executes.

For example, the following DO loop is executed once for each value of N: 0, 1, 2, 3, and 4.

n=0;
do until(n>=5);
  put n=;
  n+1;
end;


Controlling DO Loops (CONTINUE and LEAVE)

You can use the CONTINUE and LEAVE statements to control the flow of execution through DO loops.

The CONTINUE statement stops the processing of the current DO loop iteration and resumes with the next iteration of the loop. For example, the following code reads each row in the DEPT table, and if the status is not PT, it displays a frame that enables the user to update the full-time employee's salary.

deptid=open('dept');
call set(deptid);
do while (fetch(deptid) ne -1);
  if (status='PT') then continue;
  newsal=display('fulltime.frame');
end;

The LEAVE statement stops processing the current DO loop and resumes with the next statement after the DO loop. With the LEAVE statement, you have the option of specifying a label for the DO statement:

LEAVE <label>;
If you have nested DO loops and you want to skip out of more than one loop, you can specify the label of the loop that you want to leave. For example, the following LEAVE statement causes execution to skip to the last PUT statement:
myloop: 
do i=1 to 10;
  do j=1 to 10;
    if j=5 then leave myloop;
    put i= j=;
  end;
end;
put 'this statement executes next';
return;
  

In SCL applications, the LEAVE statement can be used only within DO loops, not in SELECT statements (unless it is enclosed in a DO statement).

For more information, refer to CONTINUE, LEAVE, and SAS Language Reference: Dictionary.

Previous Page | Next Page | Top of Page