Керування потоком програми
Потоком ABAP-програми керують три речі: керівні структури (IF, CASE, цикли), виклики процедур (методи, функціональні модулі, підпрограми) і робота з винятками (TRY/CATCH, RAISE). На цій сторінці зібрано основні конструкції і їхні сучасні operand-аналоги (COND, SWITCH).
Логічні вирази
Section titled “Логічні вирази”Умови будуються з порівнянь або предикатів, зʼєднуються операторами NOT, AND, OR. Для AND і OR можна явно дужкувати.
IF num = 1. ENDIF.IF num = 1 AND flag = 'X'. ENDIF.IF ( num = 1 AND flag = 'X' ) OR num = 99. ENDIF.IF num BETWEEN 1 AND 3. ENDIF.IF num IS INITIAL. ENDIF.IF dref IS BOUND. ENDIF. " data reference валіднаIF <fs> IS ASSIGNED. ENDIF. " field symbol присвоєнийIF oref IS INSTANCE OF zcl_child. ENDIF. " тип обʼєктаIF line_exists( itab[ key = val ] ). ENDIF.IF contains( val = txt pcre = `\d+` ). ENDIF.Оператори порівняння мають і символьні, і буквені форми: =/EQ, <>/NE, </LT, >/GT, <=/LE, >=/GE. Сучасний код пише символами.
Предикативний виклик методу
Section titled “Предикативний виклик методу”Функціональний метод у логічному виразі — порівнюється з initial value свого типу:
IF some_method( ). " true, якщо результат != initialIF some_method( ) IS NOT INITIAL. " еквівалент — але довшийBoolean-функції
Section titled “Boolean-функції”xsdbool( ... ) повертає abap_bool (X/' ') від логічного виразу — зручно для присвоєння:
DATA(is_empty) = xsdbool( itab IS INITIAL ).boolc( ... ) повертає string (X/' ') — небезпечний у порівняннях, бо повертає literal ' ' замість initial. У новому коді бери xsdbool.
IF / ELSEIF / ELSE
Section titled “IF / ELSEIF / ELSE”Перевірка послідовно зверху вниз; виконується перший блок, умова якого істинна. Якщо жодна — ELSE (опційний).
IF sy-subrc = 0. " знайденоELSEIF sy-subrc = 4. " не знайденоELSE. " іншеENDIF.Вкладеність можлива, але при 4+ рівнях — час виносити у метод.
COND — IF у виразі
Section titled “COND — IF у виразі”Коли потрібен результат залежно від умови (а не виконання блоку):
DATA(greeting) = COND #( WHEN sy-uzeit < '120000' THEN `Добрий ранок` WHEN sy-uzeit < '180000' THEN `Добрий день` ELSE `Добрий вечір` ).# — тип виводиться з контексту (тут — string). Всі гілки після THEN мають бути приведеними до цільового типу.
CASE / WHEN
Section titled “CASE / WHEN”Дискретне порівняння значення з набором варіантів. WHEN приймає кілька значень через OR:
CASE status. WHEN 'N'. handle_new( ). WHEN 'A' OR 'P'. handle_active_or_pending( ). WHEN OTHERS. handle_unknown( ).ENDCASE.CASE TYPE OF
Section titled “CASE TYPE OF”Спеціальна форма для перевірки типу object reference (RTTI):
DATA(descr) = cl_abap_typedescr=>describe_by_data( obj ).
CASE TYPE OF descr. WHEN TYPE cl_abap_elemdescr. " елементарний WHEN TYPE cl_abap_structdescr. " структура WHEN TYPE cl_abap_tabledescr. " таблиця WHEN OTHERS.ENDCASE.SWITCH — CASE у виразі
Section titled “SWITCH — CASE у виразі”Аналог COND для дискретних випадків:
DATA(label) = SWITCH #( status WHEN 'N' THEN `Новий` WHEN 'A' THEN `Активний` WHEN 'C' THEN `Закритий` ELSE `Невідомий` ).DO — безумовний
Section titled “DO — безумовний”Виконується заданий раз або нескінченно (до EXIT). У тілі доступне sy-index з номером ітерації (починається з 1):
DO 5 TIMES. out->write( sy-index ). " 1..5ENDDO.
DO. " нескінченний — потрібен явний EXIT IF some_condition. EXIT. ENDIF.ENDDO.WHILE — умовний
Section titled “WHILE — умовний”Поки умова істинна. sy-index також заповнюється:
WHILE counter < 10. counter += 1.ENDWHILE.Керування в тілі циклу
Section titled “Керування в тілі циклу”| Оператор | Дія |
|---|---|
EXIT | повний вихід з циклу, програма продовжується після ENDDO/ENDWHILE/ENDLOOP |
CONTINUE | пропустити залишок ітерації, перейти до наступної |
CHECK log_exp | як CONTINUE, але умовно: якщо вираз хибний — пропустити |
DO 10 TIMES. CHECK sy-index MOD 2 = 0. " тільки парні IF sy-index = 8. EXIT. ENDIF. " обробка 2, 4, 6ENDDO.Цикли по таблицях
Section titled “Цикли по таблицях”LOOP AT itab ... ENDLOOP — окрема тема, див. Внутрішні таблиці. На відміну від DO/WHILE, заповнюється sy-tabix (індекс рядка), а не sy-index.
FOR ... IN ... — ітерація як частина constructor expression (VALUE, REDUCE). Дає можливість побудувати таблицю/значення за один вираз замість циклу з APPEND:
DATA(doubled) = VALUE int_tab( FOR n IN nums ( n * 2 ) ).DATA(total) = REDUCE i( INIT s = 0 FOR n IN nums NEXT s = s + n ).Виклик процедур
Section titled “Виклик процедур”Методи класів
Section titled “Методи класів”Сучасний ABAP: вся модуляризація — у методах класів. Синтаксис і деталі — у ООП-сторінці (TBD).
Функціональні модулі
Section titled “Функціональні модулі”Legacy, але досі широко використовується у Standard ABAP (не в ABAP Cloud):
CALL FUNCTION 'SOME_FM' EXPORTING input = value1 IMPORTING output = result EXCEPTIONS not_found = 4 OTHERS = 8.
IF sy-subrc <> 0. " обробкаENDIF.Для class-based exceptions — у TRY/CATCH:
TRY. CALL FUNCTION 'SOME_FM' EXPORTING input = value1 IMPORTING output = result. CATCH cx_some_error INTO DATA(exc). out->write( exc->get_text( ) ).ENDTRY.Динамічний виклик — імʼя FM у змінній + PARAMETER-TABLE:
DATA(fm) = 'SOME_FM'.DATA(params) = VALUE abap_func_parmbind_tab( ( name = 'INPUT' kind = abap_func_exporting value = NEW string( `val` ) ) ( name = 'OUTPUT' kind = abap_func_importing value = NEW string( ) ) ).CALL FUNCTION fm PARAMETER-TABLE params.Subroutines (FORM/PERFORM)
Section titled “Subroutines (FORM/PERFORM)”Застаріла конструкція з доби до ABAP Objects. У новому коді не писати; зустрічається тільки у legacy та у специфічних SAP LUW-сценаріях (PERFORM ... ON COMMIT).
RETURN
Section titled “RETURN”Миттєво виходить з поточної процедури. Для функціональних методів (з RETURNING параметром) — можна повернути вираз одразу:
METHODS multiply IMPORTING a TYPE i b TYPE i RETURNING VALUE(result) TYPE i.
METHOD multiply. RETURN a * b. " еквівалент: result = a * b. RETURN.ENDMETHOD.WAIT UP TO — пауза
Section titled “WAIT UP TO — пауза”Зупиняє виконання на задану кількість секунд:
WAIT UP TO 3 SECONDS.Потрібне рідко — у продакшні майже завжди вказує на архітектурну проблему (polling, race condition). Безпечно у тестах і демо.
Винятки
Section titled “Винятки”Охоплено окремо на сторінці винятків (TBD). Коротко:
TRY. some_risky_op( ). CATCH cx_sy_conversion_no_number INTO DATA(exc). " обробка конкретного типу CATCH cx_root INTO DATA(any_exc). " fallback CLEANUP. " виконається незалежно від того, чи був винятокENDTRY.
" Власне породженняRAISE EXCEPTION TYPE zcx_my_error EXPORTING textid = zcx_my_error=>bad_input.Адаптовано з 13_Program_Flow_Logic.md (Apache 2.0). Повний перелік нюансів — в оригіналі.