EXIT en ABAP: Salir de bucles y subrutinas

Kategorie
ABAP-Statements
Veröffentlicht
Autor
Johannes

EXIT es una sentencia de control que interrumpe la ejecucion del bucle o subrutina actual. El comportamiento depende del contexto en que se usa.

Comportamiento por contexto

ContextoEfecto de EXIT
DO / WHILE / LOOP ATTermina el bucle inmediatamente
FORM (Subrutina)Termina la subrutina
Fuera de bucle/subrutinaNo permitido

Sintaxis

EXIT.

Ejemplos

1. EXIT en bucle DO

DATA: lv_counter TYPE i.
DO 10 TIMES.
lv_counter = sy-index.
IF lv_counter = 5.
EXIT. " Termina el bucle cuando contador = 5
ENDIF.
WRITE: / 'Iteracion:', lv_counter.
ENDDO.
WRITE: / 'Despues del bucle, contador =', lv_counter.
" Salida:
" Iteracion: 1
" Iteracion: 2
" Iteracion: 3
" Iteracion: 4
" Despues del bucle, contador = 5

2. EXIT en bucle WHILE

DATA: lv_sum TYPE i VALUE 0.
WHILE lv_sum < 1000.
lv_sum = lv_sum + 100.
IF lv_sum > 500.
EXIT. " Salir si suma supera 500
ENDIF.
WRITE: / 'Suma actual:', lv_sum.
ENDWHILE.
WRITE: / 'Suma final:', lv_sum.
" Salida:
" Suma actual: 100
" Suma actual: 200
" Suma actual: 300
" Suma actual: 400
" Suma actual: 500
" Suma final: 600

3. EXIT en LOOP AT

DATA: lt_numbers TYPE TABLE OF i,
lv_number TYPE i.
lt_numbers = VALUE #( ( 10 ) ( 20 ) ( 30 ) ( 40 ) ( 50 ) ).
LOOP AT lt_numbers INTO lv_number.
IF lv_number = 30.
EXIT. " Salir cuando se encuentra 30
ENDIF.
WRITE: / 'Numero:', lv_number.
ENDLOOP.
WRITE: / 'Ultimo numero procesado:', lv_number.
" Salida:
" Numero: 10
" Numero: 20
" Ultimo numero procesado: 30

4. EXIT en bucles anidados

DATA: lv_found TYPE abap_bool VALUE abap_false.
DO 5 TIMES.
DATA(lv_outer) = sy-index.
DO 5 TIMES.
DATA(lv_inner) = sy-index.
IF lv_outer = 3 AND lv_inner = 2.
lv_found = abap_true.
EXIT. " Sale SOLO del bucle interno!
ENDIF.
ENDDO.
IF lv_found = abap_true.
EXIT. " Ahora sale del bucle externo
ENDIF.
WRITE: / 'Bucle externo:', lv_outer.
ENDDO.
" Salida:
" Bucle externo: 1
" Bucle externo: 2

5. EXIT en FORM (Subrutina)

PERFORM process_data.
WRITE: / 'Despues de PERFORM'.
FORM process_data.
WRITE: / 'Inicio del procesamiento'.
IF sy-datum < '20240101'.
WRITE: / 'Fecha invalida'.
EXIT. " Sale de la subrutina
ENDIF.
WRITE: / 'Procesando datos...'.
WRITE: / 'Fin del procesamiento'.
ENDFORM.

6. Buscar en tabla con EXIT

TYPES: BEGIN OF ty_customer,
id TYPE i,
name TYPE string,
city TYPE string,
END OF ty_customer.
DATA: lt_customers TYPE TABLE OF ty_customer,
ls_found TYPE ty_customer.
lt_customers = VALUE #(
( id = 1 name = 'Muller' city = 'Berlin' )
( id = 2 name = 'Schmidt' city = 'Munich' )
( id = 3 name = 'Weber' city = 'Hamburg' )
).
" Buscar cliente de Munich
LOOP AT lt_customers INTO DATA(ls_customer).
IF ls_customer-city = 'Munich'.
ls_found = ls_customer.
EXIT. " Encontrado, salir del bucle
ENDIF.
ENDLOOP.
IF ls_found IS NOT INITIAL.
WRITE: / 'Encontrado:', ls_found-name.
ENDIF.

7. EXIT vs. CHECK vs. CONTINUE vs. RETURN

" EXIT - termina el bucle completamente
DO 10 TIMES.
IF sy-index = 5.
EXIT. " Sale del bucle, no ejecuta mas iteraciones
ENDIF.
ENDDO.
" CHECK - salta la iteracion actual si condicion es falsa
DO 10 TIMES.
CHECK sy-index MOD 2 = 0. " Solo numeros pares
WRITE: / sy-index. " 2, 4, 6, 8, 10
ENDDO.
" CONTINUE - salta al siguiente ciclo
DO 10 TIMES.
IF sy-index = 5.
CONTINUE. " Salta solo la iteracion 5
ENDIF.
WRITE: / sy-index. " 1,2,3,4,6,7,8,9,10
ENDDO.
" RETURN - sale del metodo/procedimiento completo
METHOD my_method.
DO 10 TIMES.
IF error_found.
RETURN. " Sale del metodo, no solo del bucle
ENDIF.
ENDDO.
" Este codigo no se ejecuta si RETURN ocurrio
cleanup( ).
ENDMETHOD.

8. Patron de busqueda con variable de control

DATA: lv_found TYPE abap_bool VALUE abap_false,
lv_idx TYPE i.
LOOP AT lt_items INTO DATA(ls_item).
lv_idx = sy-tabix.
IF ls_item-status = 'ERROR'.
lv_found = abap_true.
EXIT.
ENDIF.
ENDLOOP.
IF lv_found = abap_true.
WRITE: / 'Error encontrado en posicion:', lv_idx.
ELSE.
WRITE: / 'No se encontraron errores'.
ENDIF.

9. EXIT en SELECT…ENDSELECT

DATA: lv_count TYPE i.
SELECT * FROM sflight
INTO @DATA(ls_flight).
lv_count = lv_count + 1.
IF lv_count >= 10.
EXIT. " Detener despues de 10 registros
ENDIF.
WRITE: / ls_flight-carrid, ls_flight-connid.
ENDSELECT.

10. Pattern: Salida temprana con validacion

METHOD process_order.
" Validaciones con salida temprana usando IF
IF iv_order_id IS INITIAL.
ev_error = 'ID de pedido requerido'.
RETURN.
ENDIF.
IF iv_quantity <= 0.
ev_error = 'Cantidad debe ser positiva'.
RETURN.
ENDIF.
" Procesamiento principal (solo si validaciones pasaron)
" ...
ENDMETHOD.

Comparacion

SentenciaEn bucleEn FORMEn METHOD
EXITTermina bucleTermina FORMTermina bucle
RETURNTermina metodoTermina FORMTermina metodo
CONTINUESiguiente iteracionN/ASiguiente iteracion
CHECK condSiguiente si falsoTermina si falsoSiguiente si falso

Notas importantes / Mejores practicas

  • EXIT solo afecta al bucle mas interno en bucles anidados.
  • En FORM, EXIT funciona como RETURN (termina la subrutina).
  • Usar EXIT para busquedas - no procesar mas cuando se encuentra.
  • Preferir expresiones de tabla o READ TABLE sobre LOOP + EXIT para busquedas simples.
  • EXIT fuera de bucle o subrutina causa error de sintaxis.
  • Para salir de multiples bucles anidados, usar variables de control o reestructurar.
  • En codigo moderno, considerar RETURN en metodos en lugar de EXIT.