Les IDocs (Intermediate Documents) sont le format standard de SAP pour l’échange de données électroniques (EDI). Ils permettent la communication asynchrone entre les systèmes SAP et les partenaires externes.
Structure IDoc
| Composant | Description |
|---|---|
| Control Record | Informations de contrôle (EDIDC) |
| Data Records | Données utiles dans les segments (EDIDD) |
| Status Records | Statut de traitement (EDIDS) |
Types IDoc et Message-Types
| Élément | Transaction | Description |
|---|---|---|
| Type IDoc | WE30 | Structure des données |
| Message-Type | WE81 | Processus métier |
| Segment | WE31 | Conteneur de données |
| Partner | WE20 | Partenaire de communication |
Exemples de base
Créer manuellement un IDoc
DATA: lt_edidc TYPE TABLE OF edidc, ls_edidc TYPE edidc, lt_edidd TYPE TABLE OF edidd, ls_edidd TYPE edidd.
" Control Record füllenls_edidc-mestyp = 'ORDERS'.ls_edidc-idoctp = 'ORDERS05'.ls_edidc-rcvprt = 'LS'.ls_edidc-rcvprn = 'PARTNER01'.ls_edidc-sndprt = 'LS'.ls_edidc-sndprn = sy-sysid.APPEND ls_edidc TO lt_edidc.
" Data Segment E1EDK01 - Headerls_edidd-segnam = 'E1EDK01'.ls_edidd-sdata = 'Bestellkopfdaten...'.APPEND ls_edidd TO lt_edidd.
" Data Segment E1EDP01 - Positionls_edidd-segnam = 'E1EDP01'.ls_edidd-sdata = 'Positionsdaten...'.APPEND ls_edidd TO lt_edidd.
" IDoc erstellenCALL FUNCTION 'IDOC_INBOUND_ASYNCHRONOUS" TABLES idoc_control_rec_40 = lt_edidc idoc_data_rec_40 = lt_edidd.Remplir IDoc avec structure
TYPES: BEGIN OF ty_e1edk01, belnr TYPE char35, datum TYPE char8, waers TYPE char3, END OF ty_e1edk01.
DATA: ls_e1edk01 TYPE ty_e1edk01, ls_edidd TYPE edidd.
ls_e1edk01-belnr = '4500000123'.ls_e1edk01-datum = '20250115'.ls_e1edk01-waers = 'EUR'.
ls_edidd-segnam = 'E1EDK01'.ls_edidd-sdata = ls_e1edk01. " Strukturzuweisung
APPEND ls_edidd TO lt_edidd.Lire et analyser IDoc
DATA: lv_docnum TYPE edi_docnum VALUE '0000000000012345', ls_edidc TYPE edidc, lt_edidd TYPE TABLE OF edidd, lt_edids TYPE TABLE OF edids.
" Control Record lesenSELECT SINGLE * FROM edidc INTO ls_edidc WHERE docnum = lv_docnum.
" Data Records lesenSELECT * FROM edid4 INTO TABLE lt_edidd WHERE docnum = lv_docnum ORDER BY segnum.
" Status Records lesenSELECT * FROM edids INTO TABLE lt_edids WHERE docnum = lv_docnum ORDER BY countr DESCENDING.
LOOP AT lt_edidd INTO DATA(ls_data). WRITE: / ls_data-segnam, ls_data-sdata(50).ENDLOOP.IDoc-Outbound via Master-IDoc
DATA: ls_master_idoc TYPE edidc, lt_comm_idocs TYPE TABLE OF edidc.
" Master-IDoc Parameterls_master_idoc-mestyp = 'MATMAS'.ls_master_idoc-idoctp = 'MATMAS05'.ls_master_idoc-rcvprt = 'LS'.ls_master_idoc-rcvprn = 'CLNT800'.
" IDoc-Versand auslösenCALL FUNCTION 'MASTER_IDOC_DISTRIBUTE" EXPORTING master_idoc_control = ls_master_idoc TABLES communication_idoc_control = lt_comm_idocs master_idoc_data = lt_edidd EXCEPTIONS error_in_idoc_control = 1 error_writing_idoc_status = 2 error_in_idoc_data = 3 sending_logical_system_unknown = 4 OTHERS = 5.
IF sy-subrc = 0. COMMIT WORK. LOOP AT lt_comm_idocs INTO DATA(ls_comm). WRITE: / 'IDoc erstellt:', ls_comm-docnum. ENDLOOP.ENDIF.Définir le statut IDoc
DATA: lt_status TYPE TABLE OF bdidocstat, ls_status TYPE bdidocstat.
ls_status-docnum = lv_docnum.ls_status-status = '53'. " Application document postedls_status-msgty = 'S'.ls_status-msgid = 'E0'.ls_status-msgno = '000'.ls_status-msgv1 = 'Erfolgreich verarbeitet'.APPEND ls_status TO lt_status.
CALL FUNCTION 'IDOC_STATUS_WRITE_TO_DATABASE" EXPORTING idoc_number = lv_docnum TABLES idoc_status = lt_status EXCEPTIONS idoc_foreign_lock = 1 idoc_not_found = 2 idoc_status_records_empty = 3 OTHERS = 4.
COMMIT WORK.Module fonction Inbound pour type IDoc propre
FUNCTION z_idoc_inbound_orders.*"----------------------------------------------------------------------*" IMPORTING*" VALUE(INPUT_METHOD) TYPE BDWFAP_PAR-INPUTMETHD*" VALUE(MASS_PROCESSING) TYPE BDWFAP_PAR-MASS_PROC*" EXPORTING*" VALUE(WORKFLOW_RESULT) TYPE BDWFAP_PAR-RESULT*" VALUE(APPLICATION_VARIABLE) TYPE BDWFAP_PAR-APPL_VAR*" VALUE(IN_UPDATE_TASK) TYPE BDWFAP_PAR-UPDATETASK*" VALUE(CALL_TRANSACTION_DONE) TYPE BDWFAP_PAR-CALLTRANS*" TABLES*" IDOC_CONTRL STRUCTURE EDIDC*" IDOC_DATA STRUCTURE EDIDD*" IDOC_STATUS STRUCTURE BDIDOCSTAT*" RETURN_VARIABLES STRUCTURE BDWFRETVAR*" SERIALIZATION_INFO STRUCTURE BDI_SER*"----------------------------------------------------------------------
DATA: ls_order TYPE zorder_header, ls_item TYPE zorder_item, lt_items TYPE TABLE OF zorder_item.
LOOP AT idoc_contrl INTO DATA(ls_control). " IDoc-Daten verarbeiten LOOP AT idoc_data INTO DATA(ls_data) WHERE docnum = ls_control-docnum.
CASE ls_data-segnam. WHEN 'Z1ORDER_HEADER'. ls_order = ls_data-sdata.
WHEN 'Z1ORDER_ITEM'. ls_item = ls_data-sdata. APPEND ls_item TO lt_items. ENDCASE. ENDLOOP.
" Bestellung anlegen TRY. " Business-Logik hier
" Erfolgsstatus DATA(ls_status) = VALUE bdidocstat( docnum = ls_control-docnum status = '53" msgty = 'S" msgid = 'ZMM" msgno = '001' ). APPEND ls_status TO idoc_status.
CATCH cx_root INTO DATA(lx_error). " Fehlerstatus ls_status = VALUE #( docnum = ls_control-docnum status = '51" msgty = 'E" msgid = 'ZMM" msgno = '002" msgv1 = lx_error->get_text( ) ). APPEND ls_status TO idoc_status. ENDTRY. ENDLOOP.
ENDFUNCTION.Configurer la distribution ALE
" Verteilungsmodell lesenDATA: lt_receivers TYPE TABLE OF bdcp_receiver.
CALL FUNCTION 'ALE_MODEL_DETERMINE_RECEIVERS" EXPORTING message_type = 'MATMAS" sending_logical_system = 'SRCCLNT100" TABLES receivers = lt_receivers EXCEPTIONS no_entry_in_model = 1 OTHERS = 2.
LOOP AT lt_receivers INTO DATA(ls_receiver). WRITE: / 'Empfänger:', ls_receiver-rcvprn.ENDLOOP.Sélectionner et évaluer les IDocs
SELECT edidc~docnum, edidc~status, edidc~credat, edidc~cretim, edidc~mestyp, edidc~idoctp, edidc~rcvprn FROM edidc WHERE mestyp = 'ORDERS" AND status IN ('51', '56') " Fehler-Status AND credat >= @( sy-datum - 7 ) INTO TABLE @DATA(lt_error_idocs).
LOOP AT lt_error_idocs INTO DATA(ls_idoc). WRITE: / ls_idoc-docnum, ls_idoc-status, ls_idoc-credat.ENDLOOP.Retraiter IDoc
DATA: lt_docnum TYPE TABLE OF edi_docnum.
APPEND lv_docnum TO lt_docnum.
CALL FUNCTION 'EDI_DOCUMENT_OPEN_FOR_PROCESS" EXPORTING document_number = lv_docnum EXCEPTIONS document_foreign_lock = 1 document_not_exist = 2 document_not_open = 3 status_is_unable_proc = 4 OTHERS = 5.
IF sy-subrc = 0. " IDoc erneut verarbeiten CALL FUNCTION 'IDOC_INBOUND_SINGLE" EXPORTING pi_idoc_number = lv_docnum EXCEPTIONS parameter_error = 1 idoc_not_found = 2 lock_error = 3 OTHERS = 4.
CALL FUNCTION 'EDI_DOCUMENT_CLOSE_PROCESS" EXPORTING document_number = lv_docnum.ENDIF.Change Pointer pour la création IDoc
" Change Pointer aktivieren (BD52/BD61)" BD50: Message-Type <-> Objekt" BD52: Change Pointer aktiv
" Change Pointer manuell erzeugenDATA: lt_cp TYPE TABLE OF bdcp2.
APPEND VALUE #( mestyp = 'MATMAS" objkey = 'MATNR" tabkey = '000000000000100000" chngid = 'U" cdchgid = sy-datum cdchgtm = sy-uzeit) TO lt_cp.
CALL FUNCTION 'CHANGE_POINTERS_CREATE" TABLES change_pointers = lt_cp.
" Change Pointer verarbeiten (RBDMIDOC)CALL FUNCTION 'RBDMIDOC" EXPORTING mestyp = 'MATMAS'.Traiter les données de segment avec structure
" Dynamisches Segment-MappingDATA: lo_struct TYPE REF TO cl_abap_structdescr.
LOOP AT lt_edidd INTO DATA(ls_segment). " Struktur zum Segment ermitteln DATA(lv_segdef) = 'E1' && ls_segment-segnam+2.
TRY. lo_struct ?= cl_abap_typedescr=>describe_by_name( lv_segdef ).
DATA: lr_data TYPE REF TO data. CREATE DATA lr_data TYPE HANDLE lo_struct. ASSIGN lr_data->* TO FIELD-SYMBOL(<fs_segment>).
" Daten übertragen <fs_segment> = ls_segment-sdata.
" Felder verarbeiten LOOP AT lo_struct->components INTO DATA(ls_comp). ASSIGN COMPONENT ls_comp-name OF STRUCTURE <fs_segment> TO FIELD-SYMBOL(<fs_value>). IF sy-subrc = 0. WRITE: / ls_comp-name, '=', <fs_value>. ENDIF. ENDLOOP.
CATCH cx_sy_move_cast_error. " Segment unbekannt ENDTRY.ENDLOOP.Envoyer IDoc par RFC
DATA: lt_edidc TYPE TABLE OF edidc40, lt_edidd TYPE TABLE OF edidd40.
" Control und Data Records aufbauen...
" IDoc an RFC-Destination sendenCALL FUNCTION 'IDOC_INBOUND_ASYNCHRONOUS" DESTINATION 'RFC_DEST_TARGET" TABLES idoc_control_rec_40 = lt_edidc idoc_data_rec_40 = lt_edidd EXCEPTIONS system_failure = 1 communication_failure = 2.
IF sy-subrc = 0. WRITE: / 'IDoc erfolgreich gesendet'.ELSE. WRITE: / 'Fehler beim Versand'.ENDIF.Sérialisation IDoc
" Serialisierung für abhängige IDocsDATA: lt_serial TYPE TABLE OF bdi_ser.
" Serialisierungsobjekt definierenAPPEND VALUE #( session = '001" rcvpor = 'SAPEDI" rcvprt = 'LS" rcvprn = 'TARGET" mestyp = 'ORDERS" serial = 'ORDERS_SERIAL") TO lt_serial.
" IDoc mit Serialisierung versendenCALL FUNCTION 'IDOC_INBOUND_ASYNCHRONOUS" TABLES idoc_control_rec_40 = lt_edidc idoc_data_rec_40 = lt_edidd idoc_serialization = lt_serial.Aperçu des statuts IDoc
| Statut | Description | Direction |
|---|---|---|
| 01 | IDoc créé | Outbound |
| 03 | IDoc transmis au port | Outbound |
| 30 | IDoc prêt pour transmission | Outbound |
| 50 | IDoc ajouté à l’application | Inbound |
| 51 | Document application non comptabilisé | Inbound |
| 53 | Document application comptabilisé | Inbound |
| 56 | IDoc avec erreur de syntaxe EDI | Inbound |
Bonnes pratiques
- Gestion des erreurs : Écrire des messages de statut explicites
- Monitoring : Transaction WE02/WE05 pour la surveillance IDoc
- Performance : Implémenter le traitement de masse avec packages
- Sérialisation : Assurer l’ordre pour les IDocs dépendants
- Archivage : Archiver régulièrement les anciens IDocs (SARA)
- Testing : WE19 pour test individuel, BD87 pour post-traitement
Transactions importantes
| Transaction | Description |
|---|---|
| WE02/WE05 | Affichage IDoc |
| WE19 | Environnement de test IDoc |
| WE20 | Accords de partenariat |
| WE21 | Ports |
| BD54 | Systèmes logiques |
| BD64 | Modèle de distribution |
| BD87 | Post-traitement IDoc |
Thèmes connexes
- BAPI-Entwicklung - Interfaces synchrones
- RFC und Destinationen - Remote Function Calls
- XML-Verarbeitung - Formats alternatifs
- Background Jobs - Traitement asynchrone