This article describes an approach to replicating equipment records between two SAP systems using ALE and IDocs. Part of the solution uses out-of-the-box equipment IDocs. Additionally, BADIs and ABAP code extended the basic functionality to complete the components on the sending system.
For our project, we needed to synchronize equipment data across two different SAP instances. We wanted ALE as the synchronizing solution but were informed by SAP that it couldn't be done.
ALE is ideal because it is a proven technology and is already in use on our project. We needed to decide if we wanted to send the equipment data as master data or transactional data. This is important because different technologies are used to collect and forward the data to the ALE Distribution Layer. Master data was the method of choice because when the data is created, changed or deleted, that data is sent to update the target system. If we chose to treat the data as transactional data, then we would have to create a program to collect the data and send it periodically to the target system. Additionally, we also encounter operational problems with transactional data. As an example, when the source system is down and planned batch jobs are missed, there is a certain amount of manual work involved to ensure that the two systems are again synchronized. This work typically cannot be performed by the data control personnel and usually needs to be resolved by the specialists.
We chose the Master Data approach. When sending Master Data with ALE the following components are needed:
- IDoc with the necessary segments
- Message Type (Source and Target systems)
- Change Pointers
- Maintain Distribution Model to include Source and Target systems
- Source System program which extracts the master data and sends it to the ALE distribution layer
- Target System program which is called by the ALE distribution layer and updates the Master Data
For our project, we needed to synchronize equipment master data across two different SAP instances using change pointers and standard SAP ALE and IDoc functionality.
If all of the needed pieces are predefined, then normal technical steps that are needed to replicate master data are:
- Specify the message type on the sending partner profile (WE20)
- Specify the message type on the receiving partner profile
- Specify and activate the change pointers (BD50)
- Develop/update fields for the change pointers (BD50)
- Maintain the Distribution model and distribute it to both the sending and receiving systems
- Build the master data on the sending system
- Run program RBDMIDOC to build the IDoc(s)
- The master data will build correctly on the receiving system
We found that for equipment master data, some of the functionality was not predefined for us as part of standard SAP functionality, and that we needed to set up the missing pieces. We also found that other people had attempted the same scenario, but were not successful with standard functionality, and had therefore built custom solutions.
The missing pieces related to the change pointers and the master data extraction. There was no pre-existing facility to automatically build change pointers when the equipment records were built or changed. Additionally, there was no SAP program to extract the master data into the pre-existing IDoc format.
Here is how we used existing functionality, and added in the missing components to build and send IDocs using ALE. Our system was SAP 4.6c. Colleagues using a 4.5 configuration mentioned that some components available in our system were not available under theirs.
1. Specifying the message type on the sending partner profile (WE20)
We used a partner type of LS (Logical system - ALE). For the message type on the outbound profile, we used EQUIPMENT_CREATE and basic IDoc type EQUIPMENT_CREATE01. These were predefined SAP components.
2. Specifying the message type on the receiving partner profile (WE20)
We used a partner type of LS (Logical system - ALE). For the message type on the inbound profile, we used EQUIPMENT_CREATE with a process code of BAPI - Inbound BAPI IDoc. These were also predefined SAP component options.
3. We want SAP to build change pointers automatically whenever we build equipment records. However, at this point (SAP 4.6C), SAP does not build change pointers for equipment records. You must do this yourself. Here are the steps, and following is the expanded detail:
A. Specifying the Change Pointer Name
B. Specifying the Change Pointer Fields
C. Building the change pointers
3A. Specifying the change pointer name (BD50)
We are using message type EQUIPMENT_CREATE, but there is no standard change pointer set up for us yet. We need to add it to SAP, in the sending system.
Use Transaction BD50 -- Activate Change Pointers for Message type.
Click "New Entries", specify EQUIPMENT_CREATE for message type, and check the 'Activ' box. This puts the new message type into table TBDA2.
3B. Specifying the Change Pointer Fields
Next we need to tell SAP which field(s) to use to trigger the change pointer function. Use transaction BD52, and enter EQUIPMENT_CREATE for message type into the popup window.
Use EQUI for Object, EQUI for the table name, and KEY for the field name. This will enable SAP to build a change pointer when a new equipment record is added. The message type and corresponding fields will be in table TBD62.
3C. Building the change pointers
SAP will normally build change pointers for predefined document types such as MATMAS for material. However, SAP as delivered does not build change documents or change pointers while building new equipment master records. You must cause this to happen. First we need to build change documents (CDHDR and CDPOS), this will force SAP to also build change pointers when our change pointer entries are set up correctly (steps 3A and 3B). There is no standard functionality to build the change documents while creating equipment records, so we built this using a BADI exit.
If your installed SAP system is current enough, you can do this by taking advantage of a Business Add-in (or BADI). SAP has built an add-in for equipment updates, called "EQUI_UPDATE". This routine is available in the update process, but it has no code attached. You must add the code.
Use Transaction SE19 "Business Add-In: Initial Implementation Maintenance Screen" to define your new logic. Use an implementation name such as ZZEQUI_UPDATE. When you click the "Create" button, SAP shows you a sub-window asking for the Business Add-in – enter EQUI_UPDATE.
The Business Add-in will display the screen "Business Add-In Builder: Change Implementation ZZEQUI_UPDATE". When you go to the Interface tab, you will see the method IM_UPDATE.
When you double-click on the method name, a screen will appear which allows you to add your custom code.
Put the following code into the method:
method IF_EX_EQUI_UPDATE~IN_UPDATE. DATA: l_objectid TYPE cdhdr-objectid, l_tcode TYPE cdhdr-tcode, l_utime TYPE cdhdr-utime, l_udate TYPE cdhdr-udate, l_username TYPE cdhdr-username, object_ind TYPE cdhdr-change_ind, upd_cdtxt TYPE cdpos-chngind, upd_eqkt TYPE cdpos-chngind, upd_equi TYPE cdpos-chngind, l_n_eqkt TYPE eqkt, l_o_eqkt TYPE eqkt, l_n_equi TYPE equi, l_o_equi TYPE equi, l_n_equz TYPE equz, l_o_equz TYPE equz, l_n_iloa TYPE iloa, l_o_iloa TYPE iloa, cdtxt_equi_tab TYPE STANDARD TABLE OF cdtxt. IF sy-tcode EQ 'IE01'. MOVE: i_data_equi-itob-equnr TO l_objectid, 'IE01' TO l_tcode, sy-uzeit TO l_utime, sy-datum TO l_udate, sy-uname TO l_username, 'I' TO object_ind, 'I' TO upd_cdtxt, i_data_equi-itob-equnr TO l_n_eqkt-equnr, sy-langu TO l_n_eqkt-spras, i_data_equi-itob-shtxt TO l_n_eqkt-eqktx, ' ' TO upd_eqkt, 'I' TO upd_equi, sy-mandt TO l_n_equi-mandt, i_data_equi-itob-equnr TO l_n_equi-equnr. CALL FUNCTION 'EQUI_WRITE_DOCUMENT' EXPORTING objectid = l_objectid tcode = l_tcode utime = l_utime udate = l_udate username = l_username * PLANNED_CHANGE_NUMBER = ' ' object_change_indicator = object_ind * PLANNED_OR_REAL_CHANGES = ' ' * NO_CHANGE_POINTERS = ' ' upd_icdtxt_equi = upd_cdtxt n_eqkt = l_n_eqkt o_eqkt = l_o_eqkt upd_eqkt = upd_eqkt n_equi = l_n_equi o_equi = l_o_equi upd_equi = upd_equi n_equz = l_n_equz o_equz = l_o_equz * UPD_EQUZ = ' ' n_iloa = l_n_iloa o_iloa = l_o_iloa * UPD_ILOA = ' ' TABLES icdtxt_equi = cdtxt_equi_tab . ENDIF. endmethod.
When this code is executed, it will build both the change documents and change pointers when we add an equipment master record.
4. Building the IDocs from the change pointers
Program RBDMIDOC will normally build IDocs from change pointers when all is set up correctly. However, the EQUIPMENT_CREATE message type does not have any programming to build IDocs. You must build the code.
This code will be in the form of a function module, which will read the change pointers and build the needed equipment IDocs.
Transaction BD60 'Change view: "Additional data for Message type: Overview' will allow you to name a function module to perform your needed functions. Select the EQUIPMENT_CREATE message type. We named our function module 'Z_MASTERIDOC_CREATE_SMD_EQUIP'.
When you run program RBDMIDOC , it looks up the function module for your requested message type in table TBDME, and executes the function module to build IDocs. You need to program the function module.
This function module will read the change pointers, and based on the master data, build your needed IDocs. This program is based on the example in the book ALE, EDI, and IDoc Technologies for SAP, chapter "Programming the in the IDoc Interface", section "An Outbound Program Triggered from Change Pointers".
FUNCTION Z_MASTERIDOC_CREATE_SMD_EQUIP. *"---------------------------------------------------------------------- *"*"Local interface: *" IMPORTING *" VALUE(MESSAGE_TYPE) LIKE TBDME-MESTYP *" VALUE(CREATION_DATE_HIGH) LIKE SY-DATUM DEFAULT SY-DATUM *" VALUE(CREATION_TIME_HIGH) LIKE SY-UZEIT DEFAULT SY-UZEIT *"---------------------------------------------------------------------- DATA: T_CHGPTRS LIKE BDCP OCCURS 10 WITH HEADER LINE, C_IDOCS_BEFORE_COMMIT like sy-tabix value 50 . data: equi like equi, equz like equz, eqkt like eqkt, iflo like iflo. data: begin of t_cpident occurs 0, cpident like bdcp-cpident, end of t_cpident. data v_equnr like equi-equnr. DATA: CREATED_COMM_IDOCS LIKE SY-TABIX, CREATED_C_IDOCS LIKE SY-TABIX, CREATED_M_IDOCS LIKE SY-TABIX, DONE_SINCE_COMMIT LIKE SY-TABIX, H_WYT3_ALREADY_FILLED(1) TYPE C. data v_save_tabkey like bdcp-tabkey. CONSTANTS: C_CDOBJCL_equi LIKE BDCP-CDOBJCL VALUE 'EQUI'. data C_X(1) value 'X'. CALL FUNCTION 'CHANGE_POINTERS_READ' EXPORTING CHANGE_DOCUMENT_OBJECT_CLASS = C_CDOBJCL_EQUI MESSAGE_TYPE = MESSAGE_TYPE CREATION_DATE_HIGH = CREATION_DATE_HIGH CREATION_TIME_HIGH = CREATION_TIME_HIGH READ_NOT_PROCESSED_POINTERS = C_X TABLES CHANGE_POINTERS = T_CHGPTRS. * SORT T_CHGPTRS BY tabkey CRETIME. * Aufbauen aller Keys aus den Aenderungspointern clear t_cpident. refresh t_cpident. LOOP AT T_CHGPTRS. move t_chgptrs-cpident to t_cpident-cpident. append t_cpident. if t_chgptrs-tabkey = v_save_tabkey. continue. endif. v_save_tabkey = t_chgptrs-tabkey. move t_chgptrs-tabkey+3(18) to v_equnr. call function 'Z_MASTERIDOC_CREATE_EQUIP' exporting equnr = v_equnr sndprt = ' ' message_type = message_type importing created_comm_IDocs = created_comm_IDocs. CREATED_M_IDOCS = CREATED_M_IDOCS + 1. CREATED_C_IDOCS = CREATED_C_IDOCS + CREATED_COMM_IDOCS. DONE_SINCE_COMMIT = DONE_SINCE_COMMIT + 1. IF DONE_SINCE_COMMIT >= C_IDOCS_BEFORE_COMMIT. DONE_SINCE_COMMIT = 0. * write staus of all processed pointers CALL FUNCTION 'CHANGE_POINTERS_STATUS_WRITE' EXPORTING MESSAGE_TYPE = MESSAGE_TYPE TABLES CHANGE_POINTERS_IDENTS = T_CPIDENT. COMMIT WORK. CALL FUNCTION 'DEQUEUE_ALL'. CLEAR T_CPIDENT. REFRESH T_CPIDENT. ENDIF. EXIT. ENDLOOP. * commit if necessary IF DONE_SINCE_COMMIT > 0. * write staus of all processed pointers CALL FUNCTION 'CHANGE_POINTERS_STATUS_WRITE' EXPORTING MESSAGE_TYPE = MESSAGE_TYPE TABLES CHANGE_POINTERS_IDENTS = T_CPIDENT. COMMIT WORK. CALL FUNCTION 'DEQUEUE_ALL'. ENDIF. MESSAGE ID 'B1' TYPE 'I' NUMBER '038' WITH CREATED_M_IDOCS MESSAGE_TYPE. MESSAGE ID 'B1' TYPE 'I' NUMBER '039' WITH CREATED_C_IDOCS MESSAGE_TYPE. ENDFUNCTION. FUNCTION Z_MASTERIDOC_CREATE_EQUIP. *"---------------------------------------------------------------------- *"*"Local interface: *" IMPORTING *" REFERENCE(EQUNR) TYPE EQUNR *" REFERENCE(RCVPFC) LIKE BDALEDC-RCVPFC OPTIONAL *" REFERENCE(RCVPRN) LIKE BDALEDC-RCVPRN OPTIONAL *" REFERENCE(RCVPRT) LIKE BDALEDC-RCVPRT OPTIONAL *" REFERENCE(SNDPFC) LIKE BDALEDC-SNDPFC OPTIONAL *" REFERENCE(SNDPRN) LIKE BDALEDC-SNDPRN OPTIONAL *" REFERENCE(SNDPRT) LIKE BDALEDC-SNDPRT *" REFERENCE(MESSAGE_TYPE) LIKE TBDME-MESTYP *" EXPORTING *" REFERENCE(CREATED_COMM_IDOCS) LIKE SY-TABIX *"---------------------------------------------------------------------- tables: equz, eqkt, iloa, edimsg, equi, crhd. data f_datageneral like bapi_itob. data f_dataspecific like bapi_itob_eq_only. data f_datainstall like bapi_itob_eq_install. data control_record_out like edidc. data it_comm_IDocs like edidc occurs 0 with header line. data int_edidd like edidd occurs 0 with header line. data f_bapiret2 like bapiret2. call function 'BAPI_EQUI_GETDETAIL' exporting equipment = equnr importing data_general_exp = f_datageneral data_specific_exp = f_dataspecific return = f_bapiret2. move f_dataspecific-read_floc to f_datainstall-funcloc. data v_syst like syst. select single * from EDIMSG where MESTYP = MESSAGE_TYPE. if sy-subrc ne 0. MESSAGE ID '00' TYPE 'E' NUMBER '398' with 'Message type EDIMSG not found for ' message_type. endif. * Build control record control_record_out-mestyp = message_type. control_record_out-IDoctp = edimsg-IDoctyp. data v_receivers like bdi_logsys occurs 0 with header line. data v_bdi_fobj like bdi_fobj occurs 0 with header line. clear v_receivers. refresh v_receivers. clear v_bdi_fobj. refresh v_bdi_fobj. CALL FUNCTION 'ALE_ASYNC_BAPI_GET_RECEIVER' exporting object = 'EQUI' method = 'CREATE' tables receivers = v_receivers FILTEROBJECT_VALUES = v_bdi_fobj exceptions error_in_filterobjects = 1 error_in_ale_customizing = 2. IF NOT v_syst IS INITIAL. MESSAGE ID '00' TYPE 'E' NUMBER '398' WITH 'NO RECEIVERS - BAPI_GET_RECEIVER'. ENDIF. call function 'ALE_EQUIPMENT_CREATE' exporting * externalnumber = equi-equnr externalnumber = equnr datageneral = f_DATAGENERAL dataspecific = f_DATASPECIFIC validdate = sy-datum datainstall = f_DATAINSTALL TABLES receivers = v_receivers communication_documents = it_comm_IDocs exceptions error_creating_IDocs = 1. . IF NOT v_syst IS INITIAL. MESSAGE ID '00' TYPE 'E' NUMBER '398' WITH 'Unable to build IDOCS ALE_EQUIPMENT_CREATE'. ENDIF. describe table it_comm_IDocs lines created_comm_IDocs. ENDFUNCTION.
5. Maintain the distribution model for the receving system (BD64)
Use transaction BD64, with the ADD-BAPI functionality. Use an Object name/interface of "PieceOfEquipment", and a method of "Create". These are predefined.
6. Client set-up
When you use ALE to copy equipment data from one client to another, you need to consider:
Internal vs. external equipment numbering and ranges in the target client.
Configuration: All the needed configuration and data must be present in the target client. This includes work center, functional location, object types, etc.
7. Running and verifying the ALE scenario
Here are the operational steps from building an equipment record in the sending system to receiving it in the target system.
A. Build your equipment record in the sending system using IE01.
B. Verify that the change pointer has been built in the sending system by viewing table BDCPV, specifying the needed date/time and message type parameters.
C. Run program RMDBIDOC, with Message type EQUIPMENT_CREATE. It should build your IDoc.
D. Transaction WE02 in your sending system should verify that your IDoc has been sent to your target system.
E. Transaction WE02 in your target (receiving) system should verify that it received the IDoc from step D.
F. Transaction IE03 should verify that the equipment record was built in the target system.