Перейти до вмісту

BAdIs — розширення через Business Add-Ins

BAdI (Business Add-In) — обʼєктно-орієнтований механізм розширення SAP-функціоналу без модифікації вихідного коду. У enhancement spot SAP (або власному) розміщується BAdI-визначення з інтерфейсом; ти пишеш свій клас, який імплементує цей інтерфейс; у потрібних місцях SAP викликає GET BADI + CALL BADI — і твій код виконується як plug-in.

Ця сторінка про kernel-based BAdI — сучасний варіант, інтегрований у мову ABAP і доступний у тому числі у released API-каталозі для ABAP Cloud. Legacy classic BAdI (SE18/SE19) не розглядаємо — вони тільки у Standard ABAP і вважаються застарілими.

КомпонентПризначення
Enhancement spotКонтейнер для BAdI-визначень
BAdI definitionОпис розширення: імʼя, інтерфейс, фільтри, single/multiple use
BAdI interfaceІнтерфейс з методами, які реалізують плагіни (обовʼязково включає IF_BADI_INTERFACE)
Fallback class(Опц.) Клас-заглушка, якщо жодна реалізація не підходить (тільки для single-use)
Enhancement implementationКонтейнер для конкретних реалізацій
BAdI implementationЗвʼязка BAdI + клас-реалізатор + значення фільтра
Implementation classКлас, що імплементує BAdI-інтерфейс
  • Single use / Multiple use — скільки реалізацій можуть виконатись одночасно.
    • Single: одна реалізація на internal session. Якщо жодна не підійшла — викликається fallback.
    • Multiple: кілька реалізацій виконуються послідовно. Обмеження — методи не можуть мати RETURNING/EXPORTING-параметри (тільки IMPORTING і CHANGING).
  • Фільтри — різні реалізації для різних значень (напр., для різних країн, типів документу). Тип фільтра — примітивний (char, int).
  • Інстанціювання — new instance кожного виклику, reuse, або context-dependent (з IF_BADI_CONTEXT).

Enhancement spot ZES_DEMO, BAdI ZBADI_DEMO, інтерфейс ZIF_DEMO з методом calculate:

INTERFACE zif_demo
PUBLIC.
INTERFACES if_badi_interface. " обовʼязково
METHODS calculate IMPORTING num1 TYPE i
num2 TYPE i
RETURNING VALUE(result) TYPE string.
ENDINTERFACE.

Клас-реалізатор:

CLASS zcl_demo_sub DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_badi_interface.
INTERFACES zif_demo.
ENDCLASS.
CLASS zcl_demo_sub IMPLEMENTATION.
METHOD zif_demo~calculate.
result = |{ num1 - num2 }|.
ENDMETHOD.
ENDCLASS.

У BAdI implementation реєструємо клас zcl_demo_sub з filter value '-'. Аналогічно робимо zcl_demo_div з фільтром '/' тощо.

GET BADI — створити BAdI-обʼєкт

Section titled “GET BADI — створити BAdI-обʼєкт”
DATA badi TYPE REF TO zbadi_demo.
" Без фільтрів (multiple use без фільтрів)
GET BADI badi.
" З фільтром
GET BADI badi FILTERS operator = '-'.

Статичний варіант — TYPE REF TO <badi>. Динамічний — через CL_BADI_BASE:

DATA badi_dyn TYPE REF TO cl_badi_base.
DATA(badi_name) = 'ZBADI_DEMO'.
GET BADI badi_dyn TYPE (badi_name) FILTERS operator = '-'.

Або з filter-table (коли фільтрів багато або динамічно):

DATA(filter_tab) = VALUE badi_filter_bindings(
( name = 'OPERATOR' value = NEW char1( '/' ) ) ).
GET BADI badi_dyn TYPE (badi_name) FILTER-TABLE filter_tab.

CALL BADI — викликати метод

Section titled “CALL BADI — викликати метод”
" Статично
CALL BADI badi->calculate
EXPORTING
num1 = 10
num2 = 3
RECEIVING
result = DATA(res).
" Динамічно — імʼя методу в дужках
DATA(method) = 'CALCULATE'.
CALL BADI badi_dyn->(method)
EXPORTING
num1 = 10
num2 = 3
RECEIVING
result = res.
" З parameter-table
DATA(ptab) = VALUE abap_parmbind_tab(
( name = 'NUM1' kind = cl_abap_objectdescr=>exporting value = NEW i( 10 ) )
( name = 'NUM2' kind = cl_abap_objectdescr=>exporting value = NEW i( 3 ) )
( name = 'RESULT' kind = cl_abap_objectdescr=>returning value = REF #( res ) ) ).
CALL BADI badi_dyn->(method) PARAMETER-TABLE ptab.

При GET BADI:

  1. Шукаються активні BAdI implementation classes, прикріплені до BAdI.
  2. Фільтруються за filter values (якщо є).
  3. Якщо знайдено — створюється instance відповідного класу.
  4. Якщо single-use і нічого не підійшло — створюється instance fallback class (якщо оголошений).
  5. Якщо multiple-use і нічого — BAdI reference залишається «порожнім», наступний CALL BADI нічого не робить (без exception).

Типові catchable exceptions:

ExceptionКоли
CX_BADI_FILTER_ERRORФільтр не заданий, коли обовʼязковий; некоректний filter type
CX_BADI_INITIAL_REFERENCECALL BADI на single-use BAdI reference, який ініціалізовано у CLEAR
CX_SY_DYN_CALL_ILLEGAL_METHODНевідоме імʼя методу у динамічному виклику
CX_SY_DYN_CALL_PARAM_MISSINGБракує параметра у динамічному виклику

Для BTP ABAP Environment / ABAP Cloud:

  • api.sap.comExplore → Categories → Business Add-Ins (BAdIs).
  • У ADT: Released Objects view → фільтр Type: BAdI.
  • Документація на SAP Help Portal.

Використовуй тільки ті BAdI, що мають Use in Cloud Development (C1).

DATA badi TYPE REF TO zbadi_demo.
" single-use з fallback
GET BADI badi FILTERS operator = '-'.
CALL BADI badi->calculate
EXPORTING num1 = 10 num2 = 8
RECEIVING result = DATA(result).
" result = '2' (виконався zcl_demo_sub)
" Тепер із неіснуючим фільтром — спрацює fallback (addition)
GET BADI badi FILTERS operator = '?'.
CALL BADI badi->calculate
EXPORTING num1 = 3 num2 = 2
RECEIVING result = result.
" result = '5' (fallback: addition)

Адаптовано з 35_BAdIs.md (Apache 2.0).