Batch Input Ersatz in ABAP Cloud: Moderne Alternativen

kategorie
ABAP Cloud
Veröffentlicht
autor
Johannes

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:

ProblemBeschreibung
Dynpro-AbhaengigkeitBatch Input simuliert Bildschirmablaeufe, die in ABAP Cloud nicht existieren
FragilitaetAenderungen an Transaktionen brechen Batch-Input-Programme
PerformanceTransaktionssimulation ist langsam (eine Transaktion pro Satz)
Keine APIKein definierter Vertrag, direkter Zugriff auf UI-Logik
Nicht Cloud-faehigSAP 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

AlternativeAnwendungsfallVorteile
RAP ActionsMassenoperationen auf eigene EntitiesNative ABAP Cloud, transaktional, typsicher
EMLDirekte Entity-ManipulationFlexibel, performant, volle Kontrolle
BAPI WrapperZugriff auf SAP Standard-LogikWiederverwendung existierender BAPIs
Integration SuiteExterne DatenquellenEnterprise-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 Material
persistent table zmaterial
lock master
authorization 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 vorbereiten
DATA(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 aufrufen
MODIFY 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 pruefen
IF 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 Create
managed implementation in class zbp_i_importorder unique;
strict ( 2 );
define behavior for ZI_ImportOrder alias ImportOrder
persistent table zimportorder
lock master
authorization 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 ImportOrderItem
persistent table zimportorderitem
lock dependent by _Order
authorization 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 Logging

API-Design fuer Integration Suite

" Spezielle Action fuer externe Integration
static 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

PhaseAktivitaetErgebnis
1. AnalyseBatch-Input-Programme identifizierenInventarliste
2. KlassifizierungNach Ziel-API gruppieren (RAP, BAPI, Custom)Migrationsplan
3. API-ErstellungRAP BOs oder Wrapper erstellenAPIs verfuegbar
4. MigrationBatch-Input durch API-Aufrufe ersetzenModernisierter Code
5. TestFunktionale Tests und Performance-VergleichQualitaetssicherung
6. DekommissionierungAlte Programme stilllegenAbschluss

Mapping Batch Input zu modernen Konzepten

" ALT: Batch Input fuer Bestellanforderung
DATA: 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 Entities
MODIFY 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 Standard
DATA(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

AspektBatch Input (alt)RAP/EML (neu)
API-StabilitaetFragil (UI-abhaengig)Stabil (definierte API)
PerformanceLangsam (1 Transaktion/Satz)Schnell (Bulk-Operationen)
Fehlerbehandlungsy-subrc, BDC-MessagesStrukturiert (FAILED/REPORTED)
TestbarkeitSchwierig (UI-Simulation)Einfach (Unit Tests mit Mocks)
Cloud-faehigNeinJa
ParallelisierungKomplexNative Unterstuetzung (BGPF)
MonitoringManuellIntegriert (Application Log)

Best Practices

  1. Bulk-first: Immer Bulk-Operationen verwenden, nie Loop mit Einzel-Commits
  2. Paketgroesse: 500-2000 Saetze pro Commit als Richtwert
  3. Fehlertoleranz: Partielle Erfolge ermoeglichen, nicht bei erstem Fehler abbrechen
  4. Logging: Application Log fuer Nachvollziehbarkeit nutzen
  5. Idempotenz: Bei Retry keine Duplikate erzeugen (Check-before-Create)
  6. 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