12-30-2011 5:25 PM
Hi All,
I have a requirment, where in for the inbound idoc ORDERS02 and idoc type ORDRSP i have to insert a segment E1EDP19 with qualif 002 which will have the vendor part no of the PO item. E1EDP19 001 is already present in the inbound IDoc.
The IDoc is presently failing because the vendor part no is missing which is checked through a custom code put in another user exit. Now i tried inserting the segment in the same user exit EXIT_SAPLEINM_007 (through debug, using insert row) this process' the Idoc successfully without error but the segment is not visible when you check the IDoc.
Can anyone please tell me how to insert a segment for an inbound idoc and if at all it is possible???
thank you!!
VIkas
01-02-2012 11:19 AM
Hi Vikas,
What exactly is your motive? Adding one more record with qualf as 002??
Then you can simply do it by filling the existing segment and appending it to idoc_data.
But if you want to add a new segment itself in the idoc, then you have to create a new segment(WE31)
and create extension to the existing Basic Type(We30).
Please revert for further clarification.
Regards,
Harsh Bansal
01-02-2012 11:19 AM
Hi Vikas,
What exactly is your motive? Adding one more record with qualf as 002??
Then you can simply do it by filling the existing segment and appending it to idoc_data.
But if you want to add a new segment itself in the idoc, then you have to create a new segment(WE31)
and create extension to the existing Basic Type(We30).
Please revert for further clarification.
Regards,
Harsh Bansal
01-02-2012 11:58 AM
Hi,
The new segment should be inserted at the correct sequence as per the hierarchy of the Idoc.
Using Se24 u create a custom class interface
1.ZCL_ADD_IDOC_SEGMENT_TEMP_TEST - Class Interface - Add new segment in Idoc.
2.ZOTC_SEG_NAME - Table Type - Stores names of the Basic typeu2019s or Extensionu2019s segments.
3.ZOTC_SEG_NAME_STRUC - Structure - Idoc segment name.
Note:
Global class which adds segment to IDoc can be described in two steps
1. Constructor
· Reads the IDoc type or extension
· Checks if the given Basic type or extension is valid or not
· If the Basic type or extension is valid read the structure using
Function module - > 1. EXTTYPE_READ (For Extension)
2. IDOCTYPE_READ (For Basic type)
· Fill the class attribute with the structure of basic type or extension.
01-02-2012 5:55 PM
Hi Harsh and ramya thank you for your replies....
Harsh,
I do not want to add a new segment, the segment is already appearing in the Idoc with a qualif 001. I need to populate it with 002 with some other details and insert it into the incoming Idoc. Since its inbound IDoc i dont think i can append it since that would add it to the end of the Idoc and not at the correct place that is below E1EDP19 001. Any idea how to insert it in the IDoc FM??
Hi Ramya,
I think the steps are not complete in the solution you provided...could you please provide the remaining part.
Thank you !!
01-03-2012 6:00 AM
Hi,
First u create a class interface in Se24 as ZCL_ADD_IDOC_SEGMENT_TEMP_TEST.
1.Goto properties tab of Class interface.Mention the properties.
2.Goto the Attributes tab Mention the Attributes of the Class Interface and also mention the
Table type (Associated type ) as ZOTC_SEG_NAME and Line type as ZOTC_SEG_NAME_STRUC.
3.Goto Methods tab mention the parameters as Constructor and Z_ADD_SEGMENT.
CODE:
Method: CONSTRUCTOR(parameters).
*------------------------------------------------------------------*
* constructor reads the IDoc type or extension
* Checks if the given Basic type or extension is valid or not
* If the Basic type or extension is valid read the structure using
* Function module - > 1. EXTTYPE_READ (For Extension)
* 2. IDOCTYPE_READ (For Basic type)
* Fill the class attribute with the structure of basic type or extension
*------------------------------------------------------------------*
DATA: li_segnam TYPE zotc_seg_name,
lwa_segnam TYPE zotc_seg_name_struc,
lv_lines TYPE i,
lv_do_count TYPE i,
lv_exttyp TYPE edi_iapi00-cimtyp,
li_idoc_struc TYPE STANDARD TABLE OF edi_iapi02,
li_extn_struc TYPE STANDARD TABLE OF edi_iapi06.
FIELD-SYMBOLS: TYPE edi_iapi02,
TYPE edi_iapi06.
*------------------------------------------------------------------*
* First check if IM_IDOC_NAME contains Basic type
* If IM_IDOC_NAME is a valid Basic type then * PT_SYNTAX will have it's
* structure
CALL FUNCTION 'IDOCTYPE_READ'
EXPORTING
pi_idoctyp = im_idoc_name
pi_read_devc = space
TABLES
pt_syntax = li_idoc_struc
EXCEPTIONS
object_not_found = 1
db_error = 2
no_authority = 3
OTHERS = 4.
IF sy-subrc <> 0.
*If IM_IDOC_NAME is not a valid basic type then check if it's
* an extension
lv_exttyp = im_idoc_name. " resolve type conflict
CALL FUNCTION 'EXTTYPE_READ'
EXPORTING
pi_cimtyp = lv_exttyp
pi_read_devc = space
TABLES
pt_int_syntax = li_extn_struc
EXCEPTIONS
object_not_found = 1
db_error = 2
no_authority = 3
OTHERS = 4.
IF sy-subrc <> 0.
RAISE idoc_type_does_not_exist.
ELSE.
*------------------------------------------------------------------*
* Fill the attribute with Idoc structure in reverse order
DESCRIBE TABLE li_extn_struc LINES lv_lines.
lv_do_count = lv_lines.
DO lv_do_count TIMES.
IF lv_lines = 0.
EXIT.
ENDIF.
READ TABLE li_extn_struc ASSIGNING INDEX lv_lines.
IF sy-subrc = 0.
lwa_segnam-segnam = -segtyp.
APPEND lwa_segnam TO li_segnam.
CLEAR lwa_segnam.
ENDIF.
lv_lines = lv_lines - 1.
ENDDO.
UNASSIGN .
zotc_segnam = li_segnam.
FREE: li_segnam,li_extn_struc.
CLEAR lv_do_count.
ENDIF.
ELSE.
*------------------------------------------------------------------*
* Fill the attribute with Idoc structure in reverse order
DESCRIBE TABLE li_idoc_struc LINES lv_lines.
lv_do_count = lv_lines.
DO lv_do_count TIMES.
IF lv_lines = 0.
EXIT.
ENDIF.
READ TABLE li_idoc_struc ASSIGNING INDEX lv_lines.
IF sy-subrc = 0.
lwa_segnam-segnam = -segtyp.
APPEND lwa_segnam TO li_segnam.
CLEAR lwa_segnam.
ENDIF.
lv_lines = lv_lines - 1.
ENDDO.
UNASSIGN .
zotc_segnam = li_segnam.
FREE: li_segnam,li_idoc_struc.
CLEAR lv_do_count.
ENDIF.
Method: Z_ADD_SEGMENT(parameters).
*------------------------------------------------------------------*
*u2022 Method will check the hierarchy level at which the new segment
*must be inserted.
*u2022 If segment hierarchy level is greater than 3 then parent segment
* number is mandatory.
*u2022 If parent segment number is given insert segment as a child of *it.
*u2022 After inserting a segment; change segment number and parent
*segment number of all the segments which follow the new segment.
*u2022 If the segment is at hierarchy level 2 then check for any other
* segment with same name.
*u2022 If found then insert the new segment above the existing
*segment.
*u2022 Else check the structure of the Idoc from instance attribute.
*u2022 The new segment should be inserted at the correct sequence as *per the hierarchy of the Idoc.
*------------------------------------------------------------------*
TYPES: BEGIN OF t_psgnum_chg ,
new_psgnum TYPE edi_psgnum,
old_psgnum TYPE edi_psgnum.
TYPES: END OF t_psgnum_chg.
CONSTANTS: lc_1000(4) TYPE c VALUE '1000'.
DATA: lwa_edidd TYPE edidd,
lv_old_psegnum TYPE edidd-psgnum,
lv_old_segnum TYPE edidd-segnum,
lv_old_h TYPE edidd-hlevel,
lv_tabix TYPE sy-tabix,
lv_segnam_tabix TYPE sy-tabix,
lv_tabix_1 TYPE sy-tabix,
lv_lines TYPE i,
lv_segnam TYPE edidd-segnam,
li_result_tab TYPE match_result_tab,
li_psgnum_chg TYPE STANDARD TABLE OF t_psgnum_chg,
lwa_psgnum_chg TYPE t_psgnum_chg.
FIELD-SYMBOLS: TYPE edidd,
TYPE zotc_seg_name_struc,
TYPE match_result,
TYPE t_psgnum_chg.
IF im_hlevel >= 3 AND im_psgnum IS INITIAL.
* Check for parent segment number. If not given raise an exception
RAISE parent_segment_not_given.
ELSEIF im_psgnum IS NOT INITIAL.
*------------------------------------------------------------------*
* Parent segment number given, hence new segment must be inserted
* as a child segment of the appropriate parent
READ TABLE ch_idoc_data
ASSIGNING
WITH KEY segnum = im_psgnum.
IF sy-subrc = 0.
*Fill in the Idoc work area for insertion of segment
lwa_edidd-sdata = im_sdata. "Segment data
lwa_edidd-hlevel = im_hlevel. "Hierarchy level
lwa_edidd-mandt = sy-mandt. "Client
lwa_edidd-dtint2 = lc_1000. "Length field for VARC field
lwa_edidd-psgnum = im_psgnum. "Number of the hierarchically higher SAP segment
lwa_edidd-segnam = im_segnam. "Number of SAP segment
lwa_edidd-docnum = im_docnum. "IDoc number
lwa_edidd-segnum = -segnum + 1.
lv_tabix = sy-tabix + 1.
*Insert Segment
INSERT lwa_edidd INTO ch_idoc_data INDEX lv_tabix.
IF sy-subrc = 0.
ex_segnum = lwa_edidd-segnum.
UNASSIGN .
CLEAR lwa_edidd.
lv_tabix = lv_tabix + 1.
* After segment insertion increament the segment number of next segments
LOOP AT ch_idoc_data ASSIGNING FROM lv_tabix.
* Segment data change should be restricted to single Idoc
* Important check in case of inbound Idoc processing routine is capable
* of processing multiple IDocs at time
IF -docnum <> im_docnum.
EXIT.
ENDIF.
-segnum = -segnum + 1.
* Change parent segment number only if segment number of parent segment
* was incremented
IF lv_old_h IS NOT INITIAL.
IF lv_old_h <> -hlevel AND -hlevel <> 2.
-psgnum = lv_old_segnum.
ELSEIF lv_old_h = -hlevel AND -hlevel <> 2.
-psgnum = lv_old_psegnum.
ENDIF.
ENDIF.
lv_old_psegnum = -psgnum.
lv_old_segnum = -segnum.
lv_old_h = -hlevel.
ENDLOOP.
CLEAR: lv_old_h, lv_old_segnum, lv_old_psegnum, lv_tabix.
UNASSIGN .
ENDIF." sy-subrc for insert
ENDIF.
*------------------------------------------------------------------*
*Segment to be inserted is not a child of any segment
ELSEIF im_hlevel = 02 AND im_psgnum IS INITIAL.
*Check if a segment with same name is already present
READ TABLE ch_idoc_data
ASSIGNING
WITH KEY segnam = im_segnam.
IF sy-subrc = 0.
* Segment with same name is already present. Insert the new segment
* just above.
* This ensures that hierarchy of Idoc segments are maintained
lwa_edidd-sdata = im_sdata.
lwa_edidd-mandt = sy-mandt.
lwa_edidd-dtint2 = lc_1000.
lwa_edidd-hlevel = im_hlevel.
lwa_edidd-psgnum = im_psgnum.
lwa_edidd-segnam = im_segnam.
lwa_edidd-docnum = im_docnum.
lv_tabix = sy-tabix.
lv_tabix_1 = sy-tabix - 1.
*Calculate the Segment number for new segment dynamically
IF lv_tabix_1 >= 1.
READ TABLE ch_idoc_data
ASSIGNING
INDEX lv_tabix_1.
IF sy-subrc = 0.
lwa_edidd-segnum = -segnum + 1.
ENDIF.
ENDIF.
INSERT lwa_edidd INTO ch_idoc_data INDEX lv_tabix.
IF sy-subrc = 0.
ex_segnum = lwa_edidd-segnum.
UNASSIGN .
CLEAR lwa_edidd.
lv_tabix = sy-tabix + 2.
lv_old_segnum = ex_segnum.
* After segment insertion increament the segment number of next segm*ents
LOOP AT ch_idoc_data ASSIGNING FROM lv_tabix.
* Segment data change should be restricted to single Idoc
* Important check in case of inbound Idoc processing routine is capable
* of processing multiple IDocs at time
IF -docnum <> im_docnum.
EXIT.
ENDIF.
-segnum = lv_old_segnum + 1.
* Change parent segment number only if segment number of parent segment
* was incremented
IF lv_old_h IS NOT INITIAL.
IF lv_old_h <> -hlevel AND -hlevel <> 2.
-psgnum = lv_old_segnum.
ELSEIF lv_old_h = -hlevel AND -hlevel <> 2.
-psgnum = lv_old_psegnum.
ENDIF.
ENDIF.
lv_old_psegnum = -psgnum.
lv_old_segnum = -segnum.
lv_old_h = -hlevel.
ENDLOOP.
UNASSIGN .
CLEAR: lv_old_h, lv_old_segnum, lv_old_psegnum, lv_tabix.
ENDIF."for INSERT statment
ELSE.
* Segment with same name is not present.
* Read the Idoc hirachy from INSTATNCE ATTRIBUTE "ME->ZOTC_SEGNAM"
* Insert the new segment at correct hierarchical position
READ TABLE me->zotc_segnam ASSIGNING
WITH KEY segnam = im_segnam.
IF sy-subrc = 0.
lv_segnam_tabix = sy-tabix - 1.
LOOP AT me->zotc_segnam ASSIGNING FROM lv_segnam_tabix.
lv_segnam = .
LOOP AT ch_idoc_data ASSIGNING
WHERE segnam = .
lv_tabix = sy-tabix + 1.
ENDLOOP.
IF IS ASSIGNED.
lwa_edidd-sdata = im_sdata.
lwa_edidd-mandt = sy-mandt.
lwa_edidd-dtint2 = lc_1000.
lwa_edidd-hlevel = im_hlevel.
lwa_edidd-psgnum = im_psgnum.
lwa_edidd-segnam = im_segnam.
lwa_edidd-docnum = im_docnum.
lwa_edidd-segnum = -segnum + 1.
INSERT lwa_edidd INTO ch_idoc_data INDEX lv_tabix.
IF sy-subrc = 0.
ex_segnum = lwa_edidd-segnum.
UNASSIGN .
CLEAR lwa_edidd.
lv_tabix = lv_tabix + 1.
* After segment insertion increament the segment number of next segments
LOOP AT ch_idoc_data ASSIGNING FROM lv_tabix.
* Segment data change should be restricted to single Idoc
* Important check in case of inbound Idoc processing routine is capable
* of processing multiple IDocs at time
IF -docnum <> im_docnum.
EXIT.
ENDIF.
-segnum = -segnum + 1.
* Change parent segment number only if segment number of parent segment
* was incremented
IF lv_old_h IS NOT INITIAL.
IF lv_old_h <> -hlevel AND -hlevel <> 2.
-psgnum = lv_old_segnum.
ELSEIF lv_old_h = -hlevel AND -hlevel <> 2.
-psgnum = lv_old_psegnum.
ENDIF.
ENDIF.
lv_old_psegnum = -psgnum.
lv_old_segnum = -segnum.
lv_old_h = -hlevel.
ENDLOOP."AT ch_idoc_data
UNASSIGN .
CLEAR: lv_old_h, lv_old_segnum, lv_old_psegnum.
IF lv_tabix IS NOT INITIAL.
CLEAR lv_tabix.
EXIT.
ENDIF."lv_tabix IS NOT INITIAL.
EXIT.
ENDIF."sy-subrc = 0. for insert
ENDIF.
ENDLOOP."AT zotc_segnam.
ENDIF."READ TABLE zotc_segnam
ENDIF."READ TABLE ch_idoc_data
ENDIF.
01-03-2012 5:16 PM
Hi Ramya,
Thank again....
I will try this out and let you know the result...
Have a fantastic 2012!!!
Regards,
Vikas
01-09-2012 9:53 PM
Hi Ramya,
I tried the above code provided by you and it did insert the segment correclty into the inbound idoc ( which i checked again through debug), but once again it didnt not appear in the IDoc structure when i checked it through we02.
So now we have decided to check and change the XI mapping to populate and map this segment in XI before it is sent to sap.
I think this should work but thanks again for your replies.
Regards,
Vikas