Search code examples
loopsnested-loopsabap

Continuing the most outer loop from the most nested one


Is there a way to continue the most outer loop from the most nested one in ABAP?

Example in Java. There is a construct in this language using labels (most people do not know of it anyway) which allows me to continue the most outer loop from the nested one.

public class NestedLoopContinue {
    public static void main(String[] args) {    
        label1: for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 2; j++) {
                if (i == 3) {
                    continue label1;
                }
            }
            System.out.println(i + 1);
        }
    }
}

This outputs

1
2
3
5

Now, how can I do it in ABAP in a smart way? One solution would be to use TRY. ENDTRY. block but it is rather a hacking one. Any other ideas?

DATA: l_outer_counter TYPE i.
DO 5 TIMES.
  l_outer_counter = sy-index.
  TRY.
    DO 2 TIMES.
      IF l_outer_counter = 4.
        RAISE EXCEPTION TYPE cx_abap_random.
      ENDIF.
    ENDDO.
    WRITE / l_outer_counter.
    CATCH cx_abap_random.
      CONTINUE.
  ENDTRY.
ENDDO.

Or maybe there is a way to tell whether the DO. ENDO. ended with an EXIT statement (without introducing an own variable of course, like SYST global variable)?

DATA: l_outer_counter TYPE i.
DO 5 TIMES.
  l_outer_counter = sy-index.
  DO 2 TIMES.
    IF l_outer_counter = 4.
      EXIT.
    ENDIF.
  ENDDO.
  IF sy-last_loop_ended_with_exit = abap_true. "???
    CONTINUE.
  ENDIF.
  WRITE / l_outer_counter.
ENDDO.

Solution

  • When working with nested loops, I often find the best way to improve readability, and avoid using more unusual approaches (such as breaking to a label, which is not only controversial because of its goto-like nature, but also reduces readability because a lot of people are not familiar with them) is to extract the inner loop into a separate function. I do not know how this is done in ABAP, but the refactored Java equivalent would be:

    public class NestedLoopContinue {
    
        public static void main(String[] args) {
            for (int i = 0; i < 5; i++) {
                NestedLoopContinue.innerLoop(i)
            }
        }
    
        static void innerLoop(int i) {
            for (int j = 0; j < 2; j++) {
                if (i == 3) {
                    return;
                }
            }
            System.out.println(i + 1);
        }
    }
    

    I would argue that in this example, this actually becomes less readable because it is harder to follow the logic across the two methods. However, if this was a real-world example (where the methods and variables had some actual meanings and appropriate names to go with them), then the result of extracting the inner loop into a separate method would be more readable than using a label.