02-14-2019 10:28 PM
All,
I have the data available in BDCP2 table. Now i want to build a custom Idoc. The Basic type, Message type and Segments are all custom.
I am able to read the changes using CHANGE_POINTERS_READ but not sure what further steps to follow until i call
MASTER_IDOC_DISTRIBUTE
Thanks
02-15-2019 6:52 AM
Take a look at the piece of code that I've written to generate IDocs from change pointers - hope it helps you:
FUNCTION z_xxx_replicate_change.
*"----------------------------------------------------------------------
*"*"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:
lt_bdcp TYPE STANDARD TABLE OF bdcp,
lt_cpid TYPE t_matnr_cpid_tab,
ls_cpid TYPE t_matnr_cpid,
lv_matnr TYPE matnr,
ls_edidc TYPE edidc,
lt_edidd TYPE STANDARD TABLE OF edidd,
lt_edidc TYPE STANDARD TABLE OF edidc,
ls_z1grm01 TYPE z1grm01,
lv_master_cnt LIKE sy-tabix,
lv_comm_sum LIKE sy-tabix,
lv_comm_cnt LIKE sy-tabix,
ls_mat_class TYPE t_mat_class.
FIELD-SYMBOLS:
<bdcp> TYPE bdcp,
<cpid> TYPE t_matnr_cpid,
<edidd> TYPE edidd.
CALL FUNCTION 'CHANGE_POINTERS_READ'
EXPORTING
creation_date_high = creation_date_high
creation_time_high = creation_time_high
message_type = message_type
read_not_processed_pointers = 'X'
TABLES
change_pointers = lt_bdcp
EXCEPTIONS
error_in_date_interval = 0
error_in_time_interval = 0
OTHERS = 0.
LOOP AT lt_bdcp ASSIGNING <bdcp>.
PERFORM bdcp2matnr USING <bdcp> CHANGING lv_matnr. "get material number from a change pointer
READ TABLE lt_cpid ASSIGNING <cpid>
WITH TABLE KEY matnr = lv_matnr.
IF sy-subrc = 0.
APPEND <bdcp>-cpident TO <cpid>-cpids.
ELSE.
CLEAR ls_cpid.
ls_cpid-matnr = lv_matnr.
APPEND <bdcp>-cpident TO ls_cpid-cpids.
INSERT ls_cpid INTO TABLE lt_cpid.
ENDIF.
ENDLOOP.
ls_edidc-mestyp = message_type.
ls_edidc-idoctp = 'ZIDOCTYPE'. "put here your custom IDoc type
LOOP AT lt_cpid ASSIGNING <cpid>.
CLEAR ls_mat_class.
CLEAR: ls_z1grm01.
ls_mat_class-matnr = <cpid>-matnr.
PERFORM build_z1grm01 USING ls_mat_class CHANGING ls_z1grm01. "build IDoc segment
CLEAR: lt_edidd.
APPEND INITIAL LINE TO lt_edidd ASSIGNING <edidd>.
<edidd>-segnam = 'Z1SEGMENT'. "your custom segment name goes here
<edidd>-sdata = ls_z1grm01.
CLEAR: lt_edidc.
CALL FUNCTION 'MASTER_IDOC_DISTRIBUTE'
EXPORTING
master_idoc_control = ls_edidc
* OBJ_TYPE = ''
* CHNUM = ''
TABLES
communication_idoc_control = lt_edidc
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.
DESCRIBE TABLE lt_edidc LINES lv_comm_cnt.
lv_comm_sum = lv_comm_sum + lv_comm_cnt.
lv_master_cnt = lv_master_cnt + 1.
CALL FUNCTION 'CHANGE_POINTERS_STATUS_WRITE'
EXPORTING
message_type = message_type
TABLES
change_pointers_idents = <cpid>-cpids.
COMMIT WORK.
CALL FUNCTION 'DEQUEUE_ALL'
EXPORTING
_synchron = 'X'.
ENDLOOP.
MESSAGE i038(b1) WITH lv_master_cnt message_type.
MESSAGE i039(b1) WITH lv_comm_sum message_type.
ENDFUNCTION.
02-15-2019 6:43 AM
Take a look at SAP Help documentation: Distributing Master Data Using the SMD Tool
It gives all the customizing steps and what you need to put in your custom function module to generate IDocs from change pointers:
Implement the following steps in your function module to process change pointers and to generate and send IDocs:
1.Read all the change pointers that have not yet been processed for your message type using the function module CHANGE_POINTERS_READ.
2.Create an IDoc for every modified master data object. In the IDoc, only fill the segments that, according to the change pointers, were changed. In every segment, fill the first field MSGFN as follows:
009, if the segment was added
004, if segment fields were changed
003, if the segment was deleted
018, if segment fields were not changed, but the segment must be included in the IDoc, because hierarchically subordinate segments in the IDoc have to be dispatched.
3.Pass the IDoc to the ALE layer by calling function module MASTER_IDOC_DISTRIBUTE.
4.For the master data object that has just been processed, set the change pointers to ‘Finished’. This is done by calling function module CHANGE_POINTERS_STATUS_WRITE.
5.Execute the COMMIT WORK command and call the DEQUEUE_ALL function module. For performance reasons, do not perform this step after every IDoc. Wait until you have created, for example, 50 IDocs.
HTH
Dominik Tylczyński
02-15-2019 6:52 AM
Take a look at the piece of code that I've written to generate IDocs from change pointers - hope it helps you:
FUNCTION z_xxx_replicate_change.
*"----------------------------------------------------------------------
*"*"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:
lt_bdcp TYPE STANDARD TABLE OF bdcp,
lt_cpid TYPE t_matnr_cpid_tab,
ls_cpid TYPE t_matnr_cpid,
lv_matnr TYPE matnr,
ls_edidc TYPE edidc,
lt_edidd TYPE STANDARD TABLE OF edidd,
lt_edidc TYPE STANDARD TABLE OF edidc,
ls_z1grm01 TYPE z1grm01,
lv_master_cnt LIKE sy-tabix,
lv_comm_sum LIKE sy-tabix,
lv_comm_cnt LIKE sy-tabix,
ls_mat_class TYPE t_mat_class.
FIELD-SYMBOLS:
<bdcp> TYPE bdcp,
<cpid> TYPE t_matnr_cpid,
<edidd> TYPE edidd.
CALL FUNCTION 'CHANGE_POINTERS_READ'
EXPORTING
creation_date_high = creation_date_high
creation_time_high = creation_time_high
message_type = message_type
read_not_processed_pointers = 'X'
TABLES
change_pointers = lt_bdcp
EXCEPTIONS
error_in_date_interval = 0
error_in_time_interval = 0
OTHERS = 0.
LOOP AT lt_bdcp ASSIGNING <bdcp>.
PERFORM bdcp2matnr USING <bdcp> CHANGING lv_matnr. "get material number from a change pointer
READ TABLE lt_cpid ASSIGNING <cpid>
WITH TABLE KEY matnr = lv_matnr.
IF sy-subrc = 0.
APPEND <bdcp>-cpident TO <cpid>-cpids.
ELSE.
CLEAR ls_cpid.
ls_cpid-matnr = lv_matnr.
APPEND <bdcp>-cpident TO ls_cpid-cpids.
INSERT ls_cpid INTO TABLE lt_cpid.
ENDIF.
ENDLOOP.
ls_edidc-mestyp = message_type.
ls_edidc-idoctp = 'ZIDOCTYPE'. "put here your custom IDoc type
LOOP AT lt_cpid ASSIGNING <cpid>.
CLEAR ls_mat_class.
CLEAR: ls_z1grm01.
ls_mat_class-matnr = <cpid>-matnr.
PERFORM build_z1grm01 USING ls_mat_class CHANGING ls_z1grm01. "build IDoc segment
CLEAR: lt_edidd.
APPEND INITIAL LINE TO lt_edidd ASSIGNING <edidd>.
<edidd>-segnam = 'Z1SEGMENT'. "your custom segment name goes here
<edidd>-sdata = ls_z1grm01.
CLEAR: lt_edidc.
CALL FUNCTION 'MASTER_IDOC_DISTRIBUTE'
EXPORTING
master_idoc_control = ls_edidc
* OBJ_TYPE = ''
* CHNUM = ''
TABLES
communication_idoc_control = lt_edidc
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.
DESCRIBE TABLE lt_edidc LINES lv_comm_cnt.
lv_comm_sum = lv_comm_sum + lv_comm_cnt.
lv_master_cnt = lv_master_cnt + 1.
CALL FUNCTION 'CHANGE_POINTERS_STATUS_WRITE'
EXPORTING
message_type = message_type
TABLES
change_pointers_idents = <cpid>-cpids.
COMMIT WORK.
CALL FUNCTION 'DEQUEUE_ALL'
EXPORTING
_synchron = 'X'.
ENDLOOP.
MESSAGE i038(b1) WITH lv_master_cnt message_type.
MESSAGE i039(b1) WITH lv_comm_sum message_type.
ENDFUNCTION.
02-15-2019 1:49 PM
Hi Dominik,
This is truly awesome. Thanks a lot for all the details. Much appreciated.
Regards,
Salil