Remplacement de Batch Input dans ABAP Cloud : Alternatives modernes

Catégorie
ABAP Cloud
Publié
Auteur
Johannes

Batch Input (BDC - Batch Data Communication) a été pendant des décennies la méthode standard dans ABAP classique pour charger des données en masse via la simulation de transactions. Dans ABAP Cloud, ce concept n’est plus disponible. Cet article explique pourquoi et quelles alternatives modernes vous pouvez utiliser.

Pourquoi Batch Input n’est-il pas disponible ?

Batch Input est basé sur la simulation de transactions Dynpro (CALL TRANSACTION, BDC_INSERT). Cette technique présente plusieurs problèmes :

ProblèmeDescription
Dépendance DynproBatch Input simule des écrans qui n’existent pas dans ABAP Cloud
FragilitéLes modifications de transactions cassent les programmes Batch Input
PerformanceLa simulation de transaction est lente (une transaction par enregistrement)
Pas d’APIPas de contrat défini, accès direct à la logique UI
Incompatible CloudSAP exclut les APIs Dynpro de la whitelist ABAP Cloud

Philosophie ABAP Cloud : Au lieu de simuler des transactions, utilisez des APIs définies (RAP, BAPIs, OData) pour des interfaces propres et stables.

Vue d’ensemble des alternatives

AlternativeCas d’usageAvantages
Actions RAPOpérations en masse sur entités propresABAP Cloud natif, transactionnel, type-safe
EMLManipulation directe d’entitésFlexible, performant, contrôle complet
Wrappers BAPIAccès à la logique standard SAPRéutilisation de BAPIs existants
Integration SuiteSources de données externesIntégration d’entreprise, monitoring

Alternative 1 : Actions RAP pour mises à jour en masse

Les Actions RAP sont la méthode privilégiée pour les opérations en masse sur vos propres 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 )
{
// Action statique pour import en masse
static action massImport
parameter ZA_MaterialImport
result [0..*] $self;
// Action statique pour mise à jour en masse
static action massUpdate
parameter ZA_MaterialMassUpdate
result [0..*] $self;
// Action d'instance pour mise à jour individuelle (également appelable en masse)
action updatePrice
parameter ZA_PriceUpdate
result [1] $self;
}

Structure de paramètre pour import en masse

@EndUserText.label: 'Paramètre d'import de matériel"
define abstract entity ZA_MaterialImport
{
// Tableau de matériels à importer
@EndUserText.label: 'Données d'import"
Materials : composition [0..*] of ZA_MaterialImportItem;
}
@EndUserText.label: 'Élément d'import de matériel"
define abstract entity ZA_MaterialImportItem
{
@EndUserText.label: 'Numéro de matériel"
MaterialNumber : abap.char(18);
@EndUserText.label: 'Description"
Description : abap.char(40);
@EndUserText.label: 'Unité de base"
BaseUnit : abap.unit(3);
@EndUserText.label: 'Groupe de matériels"
MaterialGroup : abap.char(9);
@EndUserText.label: 'Prix"
Price : abap.dec(13,2);
@EndUserText.label: 'Devise"
Currency : abap.cuky;
}

Implémentation de l’action Mass Import

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.
" Lire les paramètres
LOOP AT keys INTO DATA(ls_key).
DATA(ls_param) = ls_key-%param.
" Traiter les éléments d'import
LOOP AT ls_param-Materials INTO DATA(ls_item).
DATA(lv_cid) = |CID_{ sy-tabix }|.
" Construire la structure de création
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.
" Création en masse 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.
" Transmettre les erreurs à l'appelant
failed = CORRESPONDING #( lt_failed ).
reported = CORRESPONDING #( lt_reported ).
" Retourner le résultat : tous les matériels créés avec succès
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.

Appel de l’action en masse

" Préparer les données en masse
DATA(lt_import_data) = VALUE za_materialimportitem_tab(
( MaterialNumber = 'MAT001' Description = 'Vis M8"
BaseUnit = 'ST' MaterialGroup = 'BEFEST' Price = '0.50' Currency = 'EUR' )
( MaterialNumber = 'MAT002' Description = 'Écrou M8"
BaseUnit = 'ST' MaterialGroup = 'BEFEST' Price = '0.30' Currency = 'EUR' )
( MaterialNumber = 'MAT003' Description = 'Rondelle M8"
BaseUnit = 'ST' MaterialGroup = 'BEFEST' Price = '0.10' Currency = 'EUR' )
" ... 1000 autres matériels
).
" Appeler l'action Mass Import
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.
" Vérifier le résultat
IF failed-material IS INITIAL.
WRITE: / |{ lines( result ) } matériels importés avec succès|.
ELSE.
LOOP AT reported-material INTO DATA(ls_msg).
WRITE: / ls_msg-%msg->if_message~get_text( ).
ENDLOOP.
ENDIF.

Alternative 2 : EML pour manipulation directe d’entités

EML (Entity Manipulation Language) offre la plus grande flexibilité pour les opérations en masse.

Création en masse avec 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.
" Convertir les données en masse en structure EML
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.
" Création en masse
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).
" Gestion des erreurs
IF failed-material IS NOT INITIAL.
" Construire un message d'erreur détaillé
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.

Mise à jour en masse avec EML

METHOD update_prices_bulk.
DATA: lt_update TYPE TABLE FOR UPDATE zi_material.
" Préparer les données de mise à jour
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.
" Mise à jour en masse
MODIFY ENTITIES OF zi_material
ENTITY Material
UPDATE FROM lt_update
FAILED DATA(failed)
REPORTED DATA(reported).
COMMIT ENTITIES.
" Déterminer le taux de succès
rv_success_count = lines( lt_update ) - lines( failed-material ).
ENDMETHOD.

Suppression en masse avec EML

METHOD delete_materials_bulk.
DATA: lt_delete TYPE TABLE FOR DELETE zi_material.
" Préparer les clés de suppression
lt_delete = VALUE #(
FOR material_number IN it_material_numbers
( MaterialNumber = material_number )
).
" Suppression en masse
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.
" Tous n'ont pas pu être supprimés
LOOP AT reported-material INTO DATA(ls_report).
WRITE: / ls_report-%msg->if_message~get_text( ).
ENDLOOP.
ENDIF.
ENDMETHOD.

Traitement par paquets pour très grands volumes

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.
" Déterminer le nombre total
DATA(lv_total) = lines( it_materials ).
" Traiter par paquets
WHILE lv_offset < lv_total.
" Extraire le paquet actuel
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 ] )
).
" Traiter le paquet
TRY.
DATA(lv_processed) = import_materials( lt_package ).
lv_total_processed += lv_processed.
" Logger le progrès
DATA(lv_percent) = lv_offset * 100 / lv_total.
" Application Log ou Console
WRITE: / |Progrès : { lv_percent }% ({ lv_total_processed }/{ lv_total })|.
CATCH cx_abap_invalid_value INTO DATA(lx_error).
" Logger l'erreur mais continuer
WRITE: / |Paquet { lv_offset / lc_package_size + 1 } échoué|.
ENDTRY.
lv_offset += lc_package_size.
ENDWHILE.
rv_total_processed = lv_total_processed.
ENDMETHOD.

Alternative 3 : Classes Wrapper BAPI

Pour accéder à la logique standard SAP, utilisez des wrappers BAPI qui ont été libérés par SAP pour ABAP Cloud.

Concept des classes Wrapper

┌─────────────────────────────────────────────────────────────┐
│ Code ABAP Cloud │
│ │ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ Classe Wrapper │ (Released API) │
│ │ CL_BAPI_xxx_xxx │ │
│ └──────────┬──────────┘ │
│ │ │
├─────────────────────────┼───────────────────────────────────┤
│ │ (Tier 2 - non appelable directem.)│
│ ▼ │
│ ┌─────────────────────┐ │
│ │ BAPI Standard │ │
│ │ BAPI_xxx_xxx │ │
│ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────┘

Exemple : Créer un matériel avec wrapper BAPI

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.
" Utiliser la classe Wrapper pour BAPI_MATERIAL_SAVEDATA
" (si libérée par SAP, sinon créer son propre wrapper)
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.
" Créer l'instance API
lo_material_api = NEW cl_md_bp_maintain_material( ).
" Mapper les données
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
).
" Appeler BAPI (via wrapper)
CALL METHOD lo_material_api->save
EXPORTING
headdata = ls_headdata
clientdata = ls_clientdata
IMPORTING
return = lt_return.
" Gestion des erreurs
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 (important avec les BAPIs !)
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT"
EXPORTING
wait = abap_true.
rv_material_number = is_material-material_number.
ENDMETHOD.
METHOD create_materials_bulk.
" Les BAPIs ne sont généralement pas optimisés pour le bulk
" Donc appeler individuellement, mais avec collecte d'erreurs
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.

Créer sa propre classe Wrapper

Si aucun wrapper libéré n’existe, vous pouvez créer le vôtre :

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.
" Mapper l'en-tête
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
).
" Mapper les postes
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 )
).
" Mapper les partenaires
lt_partners = VALUE #(
( partn_role = 'AG' partn_numb = is_header-sold_to )
).
" Appeler BAPI (Tier 2, autorisé uniquement dans wrapper)
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.
" Gestion des erreurs
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( |Commande créée : { lv_order }| ).
CATCH cx_abap_invalid_value.
out->write( 'Erreur lors de la création de commande' ).
ENDTRY.
ENDMETHOD.
ENDCLASS.

Alternative 4 : Integration Suite pour données externes

Pour les données provenant de systèmes externes (Excel, CSV, bases de données externes), SAP Integration Suite est la solution d’entreprise.

Architecture avec Integration Suite

┌─────────────────┐ ┌─────────────────────┐ ┌─────────────────┐
│ Source externe │────▶│ SAP Integration │────▶│ ABAP Cloud │
│ (Excel, CSV, │ │ Suite │ │ (RAP OData) │
│ ERP, DB) │ │ │ │ │
└─────────────────┘ │ - Transformation │ │ - Validation │
│ - Mapping │ │ - Persistance │
│ - Gestion erreurs │ │ - Logique │
│ - Monitoring │ │ métier │
└─────────────────────┘ └─────────────────┘

Service OData pour import en masse

" Behavior Definition avec 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 : En-tête + Postes en une seule requête
association _Items { create; }
// Action en masse pour 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;
}

Conception de flux d’intégration (concept)

iFlow: Material_Mass_Import
├── Sender: Adapteur SFTP (fichier CSV)
├── Content Modifier: Ajouter métadonnées
├── CSV to XML Converter
├── Mapping: CSV -> Format entité RAP
├── Splitter: 1000 enregistrements par lot
├── Request-Reply: POST OData vers ABAP Cloud
│ └── Endpoint: /sap/opu/odata4/sap/zui_material/Material
├── Exception Subprocess
│ ├── Logging erreur
│ └── Notification (Email/Alerte)
└── Receiver: Logging succès

Conception d’API pour Integration Suite

" Action spéciale pour intégration externe
static action externalBatchImport
parameter ZA_ExternalBatch
result [1] ZA_ImportResult;
" Paramètre avec ID de lot pour suivi
@EndUserText.label: 'Import de lot externe"
define abstract entity ZA_ExternalBatch
{
@EndUserText.label: 'ID de lot"
BatchId : sysuuid_x16;
@EndUserText.label: 'Système source"
SourceSystem : abap.char(10);
@EndUserText.label: 'Éléments"
Items : composition [0..*] of ZA_ExternalBatchItem;
}
" Résultat avec statistiques
@EndUserText.label: 'Résultat d'import"
define abstract entity ZA_ImportResult
{
@EndUserText.label: 'ID de lot"
BatchId : sysuuid_x16;
@EndUserText.label: 'Total enregistrements"
TotalRecords : abap.int4;
@EndUserText.label: 'Succès"
SuccessCount : abap.int4;
@EndUserText.label: 'Échec"
FailedCount : abap.int4;
@EndUserText.label: 'Détails erreurs"
ErrorDetails : composition [0..*] of ZA_ImportError;
}

Stratégies de migration depuis Batch Input

Migration étape par étape

PhaseActivitéRésultat
1. AnalyseIdentifier les programmes Batch InputListe d’inventaire
2. ClassificationRegrouper par API cible (RAP, BAPI, Custom)Plan de migration
3. Création d’APICréer RAP BOs ou wrappersAPIs disponibles
4. MigrationRemplacer Batch Input par appels APICode modernisé
5. TestTests fonctionnels et comparaison performanceAssurance qualité
6. DécommissionnementDésactiver anciens programmesAchèvement

Mapping Batch Input vers concepts modernes

" ANCIEN : Batch Input pour demande d'achat
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'.
" NOUVEAU : EML pour entités RAP propres
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.
" NOUVEAU : Wrapper BAPI pour standard SAP
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 )
)
).

Checklist pour la migration

  • Inventorier les programmes Batch Input (SE38, SMOD, Report)
  • Identifier les transactions cibles (quels objets SAP sont créés/modifiés ?)
  • Vérifier les APIs libérées (whitelist SAP, wrappers BAPI)
  • Pour objets propres : créer RAP BO avec Actions
  • Moderniser la gestion d’erreurs (FAILED/REPORTED au lieu de sy-subrc)
  • Effectuer tests de performance (Bulk vs Loop)
  • Configurer monitoring/logging (Application Log)
  • Mettre à jour la documentation

Comparaison : Batch Input vs Alternatives modernes

AspectBatch Input (ancien)RAP/EML (nouveau)
Stabilité APIFragile (dépendant UI)Stable (API définie)
PerformanceLent (1 transaction/enregistrement)Rapide (opérations en masse)
Gestion erreurssy-subrc, messages BDCStructuré (FAILED/REPORTED)
TestabilitéDifficile (simulation UI)Facile (tests unitaires avec mocks)
Compatible CloudNonOui
ParallélisationComplexeSupport natif (BGPF)
MonitoringManuelIntégré (Application Log)

Bonnes pratiques

  1. Bulk-first : Toujours utiliser des opérations en masse, jamais de boucle avec commits individuels
  2. Taille de paquet : 500-2000 enregistrements par commit comme référence
  3. Tolérance erreurs : Permettre succès partiels, ne pas abandonner à la première erreur
  4. Logging : Utiliser Application Log pour traçabilité
  5. Idempotence : Lors de retry, ne pas créer de doublons (vérification avant création)
  6. Monitoring : Capturer et exposer les statistiques de traitement

Conclusion

Batch Input n’a plus sa place dans ABAP Cloud. Les alternatives modernes offrent des avantages significatifs :

  • Actions RAP : Solution ABAP Cloud native pour Business Objects propres
  • EML : Flexibilité et performance maximales pour manipulations d’entités
  • Wrappers BAPI : Accès à la logique standard SAP de manière compatible Cloud
  • Integration Suite : Intégration d’entreprise pour sources de données externes

La migration nécessite un effort initial, mais se rentabilise par une meilleure stabilité, performance et maintenabilité.

Ressources complémentaires