Batch Input (BDC - Batch Data Communication) war jahrzehntelang die Standard-Methode in klassischem ABAP, um Massendaten ueber Transaktionssimulation in SAP einzuspielen. In ABAP Cloud steht dieses Konzept nicht mehr zur Verfuegung. Dieser Artikel zeigt, warum das so ist und welche modernen Alternativen Sie nutzen koennen.
Warum ist Batch Input nicht verfuegbar?
Batch Input basiert auf der Simulation von Dynpro-Transaktionen (CALL TRANSACTION, BDC_INSERT). Diese Technik hat mehrere Probleme:
| Problem | Beschreibung |
|---|---|
| Dynpro-Abhaengigkeit | Batch Input simuliert Bildschirmablaeufe, die in ABAP Cloud nicht existieren |
| Fragilitaet | Aenderungen an Transaktionen brechen Batch-Input-Programme |
| Performance | Transaktionssimulation ist langsam (eine Transaktion pro Satz) |
| Keine API | Kein definierter Vertrag, direkter Zugriff auf UI-Logik |
| Nicht Cloud-faehig | SAP schliesst Dynpro-APIs aus der ABAP Cloud Whitelist aus |
ABAP Cloud Philosophie: Statt Transaktionen zu simulieren, nutzen Sie definierte APIs (RAP, BAPIs, OData) fuer saubere, stabile Schnittstellen.
Uebersicht der Alternativen
| Alternative | Anwendungsfall | Vorteile |
|---|---|---|
| RAP Actions | Massenoperationen auf eigene Entities | Native ABAP Cloud, transaktional, typsicher |
| EML | Direkte Entity-Manipulation | Flexibel, performant, volle Kontrolle |
| BAPI Wrapper | Zugriff auf SAP Standard-Logik | Wiederverwendung existierender BAPIs |
| Integration Suite | Externe Datenquellen | Enterprise-Integration, Monitoring |
Alternative 1: RAP Actions fuer Massenupdates
RAP Actions sind die bevorzugte Methode fuer Massenoperationen auf Ihre eigenen Business Objects.
Behavior Definition
managed implementation in class zbp_i_material unique;strict ( 2 );
define behavior for ZI_Material alias Materialpersistent table zmateriallock masterauthorization master ( instance ){ // Statische Action fuer Massenimport static action massImport parameter ZA_MaterialImport result [0..*] $self;
// Statische Action fuer Massenupdate static action massUpdate parameter ZA_MaterialMassUpdate result [0..*] $self;
// Instance Action fuer Einzelupdate (auch in Masse aufrufbar) action updatePrice parameter ZA_PriceUpdate result [1] $self;}Parameter-Struktur fuer Massenimport
@EndUserText.label: 'Material Import Parameter'define abstract entity ZA_MaterialImport{ // Tabelle von zu importierenden Materialien @EndUserText.label: 'Import Data' Materials : composition [0..*] of ZA_MaterialImportItem;}
@EndUserText.label: 'Material Import Item'define abstract entity ZA_MaterialImportItem{ @EndUserText.label: 'Material Number' MaterialNumber : abap.char(18);
@EndUserText.label: 'Description' Description : abap.char(40);
@EndUserText.label: 'Base Unit' BaseUnit : abap.unit(3);
@EndUserText.label: 'Material Group' MaterialGroup : abap.char(9);
@EndUserText.label: 'Price' Price : abap.dec(13,2);
@EndUserText.label: 'Currency' Currency : abap.cuky;}Implementation der Mass Import Action
CLASS lhc_material DEFINITION INHERITING FROM cl_abap_behavior_handler. PRIVATE SECTION. METHODS mass_import FOR MODIFY IMPORTING keys FOR ACTION Material~massImport RESULT result.ENDCLASS.
CLASS lhc_material IMPLEMENTATION. METHOD mass_import. DATA: lt_create TYPE TABLE FOR CREATE zi_material, lt_mapped TYPE TABLE FOR MAPPED zi_material, lt_failed TYPE TABLE FOR FAILED zi_material, lt_reported TYPE TABLE FOR REPORTED zi_material.
" Parameter auslesen LOOP AT keys INTO DATA(ls_key). DATA(ls_param) = ls_key-%param.
" Import-Items verarbeiten LOOP AT ls_param-Materials INTO DATA(ls_item). DATA(lv_cid) = |CID_{ sy-tabix }|.
" Create-Struktur aufbauen APPEND VALUE #( %cid = lv_cid MaterialNumber = ls_item-MaterialNumber Description = ls_item-Description BaseUnit = ls_item-BaseUnit MaterialGroup = ls_item-MaterialGroup Price = ls_item-Price Currency = ls_item-Currency ) TO lt_create. ENDLOOP. ENDLOOP.
" Bulk Create via EML MODIFY ENTITIES OF zi_material IN LOCAL MODE ENTITY Material CREATE FIELDS ( MaterialNumber Description BaseUnit MaterialGroup Price Currency ) WITH lt_create MAPPED lt_mapped FAILED lt_failed REPORTED lt_reported.
" Fehler an Aufrufer weiterreichen failed = CORRESPONDING #( lt_failed ). reported = CORRESPONDING #( lt_reported ).
" Ergebnis zurueckgeben: alle erfolgreich erstellten Materialien IF lt_failed IS INITIAL. READ ENTITIES OF zi_material IN LOCAL MODE ENTITY Material ALL FIELDS WITH CORRESPONDING #( lt_mapped-material ) RESULT DATA(lt_materials).
result = VALUE #( FOR material IN lt_materials ( %cid_ref = material-%cid %param = CORRESPONDING #( material ) ) ). ENDIF. ENDMETHOD.ENDCLASS.Aufruf der Mass Action
" Massendaten vorbereitenDATA(lt_import_data) = VALUE za_materialimportitem_tab( ( MaterialNumber = 'MAT001' Description = 'Schraube M8' BaseUnit = 'ST' MaterialGroup = 'BEFEST' Price = '0.50' Currency = 'EUR' ) ( MaterialNumber = 'MAT002' Description = 'Mutter M8' BaseUnit = 'ST' MaterialGroup = 'BEFEST' Price = '0.30' Currency = 'EUR' ) ( MaterialNumber = 'MAT003' Description = 'Unterlegscheibe M8' BaseUnit = 'ST' MaterialGroup = 'BEFEST' Price = '0.10' Currency = 'EUR' ) " ... weitere 1000 Materialien).
" Mass Import Action aufrufenMODIFY ENTITIES OF zi_material ENTITY Material EXECUTE massImport FROM VALUE #( ( %param-Materials = lt_import_data ) ) RESULT DATA(result) FAILED DATA(failed) REPORTED DATA(reported).
COMMIT ENTITIES.
" Ergebnis pruefenIF failed-material IS INITIAL. WRITE: / |{ lines( result ) } Materialien erfolgreich importiert|.ELSE. LOOP AT reported-material INTO DATA(ls_msg). WRITE: / ls_msg-%msg->if_message~get_text( ). ENDLOOP.ENDIF.Alternative 2: EML fuer direkte Entity-Manipulation
EML (Entity Manipulation Language) bietet die groesste Flexibilitaet fuer Massenoperationen.
Bulk Create mit EML
CLASS zcl_material_mass_processor DEFINITION PUBLIC FINAL CREATE PUBLIC. PUBLIC SECTION. TYPES: BEGIN OF ty_material_data, material_number TYPE matnr, description TYPE maktx, base_unit TYPE meins, material_group TYPE matkl, price TYPE netpr, currency TYPE waers, END OF ty_material_data, tt_material_data TYPE STANDARD TABLE OF ty_material_data WITH EMPTY KEY.
METHODS import_materials IMPORTING it_materials TYPE tt_material_data RETURNING VALUE(rv_count) TYPE i RAISING cx_abap_invalid_value.ENDCLASS.
CLASS zcl_material_mass_processor IMPLEMENTATION. METHOD import_materials. DATA: lt_create TYPE TABLE FOR CREATE zi_material, lv_idx TYPE i.
" Massendaten in EML-Struktur konvertieren LOOP AT it_materials INTO DATA(ls_material). lv_idx += 1.
APPEND VALUE #( %cid = |CID_{ lv_idx }| MaterialNumber = ls_material-material_number Description = ls_material-description BaseUnit = ls_material-base_unit MaterialGroup = ls_material-material_group Price = ls_material-price Currency = ls_material-currency ) TO lt_create. ENDLOOP.
" Bulk Create MODIFY ENTITIES OF zi_material ENTITY Material CREATE FIELDS ( MaterialNumber Description BaseUnit MaterialGroup Price Currency ) WITH lt_create MAPPED DATA(mapped) FAILED DATA(failed) REPORTED DATA(reported).
" Fehlerbehandlung IF failed-material IS NOT INITIAL. " Detaillierte Fehlermeldung aufbauen DATA(lv_error_msg) = ||. LOOP AT reported-material INTO DATA(ls_report). lv_error_msg &&= ls_report-%msg->if_message~get_text( ) && cl_abap_char_utilities=>newline. ENDLOOP. RAISE EXCEPTION TYPE cx_abap_invalid_value EXPORTING textid = cx_abap_invalid_value=>cx_abap_invalid_value. ENDIF.
" Commit COMMIT ENTITIES RESPONSE OF zi_material FAILED DATA(commit_failed) REPORTED DATA(commit_reported).
IF commit_failed-material IS NOT INITIAL. RAISE EXCEPTION TYPE cx_abap_invalid_value EXPORTING textid = cx_abap_invalid_value=>cx_abap_invalid_value. ENDIF.
rv_count = lines( lt_create ) - lines( failed-material ). ENDMETHOD.ENDCLASS.Bulk Update mit EML
METHOD update_prices_bulk. DATA: lt_update TYPE TABLE FOR UPDATE zi_material.
" Update-Daten vorbereiten LOOP AT it_price_updates INTO DATA(ls_update). APPEND VALUE #( MaterialNumber = ls_update-material_number Price = ls_update-new_price %control-Price = if_abap_behv=>mk-on ) TO lt_update. ENDLOOP.
" Bulk Update MODIFY ENTITIES OF zi_material ENTITY Material UPDATE FROM lt_update FAILED DATA(failed) REPORTED DATA(reported).
COMMIT ENTITIES.
" Erfolgsquote ermitteln rv_success_count = lines( lt_update ) - lines( failed-material ).ENDMETHOD.Bulk Delete mit EML
METHOD delete_materials_bulk. DATA: lt_delete TYPE TABLE FOR DELETE zi_material.
" Delete-Keys vorbereiten lt_delete = VALUE #( FOR material_number IN it_material_numbers ( MaterialNumber = material_number ) ).
" Bulk Delete MODIFY ENTITIES OF zi_material ENTITY Material DELETE FROM lt_delete FAILED DATA(failed) REPORTED DATA(reported).
COMMIT ENTITIES.
IF failed-material IS NOT INITIAL. " Nicht alle konnten geloescht werden LOOP AT reported-material INTO DATA(ls_report). WRITE: / ls_report-%msg->if_message~get_text( ). ENDLOOP. ENDIF.ENDMETHOD.Paketweise Verarbeitung fuer sehr grosse Mengen
METHOD process_in_packages. CONSTANTS: lc_package_size TYPE i VALUE 1000.
DATA: lv_offset TYPE i VALUE 0, lv_total_processed TYPE i VALUE 0.
" Gesamtanzahl ermitteln DATA(lv_total) = lines( it_materials ).
" In Paketen verarbeiten WHILE lv_offset < lv_total. " Aktuelles Paket extrahieren DATA(lt_package) = VALUE tt_material_data( FOR i = lv_offset WHILE i < lv_offset + lc_package_size AND i < lv_total ( it_materials[ i + 1 ] ) ).
" Paket verarbeiten TRY. DATA(lv_processed) = import_materials( lt_package ). lv_total_processed += lv_processed.
" Fortschritt loggen DATA(lv_percent) = lv_offset * 100 / lv_total. " Application Log oder Konsole WRITE: / |Fortschritt: { lv_percent }% ({ lv_total_processed }/{ lv_total })|.
CATCH cx_abap_invalid_value INTO DATA(lx_error). " Fehler loggen, aber weitermachen WRITE: / |Paket { lv_offset / lc_package_size + 1 } fehlgeschlagen|. ENDTRY.
lv_offset += lc_package_size. ENDWHILE.
rv_total_processed = lv_total_processed.ENDMETHOD.Alternative 3: BAPI Wrapper Klassen
Fuer den Zugriff auf SAP-Standard-Logik nutzen Sie BAPI Wrapper, die von SAP fuer ABAP Cloud freigegeben wurden.
Konzept der Wrapper-Klassen
┌─────────────────────────────────────────────────────────────┐│ ABAP Cloud Code ││ │ ││ ▼ ││ ┌─────────────────────┐ ││ │ Wrapper-Klasse │ (Released API) ││ │ CL_BAPI_xxx_xxx │ ││ └──────────┬──────────┘ ││ │ │├─────────────────────────┼───────────────────────────────────┤│ │ (Tier 2 - nicht direkt aufrufbar) ││ ▼ ││ ┌─────────────────────┐ ││ │ Standard BAPI │ ││ │ BAPI_xxx_xxx │ ││ └─────────────────────┘ │└─────────────────────────────────────────────────────────────┘Beispiel: Material anlegen mit BAPI Wrapper
CLASS zcl_material_bapi_import DEFINITION PUBLIC FINAL CREATE PUBLIC. PUBLIC SECTION. METHODS create_material IMPORTING is_material TYPE zcl_material_bapi_import=>ty_material_data RETURNING VALUE(rv_material_number) TYPE matnr RAISING cx_bapi_error.
METHODS create_materials_bulk IMPORTING it_materials TYPE zcl_material_bapi_import=>tt_material_data RETURNING VALUE(rt_results) TYPE tt_import_result.ENDCLASS.
CLASS zcl_material_bapi_import IMPLEMENTATION. METHOD create_material. " Wrapper-Klasse fuer BAPI_MATERIAL_SAVEDATA nutzen " (falls von SAP freigegeben, sonst eigenen Wrapper erstellen)
DATA: lo_material_api TYPE REF TO cl_md_bp_maintain_material, ls_headdata TYPE bapi_mara, ls_clientdata TYPE bapi_mara, lt_return TYPE bapiret2_tab.
" API-Instanz erzeugen lo_material_api = NEW cl_md_bp_maintain_material( ).
" Daten mappen ls_headdata = VALUE #( material = is_material-material_number matl_type = is_material-material_type ind_sector = is_material-industry_sector basic_view = abap_true ).
ls_clientdata = VALUE #( matl_group = is_material-material_group base_uom = is_material-base_unit ).
" BAPI aufrufen (ueber Wrapper) CALL METHOD lo_material_api->save EXPORTING headdata = ls_headdata clientdata = ls_clientdata IMPORTING return = lt_return.
" Fehlerbehandlung LOOP AT lt_return INTO DATA(ls_return) WHERE type CA 'AEX'. RAISE EXCEPTION TYPE cx_bapi_error EXPORTING textid = cx_bapi_error=>cx_bapi_error. ENDLOOP.
" Commit (wichtig bei BAPIs!) CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' EXPORTING wait = abap_true.
rv_material_number = is_material-material_number. ENDMETHOD.
METHOD create_materials_bulk. " BAPIs sind meist nicht fuer Bulk optimiert " Daher einzeln aufrufen, aber mit Fehlersammlung LOOP AT it_materials INTO DATA(ls_material). TRY. DATA(lv_matnr) = create_material( ls_material ). APPEND VALUE #( material_number = lv_matnr success = abap_true ) TO rt_results.
CATCH cx_bapi_error INTO DATA(lx_error). APPEND VALUE #( material_number = ls_material-material_number success = abap_false message = lx_error->get_text( ) ) TO rt_results. ENDTRY. ENDLOOP. ENDMETHOD.ENDCLASS.Eigene Wrapper-Klasse erstellen
Wenn kein freigegebener Wrapper existiert, koennen Sie einen eigenen erstellen:
CLASS zcl_bapi_salesorder_wrapper DEFINITION PUBLIC FINAL CREATE PUBLIC. PUBLIC SECTION. INTERFACES if_oo_adt_classrun.
TYPES: BEGIN OF ty_order_item, material TYPE matnr, quantity TYPE kwmeng, plant TYPE werks_d, END OF ty_order_item, tt_order_items TYPE STANDARD TABLE OF ty_order_item WITH EMPTY KEY.
TYPES: BEGIN OF ty_order_header, order_type TYPE auart, sales_org TYPE vkorg, distr_chan TYPE vtweg, division TYPE spart, sold_to TYPE kunnr, END OF ty_order_header.
METHODS create_sales_order IMPORTING is_header TYPE ty_order_header it_items TYPE tt_order_items RETURNING VALUE(rv_order_number) TYPE vbeln RAISING cx_abap_invalid_value.ENDCLASS.
CLASS zcl_bapi_salesorder_wrapper IMPLEMENTATION. METHOD create_sales_order. DATA: ls_header TYPE bapisdhd1, lt_items TYPE TABLE OF bapisditm, lt_partners TYPE TABLE OF bapiparnr, lt_return TYPE TABLE OF bapiret2.
" Header mappen ls_header = VALUE #( doc_type = is_header-order_type sales_org = is_header-sales_org distr_chan = is_header-distr_chan division = is_header-division ).
" Items mappen lt_items = VALUE #( FOR item IN it_items INDEX INTO idx ( itm_number = idx * 10 material = item-material target_qty = item-quantity plant = item-plant ) ).
" Partner mappen lt_partners = VALUE #( ( partn_role = 'AG' partn_numb = is_header-sold_to ) ).
" BAPI aufrufen (Tier 2, nur in Wrapper erlaubt) CALL FUNCTION 'BAPI_SALESORDER_CREATEFROMDAT2' EXPORTING order_header_in = ls_header IMPORTING salesdocument = rv_order_number TABLES return = lt_return order_items_in = lt_items order_partners = lt_partners.
" Fehlerbehandlung IF line_exists( lt_return[ type = 'E' ] ). RAISE EXCEPTION TYPE cx_abap_invalid_value. ENDIF.
" Commit CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' EXPORTING wait = abap_true. ENDMETHOD.
METHOD if_oo_adt_classrun~main. TRY. DATA(lv_order) = create_sales_order( is_header = VALUE #( order_type = 'TA' sales_org = '1000' distr_chan = '10' division = '00' sold_to = '0000001000' ) it_items = VALUE #( ( material = 'MAT001' quantity = 10 plant = '1000' ) ( material = 'MAT002' quantity = 5 plant = '1000' ) ) ). out->write( |Auftrag erstellt: { lv_order }| ). CATCH cx_abap_invalid_value. out->write( 'Fehler bei Auftragserstellung' ). ENDTRY. ENDMETHOD.ENDCLASS.Alternative 4: Integration Suite fuer externe Daten
Fuer Daten aus externen Systemen (Excel, CSV, externe Datenbanken) ist die SAP Integration Suite die Enterprise-Loesung.
Architektur mit Integration Suite
┌─────────────────┐ ┌─────────────────────┐ ┌─────────────────┐│ Externe Quelle │────▶│ SAP Integration │────▶│ ABAP Cloud ││ (Excel, CSV, │ │ Suite │ │ (RAP OData) ││ ERP, DB) │ │ │ │ │└─────────────────┘ │ - Transformation │ │ - Validation │ │ - Mapping │ │ - Persistence │ │ - Error Handling │ │ - Business │ │ - Monitoring │ │ Logic │ └─────────────────────┘ └─────────────────┘OData Service fuer Massenimport bereitstellen
" Behavior Definition mit Deep Createmanaged implementation in class zbp_i_importorder unique;strict ( 2 );
define behavior for ZI_ImportOrder alias ImportOrderpersistent table zimportorderlock masterauthorization master ( instance ){ create; update; delete;
// Deep Create: Header + Items in einem Request association _Items { create; }
// Mass Action fuer Integration Suite static action processImport parameter ZA_ImportBatch result [0..*] $self;}
define behavior for ZI_ImportOrderItem alias ImportOrderItempersistent table zimportorderitemlock dependent by _Orderauthorization dependent by _Order{ update; delete;
association _Order;}Integration Flow Design (Konzept)
iFlow: Material_Mass_Import├── Sender: SFTP Adapter (CSV-Datei)├── Content Modifier: Metadaten hinzufuegen├── CSV to XML Converter├── Mapping: CSV -> RAP Entity Format├── Splitter: 1000 Records pro Batch├── Request-Reply: OData POST an ABAP Cloud│ └── Endpoint: /sap/opu/odata4/sap/zui_material/Material├── Exception Subprocess│ ├── Error Logging│ └── Notification (Email/Alert)└── Receiver: Success LoggingAPI-Design fuer Integration Suite
" Spezielle Action fuer externe Integrationstatic action externalBatchImport parameter ZA_ExternalBatch result [1] ZA_ImportResult;
" Parameter mit Batch-ID fuer Nachverfolgung@EndUserText.label: 'External Batch Import'define abstract entity ZA_ExternalBatch{ @EndUserText.label: 'Batch ID' BatchId : sysuuid_x16;
@EndUserText.label: 'Source System' SourceSystem : abap.char(10);
@EndUserText.label: 'Items' Items : composition [0..*] of ZA_ExternalBatchItem;}
" Ergebnis mit Statistiken@EndUserText.label: 'Import Result'define abstract entity ZA_ImportResult{ @EndUserText.label: 'Batch ID' BatchId : sysuuid_x16;
@EndUserText.label: 'Total Records' TotalRecords : abap.int4;
@EndUserText.label: 'Successful' SuccessCount : abap.int4;
@EndUserText.label: 'Failed' FailedCount : abap.int4;
@EndUserText.label: 'Error Details' ErrorDetails : composition [0..*] of ZA_ImportError;}Migrationsstrategien von Batch Input
Schritt-fuer-Schritt Migration
| Phase | Aktivitaet | Ergebnis |
|---|---|---|
| 1. Analyse | Batch-Input-Programme identifizieren | Inventarliste |
| 2. Klassifizierung | Nach Ziel-API gruppieren (RAP, BAPI, Custom) | Migrationsplan |
| 3. API-Erstellung | RAP BOs oder Wrapper erstellen | APIs verfuegbar |
| 4. Migration | Batch-Input durch API-Aufrufe ersetzen | Modernisierter Code |
| 5. Test | Funktionale Tests und Performance-Vergleich | Qualitaetssicherung |
| 6. Dekommissionierung | Alte Programme stilllegen | Abschluss |
Mapping Batch Input zu modernen Konzepten
" ALT: Batch Input fuer BestellanforderungDATA: lt_bdcdata TYPE TABLE OF bdcdata.
PERFORM fill_bdc USING 'SAPMM06B' '0100'.PERFORM fill_bdc USING 'BDC_OKCODE' '/00'.PERFORM fill_bdc USING 'EBAN-MATNR' lv_material.PERFORM fill_bdc USING 'EBAN-MENGE' lv_quantity.
CALL TRANSACTION 'ME51N' USING lt_bdcdata MODE 'N' UPDATE 'S'.
" NEU: EML fuer eigene RAP EntitiesMODIFY ENTITIES OF zi_purchreq ENTITY PurchaseRequisition CREATE FIELDS ( Material Quantity Plant ) WITH VALUE #( ( %cid = 'REQ_1' Material = lv_material Quantity = lv_quantity Plant = lv_plant ) ) MAPPED DATA(mapped) FAILED DATA(failed).
COMMIT ENTITIES.
" NEU: BAPI Wrapper fuer SAP StandardDATA(lo_pr_api) = NEW zcl_purchreq_wrapper( ).lo_pr_api->create_requisition( is_header = VALUE #( doc_type = 'NB' ) it_items = VALUE #( ( material = lv_material quantity = lv_quantity plant = lv_plant ) )).Checkliste fuer die Migration
- Batch-Input-Programme inventarisieren (SE38, SMOD, Report)
- Zieltransaktionen identifizieren (welche SAP-Objekte werden angelegt/geaendert?)
- Freigegebene APIs pruefen (SAP Whitelist, BAPI Wrapper)
- Bei eigenen Objekten: RAP BO mit Actions erstellen
- Fehlerbehandlung modernisieren (FAILED/REPORTED statt sy-subrc)
- Performance-Tests durchfuehren (Bulk vs. Loop)
- Monitoring/Logging einrichten (Application Log)
- Dokumentation aktualisieren
Vergleich: Batch Input vs. Moderne Alternativen
| Aspekt | Batch Input (alt) | RAP/EML (neu) |
|---|---|---|
| API-Stabilitaet | Fragil (UI-abhaengig) | Stabil (definierte API) |
| Performance | Langsam (1 Transaktion/Satz) | Schnell (Bulk-Operationen) |
| Fehlerbehandlung | sy-subrc, BDC-Messages | Strukturiert (FAILED/REPORTED) |
| Testbarkeit | Schwierig (UI-Simulation) | Einfach (Unit Tests mit Mocks) |
| Cloud-faehig | Nein | Ja |
| Parallelisierung | Komplex | Native Unterstuetzung (BGPF) |
| Monitoring | Manuell | Integriert (Application Log) |
Best Practices
- Bulk-first: Immer Bulk-Operationen verwenden, nie Loop mit Einzel-Commits
- Paketgroesse: 500-2000 Saetze pro Commit als Richtwert
- Fehlertoleranz: Partielle Erfolge ermoeglichen, nicht bei erstem Fehler abbrechen
- Logging: Application Log fuer Nachvollziehbarkeit nutzen
- Idempotenz: Bei Retry keine Duplikate erzeugen (Check-before-Create)
- Monitoring: Verarbeitungsstatistiken erfassen und exponieren
Fazit
Batch Input hat in ABAP Cloud keinen Platz mehr. Die modernen Alternativen bieten deutliche Vorteile:
- RAP Actions: Native ABAP Cloud Loesung fuer eigene Business Objects
- EML: Maximale Flexibilitaet und Performance fuer Entity-Manipulationen
- BAPI Wrapper: Zugang zu SAP Standard-Logik in Cloud-konformer Art
- Integration Suite: Enterprise-Integration fuer externe Datenquellen
Die Migration erfordert initialen Aufwand, zahlt sich aber durch bessere Stabilitaet, Performance und Wartbarkeit aus.
Weitere Ressourcen
- EML: Entity Manipulation Language
- RAP Actions und Functions
- Wrapper-Klassen fuer ABAP Cloud
- Massendaten-Processing Best Practices
- Background Jobs in ABAP Cloud