Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Populating a new segment value for a inbound idoc in recieving system.

Former Member
0 Kudos

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

1 ACCEPTED SOLUTION

Harsh_Bansal
Contributor
0 Kudos

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

6 REPLIES 6

Harsh_Bansal
Contributor
0 Kudos

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

Former Member
0 Kudos

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.

0 Kudos

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 !!

0 Kudos

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.

0 Kudos

Hi Ramya,

Thank again....

I will try this out and let you know the result...

Have a fantastic 2012!!!

Regards,

Vikas

0 Kudos

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