Hi community,
I would like to share with you some functionality I used in my last S/4HANA 2022 Assetmanagement Project to prevent the WDA-App for maintaining orders (EAMS_WDA_ORDNTF_OIF) to lead to an error-page after occuring of an exception in UserExit or BADI during saving of the order.
When using the WebDynpro-App EAMS_WDA_ORDNTF_OIF (Maintain PM-Order) - raising an exception or sending an error-message
in UserExit IWO10009 "PM Order: Customer check for 'Save' Event"
or
in BADI WORKORDER_UPDATE Methode AT_SAVE
is a showstopper and will lead the user to an "Error-Page", not allowing to come back and work on the same data. Instead, all changes the user made are lost and the user has to start the app from the beginning:
(This issue was told to SAP, but we got a negative answer and the problem seems not to be resolved in near time.)
For more information and the reason for this behavior you can read the comments in attachement "IWO10009_sample.txt" of SAP-Note "3092671 - Customer ConnectionImprovement Request D9817 - Implementation Example for User Exit IWO10009".
In SAPgui and WebGui, when an error occurred during saving of an order, we are used to come back to the app, being able to correct our entries.
The challenge was to find a workaround, to get the same behavior in the WebDynpro-App:
When saving an order in WDA, the method CALL_TRANSACTION_SAVE of the FloorPlanManager (Class CL_FPM) is called. It is devided into two parts:
First part: Standard-checks, making certain, that data is consistent.
Second part: Saving the order: BAPI "BAPI_ALM_ORDER_MAINTAIN" is called with method SAVE, that is calling UserExit IWO10009 and BADI WORKORDER_UPDATE Methode AT_SAVE. But this point is too late to come back to WDA-App, if a check fails.
Somewhere in or between these two parts, there is the "Point-Of-No-Return". If this is passed, a come back to the WDA-App is not possible:
So the idea is, to additionally implement the customer own checks within the first part.
Therefor the method CHECK_BEFORE_SAVE of class CL_EAMS_BO_ORDER seems to be the right one.
We added a small enhancement there at the end:
We decided to call here (inside the enhancement-method) the UserExit IWO10009 and BADI WORKORDER_UPDATE Methode AT_SAVE in general.
We wanted to have the same logic and checks in all UIs and a central message-handling in the UserExits and BADIs.
(It would also be possible, to call here just the UserExit or the BADI only or only one BADI-Implementation or even only a special method with custom specific checks.)
Occuring Messages have to be given back from the enhancement to the caller through exporting-parameter ET_MESSAGE of method CHECK_BEFORE_SAVE.
Here is the complete idea in steps:
*"----------------------------------------------------------------------
*"Methoden Signatur:
*" Importing
*" MIT_NODE_DATA TYPE EAMS_T_BO_ORD_HEADER
*" Changing
*" MCT_MESSAGE TYPE /PLMB/T_SPI_MSG
*"----------------------------------------------------------------------
METHOD enh_eamsorder__chckbefsave_end.
* Aufruf in CL_EAMS_BO_ORDER~CHECK_BEFORE_SAVE (Ende):
* Beim Sichern in der WebDynpro-Applikation zur Auftragsbearbeitung
* VOR Aufruf der Sicherungsroutinen.
* Funktionsweise:
* Aufruf des UserExits und des BADIs beim Sichern,
* um dortige kundeneigenen Prüfungsroutinen VOR und nicht erst
* innerhalb der Sicherungsroutinen auszuführen.
* Fehlernachrichten können somit noch an die Applikation gereicht werden,
* ohne dass diese abbricht (auf die Error-Page führt). Benutzer können
* dadurch ihre eingegebenen Daten noch korrigieren und erneut sichern.
DATA: lt_caufvdb_new TYPE STANDARD TABLE OF caufvdb.
DATA: lt_caufvdb_old TYPE STANDARD TABLE OF caufvdb.
DATA: ls_caufvd_new TYPE caufvd.
DATA: ls_caufvd_old TYPE caufvd.
DATA: lv_trtyp TYPE tc10-trtyp.
DATA: lv_subrc TYPE sy-subrc.
DATA: lt_message TYPE /plmb/t_spi_msg.
FIELD-SYMBOLS <ls_node_data> LIKE LINE OF mit_node_data.
FIELD-SYMBOLS: <ls_caufvdb_new> LIKE LINE OF lt_caufvdb_new.
FIELD-SYMBOLS: <ls_caufvdb_old> LIKE LINE OF lt_caufvdb_old.
***--- Aufträge aus Belegtabellen einlesen
cl_co_fm_access_factory=>cobh( )->co_bh_caufv_bt_fetch(
IMPORTING
et_caufv_bt = lt_caufvdb_new
et_caufv_bt_old = lt_caufvdb_old ).
***--- Auftragsweise Abarbeitung
LOOP AT mit_node_data ASSIGNING <ls_node_data>.
**-- Aktuelle Auftragsdaten lesen
READ TABLE lt_caufvdb_new ASSIGNING <ls_caufvdb_new> WITH KEY aufnr = <ls_node_data>-eams_aufnr.
CHECK: sy-subrc IS INITIAL AND ( <ls_caufvdb_new>-vbkz = 'U' OR <ls_caufvdb_new>-vbkz = 'I' ).
MOVE-CORRESPONDING <ls_caufvdb_new> TO ls_caufvd_new.
**-- "Alte" Auftragsdaten einlesen, falls vorhanden
READ TABLE lt_caufvdb_old ASSIGNING <ls_caufvdb_old> WITH KEY aufnr = <ls_node_data>-eams_aufnr.
IF sy-subrc IS INITIAL.
MOVE-CORRESPONDING <ls_caufvdb_old> TO ls_caufvd_old.
ELSE.
MOVE-CORRESPONDING <ls_caufvdb_new> TO ls_caufvd_old.
ENDIF.
**-- Bestimmung des Transaktionstyps je Auftrag aus dem Verbuchungskennzeichen
CASE <ls_caufvdb_new>-vbkz.
WHEN 'I'.
lv_trtyp = 'H'.
WHEN 'U'.
lv_trtyp = 'V'.
ENDCASE.
**-- Aufruf "UserExit beim Sichern"
PERFORM user_exits_save IN PROGRAM saplcoih USING ls_caufvd_new ls_caufvd_old lv_trtyp lv_subrc.
*- Nachrichtenverarbeitung aus UserExit
IF lv_subrc IS NOT INITIAL.
CLEAR: lt_message.
/plmb/cl_spi_appl_access_utils=>add_syst_message(
CHANGING
ct_message = lt_message ).
APPEND LINES OF lt_message TO mct_message.
CLEAR: lt_message.
lt_message = znibadisexits=>glob_mess_give_2_spi( EXPORTING miv_do_init = 'X' ).
APPEND LINES OF lt_message TO mct_message.
ENDIF.
**-- Aufruf BADI "WORKORDER_UPDATE" Methode AT_SAVE
DATA: lp_badi_if TYPE REF TO if_ex_workorder_update.
CALL FUNCTION 'CO_BADI_GET_BUSINESS_ADD_IN'
EXPORTING
i_badi_name = 'WORKORDER_UPDATE'
CHANGING
c_badi_instance = lp_badi_if
EXCEPTIONS
not_active = 1
OTHERS = 2.
IF sy-subrc IS INITIAL.
CALL METHOD lp_badi_if->at_save
EXPORTING
is_header_dialog = ls_caufvd_new
EXCEPTIONS
error_with_message = 1
OTHERS = 2.
*- Nachrichtenverarbeitung aus BADI
IF sy-subrc <> 0.
CLEAR: lt_message.
/plmb/cl_spi_appl_access_utils=>add_syst_message(
CHANGING
ct_message = lt_message ).
APPEND LINES OF lt_message TO mct_message.
CLEAR: lt_message.
lt_message = znibadisexits=>glob_mess_give_2_spi( EXPORTING miv_do_init = 'X' ).
APPEND LINES OF lt_message TO mct_message.
ENDIF.
ENDIF.
ENDLOOP.
ENDMETHOD.*"----------------------------------------------------------------------
*"Methoden Signatur:
*" Importing
*" MIV_DO_INIT TYPE FLAG
*" Returning
*" VALUE(MRT_MESSAGES_SPI) TYPE /PLMB/T_SPI_MSG
*"----------------------------------------------------------------------
METHOD GLOB_MESS_GIVE_2_SPI.
DATA: lt_message TYPE /plmb/t_spi_msg.
FIELD-SYMBOLS: <fs_s_return> LIKE LINE OF gt_return.
LOOP AT gt_return ASSIGNING <fs_s_return>.
MESSAGE ID <fs_s_return>-id TYPE <fs_s_return>-type NUMBER <fs_s_return>-number
WITH <fs_s_return>-message_v1 <fs_s_return>-message_v2
<fs_s_return>-message_v3 <fs_s_return>-message_v4
INTO sy-lisel.
/plmb/cl_spi_appl_access_utils=>add_syst_message(
EXPORTING
iv_msg_index = <fs_s_return>-row
iv_fieldname = <fs_s_return>-field
CHANGING
ct_message = lt_message ).
ENDLOOP.
APPEND LINES OF lt_message TO mrt_messages_spi.
CHECK: miv_do_init IS NOT INITIAL.
CLEAR: gt_return.
ENDMETHOD.*"----------------------------------------------------------------------
*"Methoden Signatur:
*" Importing
*" MIT_RETURN TYPE BAPIRETTAB
*"----------------------------------------------------------------------
METHOD ORDER_MESS_SHOW.
FIELD-SYMBOLS: <fs_v_log_handle> TYPE balloghndl.
FIELD-SYMBOLS: <fs_s_return> TYPE bapiret2.
DATA: ls_keys_order TYPE cno1keys.
*- Nur wenn Nachrichten auszugeben sind
CHECK: mit_return IS NOT INITIAL.
*- GUI-Typ ermitteln
DATA(ls_gui) = znibadisexits=>xx_get_ui_type( ).
*- Wenn Order-BAPI aktiv ist, geht dessen Message-Handling vor, egal welcher GUI-Typ!
CALL FUNCTION 'IBAPI_Z_GET_BAPI_FLAG'
EXCEPTIONS
bapi_active = 1
bapi_not_active = 2
OTHERS = 3.
IF sy-subrc = 1.
ls_gui-name = 'BAPI'.
ENDIF.
CASE ls_gui-name.
WHEN 'WGU' OR 'HGU' OR 'BAT'.
znibadisexits=>xx_mess_show_gui(
EXPORTING
mit_return = mit_return ).
WHEN 'WDA' OR 'ODA' OR 'BSP' OR 'BAPI'.
***--- Prüfungen
*- Prüfen, ob Order-BAPI aktiv ist
CALL FUNCTION 'IBAPI_Z_GET_BAPI_FLAG' "muss hier erneut geprüft werden,
EXCEPTIONS "da ENH CHECK_BEFORE_SAVE für WebDynpro
bapi_active = 1 "außerhalb des BAPIs läuft.
bapi_not_active = 2 "Dort wird dann gt_return mit Methode
OTHERS = 3. "GLOB_MESS_GIVE_2_SPI genutzt.
IF sy-subrc = 1.
*- Prüfen, ob Message-Handling des BAPIs aktiv ist
ASSIGN ('(SAPLIBAPI_Z)GV_LOG_HANDLE') TO <fs_v_log_handle>.
IF sy-subrc IS INITIAL AND <fs_v_log_handle> IS NOT INITIAL.
***--- Ausführung
*- Übergeben der Messages aus SYST an das Appl.Log des BAPIs
LOOP AT mit_return ASSIGNING <fs_s_return>.
CLEAR: ls_keys_order.
IF <fs_s_return>-parameter IS NOT INITIAL.
IF <fs_s_return>-parameter(4) = 'AUFK'.
ls_keys_order = <fs_s_return>-parameter+4.
ENDIF.
ENDIF.
MESSAGE ID <fs_s_return>-id TYPE <fs_s_return>-type NUMBER <fs_s_return>-number
WITH <fs_s_return>-message_v1 <fs_s_return>-message_v2
<fs_s_return>-message_v3 <fs_s_return>-message_v4
INTO sy-lisel.
CALL FUNCTION 'IBAPI_Z_MSG_STORE'
EXPORTING
iv_aufnr = ls_keys_order-aufnr
iv_vornr = ls_keys_order-activity
iv_uvorn = ls_keys_order-sub_activity
iv_repid = sy-repid.
ENDLOOP.
ENDIF.
ENDIF.
IF <fs_v_log_handle> IS NOT ASSIGNED. "BAPI-Flag ist nicht aktiv oder LOG_HANDLE war nicht gesetzt
APPEND LINES OF mit_return TO gt_return. "=> Nachrichten global speichern, können dann abgeholt werden,
ENDIF. " z.B. bzw. siehe Methode GLOB_MESS_GIVE_2_SPI
WHEN 'BNP'.
LOOP AT mit_return ASSIGNING <fs_s_return>.
MESSAGE ID <fs_s_return>-id TYPE <fs_s_return>-type NUMBER <fs_s_return>-number
WITH <fs_s_return>-message_v1 <fs_s_return>-message_v2
<fs_s_return>-message_v3 <fs_s_return>-message_v4.
ENDLOOP.
WHEN OTHERS.
ENDCASE.
ENDMETHOD.*"----------------------------------------------------------------------
*"Methoden Signatur:
*" Returning
*" VALUE(MES_GUI) TYPE IHTTPNVP
*"----------------------------------------------------------------------
METHOD xx_get_ui_type.
*-- HGU - Html SAP GUI
DATA: lv_its_active TYPE flag.
CALL FUNCTION 'GUI_IS_ITS'
IMPORTING
return = lv_its_active.
IF lv_its_active IS NOT INITIAL.
mes_gui-name = 'HGU'.
mes_gui-value = 'Html SAP GUI' ##NO_TEXT.
RETURN.
ENDIF.
*- BatchInput (muss vor WGU stehen!)
IF sy-binpt IS NOT INITIAL.
mes_gui-name = 'BNP'.
mes_gui-value = 'BatchInput' ##NO_TEXT.
RETURN.
ENDIF.
*-- WGU - Windows SAP GUI
DATA: lv_gui_active TYPE flag.
CALL FUNCTION 'GUI_IS_AVAILABLE'
IMPORTING
return = lv_gui_active.
IF lv_gui_active IS NOT INITIAL.
mes_gui-name = 'WGU'.
mes_gui-value = 'Windows SAP GUI' ##NO_TEXT.
RETURN.
ENDIF.
*-- BSP - Business Server Pages
DATA(lr_bsp_server) = cl_bsp_runtime=>if_bsp_runtime~server.
IF lr_bsp_server IS BOUND.
mes_gui-name = 'BSP'.
mes_gui-value = 'Business Server Pages' ##NO_TEXT.
RETURN.
ENDIF.
*-- WDA - WebDynpro for ABAP
DATA(lr_wd_server) = wdr_task=>server.
IF lr_wd_server IS BOUND.
mes_gui-name = 'WDA'.
mes_gui-value = 'WebDynpro ABAP' ##NO_TEXT.
RETURN.
ENDIF.
*-- ODA - oData (Fiori, ...)
DATA(lo_batch_helper) = /iwfnd/cl_mgw_batch_helper=>get_batch_helper( ). "wird angelegt, wenn nicht aktiv!
lo_batch_helper->batch_get_service_name_version( "Daher keine Prüfung 'IS BOUND'nötig
IMPORTING
ev_service_name = DATA(lv_service_name)
ev_service_version = DATA(lv_service_version)
).
IF lv_service_name IS NOT INITIAL.
mes_gui-name = 'ODA'.
mes_gui-value = 'oData (Fiori, ...)' ##NO_TEXT.
RETURN.
ENDIF.
*-- Hintergrundverarbeitung (Job/...)
IF sy-batch IS NOT INITIAL.
mes_gui-name = 'BAT'.
mes_gui-value = 'batch / background' ##NO_TEXT.
RETURN.
ENDIF.
*-- damit Exporting-Parameter immer gefüllt ist und mit Offset(3) abgefragt werden kann
mes_gui-name = 'OTH'.
mes_gui-value = 'others / unknown' ##NO_TEXT.
ENDMETHOD.*"----------------------------------------------------------------------
*"Methoden Signatur:
*" Importing
*" MIT_RETURN TYPE BAPIRETTAB
*"----------------------------------------------------------------------
METHOD xx_mess_show_gui.
DATA: lv_mess_ident TYPE sy-uzeit.
FIELD-SYMBOLS: <fs_s_return> TYPE bapiret2.
FIELD-SYMBOLS: <fs_v_ident> TYPE sy-uzeit.
***--- StartChecks
*- Nur wenn Nachrichten auszugeben sind
CHECK: mit_return IS NOT INITIAL.
*- Nicht bei BatchInput
CHECK: sy-binpt IS INITIAL.
*- GUI-Typ ermitteln -> Nur bei WinGUI und HtmlGUI Nachrichten hier anzeigen.
DATA(ls_gui) = znibadisexits=>xx_get_ui_type( ).
CHECK: ls_gui-name = 'WGU' OR ls_gui-name = 'HGU' OR ls_gui-name = 'BAT'.
***--- Preparation
*- Prüfen, ob Message-Handler bereits aktiv ist
CALL FUNCTION 'MESSAGES_ACTIVE'
EXCEPTIONS
not_active = 1
OTHERS = 2.
IF sy-subrc <> 0.
ASSIGN ('(SAPLSMSG)GD_IDENT') TO <fs_v_ident>.
IF sy-subrc IS INITIAL.
lv_mess_ident = <fs_v_ident>.
ENDIF.
*- Message-Handler ggf. aktivieren
CALL FUNCTION 'MESSAGES_INITIALIZE'
EXPORTING
i_store_duplicates = 'X'
i_identification = lv_mess_ident
i_allow_foreign_reset = 'X'
IMPORTING
e_identification = lv_mess_ident
EXCEPTIONS
log_not_active = 1
wrong_identification = 2
OTHERS = 0.
IF sy-subrc <> 0.
* nothing to do here
ENDIF.
ENDIF.
***--- Execution
*- Message an Message-Handler geben
LOOP AT mit_return ASSIGNING <fs_s_return>.
CALL FUNCTION 'MESSAGE_STORE'
EXPORTING
arbgb = <fs_s_return>-id
exception_if_not_active = ' '
msgty = <fs_s_return>-type
msgv1 = <fs_s_return>-message_v1
msgv2 = <fs_s_return>-message_v2
msgv3 = <fs_s_return>-message_v3
msgv4 = <fs_s_return>-message_v4
txtnr = <fs_s_return>-number
EXCEPTIONS
message_type_not_valid = 1
not_active = 2
OTHERS = 3.
IF sy-subrc <> 0.
* nothing to do here
ENDIF.
ENDLOOP.
*- Messages ausgeben
CALL FUNCTION 'MESSAGES_SHOW'
EXCEPTIONS
inconsistent_range = 1
no_messages = 2
OTHERS = 3.
IF sy-subrc <> 0.
* nothing to do here
ENDIF.
***--- PostProcessing
*- Sammeln von Nachrichten beenden
IF lv_mess_ident IS NOT INITIAL.
CALL FUNCTION 'MESSAGES_STOP'
EXPORTING
i_identification = lv_mess_ident
i_reset_messages = 'X'
EXCEPTIONS
a_message = 1
e_message = 2
w_message = 3
i_message = 4
s_message = 5
deactivated_by_md = 6
OTHERS = 7.
IF sy-subrc <> 0.
* nothing to do here
ENDIF.
ENDIF.
ENDMETHOD.*"----------------------------------------------------------------------
*"Methoden Signatur:
*" Changing
*" MCS_CAUFVD TYPE CAUFVD
*" Exception
*" ERROR_WITH_MESSAGE
*"----------------------------------------------------------------------
METHOD badi_wupd__at_save.
DATA: lt_return TYPE bapirettab.
* ...
* Implement your custom checks here and collect messages in table lt_return,
* you can use CALL FUNCTION 'BALW_BAPIRETURN_GET2' ... to do that.
* ...
**-- Message-Handling
znibadisexits=>order_mess_show( EXPORTING mit_return = lt_return ).
TRY.
DATA(ls_return) = lt_return[ type = 'E' ].
MESSAGE e005(zli_iwoc) RAISING error_with_message.
* "Beim Speichern wurde ein Fehler gefunden"
CATCH cx_sy_itab_line_not_found.
ENDTRY.
ENDMETHOD.*"----------------------------------------------------------------------
*"Methoden Signatur:
*" Importing
*" MIS_CAUFVD TYPE CAUFVD
*" MIV_TRTYP TYPE TRTYP
*" Changing
*" MCV_RELEASE_ORDER TYPE XFLAG
*" Exception
*" ERROR_WITH_MESSAGE
*"----------------------------------------------------------------------
METHOD userexit_iwo10009.
DATA: lt_return TYPE bapirettab.
* ...
* Implement your custom checks here and collect messages in table lt_return,
* you can use CALL FUNCTION 'BALW_BAPIRETURN_GET2' ... to do that.
* ...
*- Nachrichten- und Ausnahmen-Handling
znibadisexits=>order_mess_show( EXPORTING mit_return = lt_return ).
IF line_exists( lt_return[ type = 'E' ] ).
CHECK: mis_caufvd-abruf_flag IS INITIAL AND ( mis_caufvd-wo_flag IS INITIAL OR miv_trtyp = 'V' ).
MESSAGE e084(iw) RAISING error_with_message.
* "Der Auftrag soll nicht gesichert werden (festgelegt durch Customer-Exit)"
ENDIF.
ENDMETHOD.
Additionally implement the following:
*&---------------------------------------------------------------------*
*& Include ZXWOCU07
*&---------------------------------------------------------------------*
*"----------------------------------------------------------------------
*"*"Lokale Schnittstelle:
*" IMPORTING
*" VALUE(CAUFVD_IMP) LIKE CAUFVD STRUCTURE CAUFVD
*" VALUE(TRTYP) LIKE TC10-TRTYP
*" EXPORTING
*" REFERENCE(RELEASE_ORDER) TYPE XFLAG
*"----------------------------------------------------------------------
znibadisexits=>userexit_iwo10009( EXPORTING mis_caufvd = caufvd_imp
miv_trtyp = trtyp
CHANGING mcv_release_order = release_order
EXCEPTIONS error_with_message = 1
OTHERS = 2 ).
IF sy-subrc <> 0.
IF sy-msgid IS NOT INITIAL AND sy-msgty IS NOT INITIAL.
RAISE error_with_message.
ELSE.
MESSAGE e079(iw) RAISING error_with_message.
* "Sichern wurde vom System zurückgewiesen"
ENDIF.
ENDIF. METHOD if_ex_workorder_update~at_save.
*@78\QImporting@ IS_HEADER_DIALOG TYPE COBAI_S_HEADER_DIALOG Auftragskopf in Dialogstruktur
*@03\QException@ ERROR_WITH_MESSAGE Fehlermeldung aufgetreten
DATA: ls_caufvd TYPE caufvd.
MOVE-CORRESPONDING is_header_dialog TO ls_caufvd.
znibadisexits=>badi_wupd__at_save(
CHANGING
mcs_caufvd = ls_caufvd
EXCEPTIONS
error_with_message = 1
OTHERS = 2 ).
IF sy-subrc <> 0.
IF sy-msgid IS NOT INITIAL AND sy-msgty IS NOT INITIAL.
RAISE error_with_message.
ELSE.
MESSAGE e079(iw) RAISING error_with_message.
* "Sichern wurde vom System zurückgewiesen"
ENDIF.
ENDIF.
ENDMETHOD."""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""$"$\SE:(1) Klasse CL_EAMS_BO_ORDER, Methode CHECK_BEFORE_SAVE, Ende A
*$*$-Start: (1)---------------------------------------------------------------------------------$*$*
ENHANCEMENT 1 ZNIEAMSORDER_CHECKBEFSAVE. "active version
znibadisexits=>enh_eamsorder__chckbefsave_end(
EXPORTING
mit_node_data = lt_node_data
CHANGING
mct_message = et_message ).
ENDENHANCEMENT.
*$*$-End: (1)---------------------------------------------------------------------------------$*$*
As a result, when errors occur during saving of an order in WDA, the user is led back to the WDA-App and the messages are displayed:
The UserExit and the BADI are now called once within the first part of saving (before POINT OF NO RETURN) by custom logic and once after it by SAP-Standard logic:
Important point:
As we decided later, not to use WDA-Apps in productive system at all due to several reasons, this solution is not deeply testet, yet.
Please be careful and check each and every step to meet your requirements.
Another important point:
Due to SAP-Note 3092671, it is possible, to change the order within UserExit IWO10009 during saving by using function modules IBAPI_.... . If you already do that and as this UserExit and BADI WORKORDER_UPDATE~AT_SAVE are now passed at least two times during one save from WDA, you should carefully review your custom logic regarding this.
Here are two articles I wrote some time ago regarding two methods that I use above:
"How to identify the actually used UserInterface Technology from ABAP"
https://community.sap.com/t5/blogs/blogworkflowpage/blog-id/technology-blog-members/article-id/16695...
"How to pass multiple messages from ABAP (Exit/BADI) to the UserInterfaces in S/4HANA-Assetmanagement"
https://community.sap.com/t5/blogs/blogworkflowpage/blog-id/technology-blog-members/article-id/16695...
Maybe these articles are of interest for you, too.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
| User | Count |
|---|---|
| 12 | |
| 5 | |
| 5 | |
| 5 | |
| 4 | |
| 4 | |
| 3 | |
| 3 | |
| 3 | |
| 3 |