Skip to end of metadata
Go to start of metadata

Author: Amitanshu Deep

Submitted: 6th may 2009.

Description : This code sample is meant for the developers who are looking for a prototype of a report program for editing (modifying) Idocs data.  This report program can be very useful for editing any Idoc with repeated incorrect values in the segment fields .It is just an atempt to develop a reusable report which can provide us flexibility of editing different types of Idocs and incorporate conditional edit in the Idoc with all the possible validations which I can think ofJ.It is a prototype and whoever so using the report can customize and enhance it to address the specific needs of the project. Report can also be tuned for its performance for better results.

 

REPORT zeditidoc MESSAGE-ID idoc_xml1 LINE-SIZE 255.
*---------------------------------------------------------------------*
*                     Type-Pools                                      *
*---------------------------------------------------------------------*
TYPE-POOLS : abap.
*---------------------------------------------------------------------*
*                   Internal Tables                                   *
*---------------------------------------------------------------------*
DATA:
* Internal table to hold entries for control record
      itab_edidc LIKE edidc,
* Internal table to hold entries of status record
      itab_edids40 LIKE edi_ds40 OCCURS 0 WITH HEADER LINE,
* Internal table to hold entries for data record
      itab_edidd LIKE edidd OCCURS 0 WITH HEADER LINE,
* Internal table to hold entries of dd03l corresponding to segment
      BEGIN OF itab_fld OCCURS 0,
        fieldname LIKE dd03l-fieldname,
        inttype   LIKE dd03l-inttype ,
        datatype  LIKE dd03l-datatype ,
        intlen    LIKE dd03l-intlen ,
        decimals  LIKE dd03l-decimals ,
      END OF itab_fld.
*---------------------------------------------------------------------*
*                   Field Symbols                                     *
*---------------------------------------------------------------------*
FIELD-SYMBOLS: <dyn_table> TYPE STANDARD TABLE,
               <dyn_wa>,
               <dyn_var1>,
               <dyn_var2>.
*---------------------------------------------------------------------*
*                    Variables                                        *
*---------------------------------------------------------------------*
*Variables defined for creation of dynamic internal table
DATA:   dy_table TYPE REF TO data,
        dy_line  TYPE REF TO data,
        xfc TYPE lvc_s_fcat,
        ifc TYPE lvc_t_fcat,
        fld_length(255),
        w_seg_elm(62).
*---------------------------------------------------------------------*
*       S E L E C T - O P T I O N S / P A R A M E T E R S             *
*---------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-001.
PARAMETER: p_docnum LIKE edidc-docnum OBLIGATORY, ""Idoc Number
           p_idctyp LIKE idocsyn-idoctyp,
           p_sgmnt  LIKE idocsyn-segtyp OBLIGATORY DEFAULT 'E1EDKA1',
           p_elmnt  TYPE dfies-fieldname OBLIGATORY DEFAULT 'LIFNR',
           p_val LIKE fld_length OBLIGATORY .
SELECTION-SCREEN END OF BLOCK b1.
SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE text-002.
PARAMETER: p_elmnt1  TYPE dfies-fieldname ,
           p_val1 LIKE fld_length .
SELECTION-SCREEN END OF BLOCK b2.
*---------------------------------------------------------------------*
*                    At Selection-screen                              *
*---------------------------------------------------------------------*
AT SELECTION-SCREEN .
  IF NOT p_idctyp EQ space.
    SELECT SINGLE segtyp FROM idocsyn INTO (p_sgmnt)
                WHERE idoctyp = p_idctyp
                 AND  segtyp =  p_sgmnt.
    IF NOT sy-subrc IS INITIAL.
      CONCATENATE 'Type -' p_idctyp INTO w_seg_elm.
      MESSAGE s102 WITH p_sgmnt w_seg_elm.
      CLEAR w_seg_elm.
      STOP.
    ENDIF.
  ENDIF.
*---------------------------------------------------------------------*
*                    Start-of-Selection                               *
*---------------------------------------------------------------------*
START-OF-SELECTION.
  PERFORM open_idoc_to_edit .
  PERFORM change_data.
  PERFORM change_data_segments.
  PERFORM change_control_record.
  PERFORM close_idoc.

END-OF-SELECTION.
*----------------------------------------------------------------------*
*                     S U B - R O U T I N E S                          *
*----------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*&      Form  open_idoc_to_edit
*&---------------------------------------------------------------------*
*      Subroutine to open the Idoc for editing
*----------------------------------------------------------------------*
FORM open_idoc_to_edit.
  CALL FUNCTION 'EDI_DOCUMENT_OPEN_FOR_EDIT'
    EXPORTING
      document_number               = p_docnum
    IMPORTING
      idoc_control                  = itab_edidc
    TABLES
      idoc_data                     = itab_edidd
    EXCEPTIONS
      document_foreign_lock         = 1
      document_not_exist            = 2
      document_not_open             = 3
      status_is_unable_for_changing = 4
      OTHERS                        = 5.
  CASE sy-subrc.
    WHEN 0.
*Validation on segment level
      IF p_elmnt1 NE space AND p_val1 EQ space
      OR p_elmnt1 EQ space AND p_val1 NE space.
        WRITE / text-006.
        STOP.
      ENDIF.
      READ TABLE itab_edidd WITH KEY segnam = p_sgmnt
                               TRANSPORTING NO FIELDS.
      IF NOT sy-subrc IS INITIAL.
        MESSAGE s102 WITH p_sgmnt p_docnum.
        STOP.
      ELSE.
        EXIT.
      ENDIF.
    WHEN OTHERS.
      MESSAGE s113 .
      STOP.
  ENDCASE.
ENDFORM.                    " open_idoc_to_edit
*&---------------------------------------------------------------------
*&      Form  change_data                                             *
*&---------------------------------------------------------------------
*Subroutine performs following steps                                  *
*1. Selection of data structure from table dd03l for the segment      *
*2. Creation of dynamic internal table according to the structure     *
*   provided in selection screen                                      *
* 3.Modification of the Idoc data                                     *
*----------------------------------------------------------------------
FORM change_data.
*select data from DD03L to get the segment structure
  SELECT fieldname
         inttype
         datatype
         intlen
         decimals
   FROM  dd03l
   INTO  TABLE itab_fld
   WHERE tabname = p_sgmnt.
*Validation on elements level
  IF sy-subrc IS INITIAL.
    READ TABLE itab_fld WITH KEY fieldname = p_elmnt
                               TRANSPORTING NO FIELDS.
    IF sy-subrc EQ 0 .
      IF p_elmnt1 NE space.
        READ TABLE itab_fld WITH KEY fieldname = p_elmnt1
                                  TRANSPORTING NO FIELDS.
        IF NOT sy-subrc IS INITIAL.
          CONCATENATE p_sgmnt '--' p_elmnt1 INTO w_seg_elm.
          MESSAGE s102 WITH w_seg_elm p_docnum.
          STOP.
        ENDIF.
      ENDIF.
    ELSE.
      CLEAR w_seg_elm.
      CONCATENATE p_sgmnt '--' p_elmnt INTO w_seg_elm.
      MESSAGE s102 WITH w_seg_elm p_docnum.
      STOP.
    ENDIF.
* Create internal table for creation of dynamic internal table
    LOOP AT itab_fld.
      CLEAR xfc.
      xfc-fieldname =  itab_fld-fieldname .
      xfc-datatype  =  itab_fld-datatype .
      xfc-inttype   =  itab_fld-inttype .
      xfc-intlen    =  itab_fld-intlen .
      xfc-decimals  = itab_fld-decimals .
      APPEND xfc TO ifc.
    ENDLOOP.
* Create dynamic internal table and assign to FS
    CALL METHOD cl_alv_table_create=>create_dynamic_table
      EXPORTING
        it_fieldcatalog = ifc
      IMPORTING
        ep_table        = dy_table.
    ASSIGN dy_table->* TO <dyn_table>.
* Create dynamic work area and assign to FS
    CREATE DATA dy_line LIKE LINE OF <dyn_table>.
    ASSIGN dy_line->* TO <dyn_wa>.
  ELSE.
    WRITE : / text-003.
  ENDIF.
* If comparison values are provided then check the value in the
* corresponding field before editing
  IF p_elmnt1 NE space AND p_val1 NE space.
    LOOP AT itab_edidd WHERE segnam = p_sgmnt.
      <dyn_wa> = itab_edidd-sdata.
      ASSIGN COMPONENT p_elmnt1  OF STRUCTURE  <dyn_wa> TO <dyn_var2> .
      IF <dyn_var2> = p_val1.
        ASSIGN COMPONENT p_elmnt  OF STRUCTURE  <dyn_wa> TO <dyn_var1> .
        <dyn_var1> = p_val.
        itab_edidd-sdata = <dyn_wa>.
        MODIFY itab_edidd.
      ENDIF.
    ENDLOOP.
  ELSE.
* If comparison values are not provided then edit directly
    LOOP AT itab_edidd WHERE segnam = p_sgmnt.
      <dyn_wa> = itab_edidd-sdata.
      ASSIGN COMPONENT p_elmnt  OF STRUCTURE  <dyn_wa> TO <dyn_var1> .
      <dyn_var1> = p_val.
      itab_edidd-sdata = <dyn_wa>.
      MODIFY itab_edidd.
    ENDLOOP.
  ENDIF.
ENDFORM.                    " change_data
*&---------------------------------------------------------------------
*&      Form  change_data_segments                                    *
*&---------------------------------------------------------------------
* Subroutine to change the data segments                               *
*----------------------------------------------------------------------
FORM change_data_segments.
  CALL FUNCTION 'EDI_CHANGE_DATA_SEGMENTS'
    TABLES
      idoc_changed_data_range = itab_edidd
    EXCEPTIONS
      idoc_not_open           = 1
      data_record_not_exist   = 2
      OTHERS                  = 3.
  CASE sy-subrc.
    WHEN 0.
      EXIT.
    WHEN OTHERS.
      MESSAGE s113 .
      STOP.
  ENDCASE.
ENDFORM.                    " change_data_segments
*&---------------------------------------------------------------------
*&      Form  change_control_record                                   *
*&---------------------------------------------------------------------
*Subroutine to change the control record                              *
*----------------------------------------------------------------------
FORM change_control_record.
  CALL FUNCTION 'EDI_CHANGE_CONTROL_RECORD'
    EXPORTING
      idoc_changed_control         = itab_edidc
    EXCEPTIONS
      idoc_not_open                = 1
      direction_change_not_allowed = 2
      OTHERS                       = 3.
  CASE sy-subrc.
    WHEN 0.
      EXIT.
    WHEN OTHERS.
      MESSAGE s113 .
      STOP.
  ENDCASE.
ENDFORM.                    " change_control_record
*&---------------------------------------------------------------------
*&      Form  close_Idoc                                             *
*&---------------------------------------------------------------------
*Subroutine to close the Idoc after edit                             *
*----------------------------------------------------------------------
FORM close_idoc.
  CLEAR itab_edids40.
*steps for updating idoc status
  itab_edids40-docnum = p_docnum.
  itab_edids40-status = '51'.
  itab_edids40-repid = sy-repid.
  itab_edids40-tabnam = 'EDI_DS'.
  itab_edids40-mandt = sy-mandt.
  itab_edids40-stamqu = 'SAP'.
  itab_edids40-stamid = 'B1'.
  itab_edids40-stamno = '999'.
  itab_edids40-stapa1 = 'values changed to '.
  itab_edids40-stapa2 = p_val.
  itab_edids40-logdat = sy-datum.
  itab_edids40-logtim = sy-uzeit.
  APPEND itab_edids40.
  CALL FUNCTION 'EDI_DOCUMENT_CLOSE_EDIT'
    EXPORTING
      document_number  = p_docnum
      do_commit        = 'X'
      do_update        = 'X'
      write_all_status = 'X'
    TABLES
      status_records   = itab_edids40
    EXCEPTIONS
      idoc_not_open    = 1
      db_error         = 2
      OTHERS           = 3.
  CASE sy-subrc.
    WHEN 0.
      WRITE : / 'IDOC number ', p_docnum ,' edited' .
      EXIT.
    WHEN OTHERS.
      MESSAGE s113.
      STOP.
  ENDCASE.
ENDFORM.                    " close_Idoc
 

Text Elements used in report:

1) Selection Texts :-

2) Text Symbols :-

2 Comments

  1. Unknown User (1068x0thg)

    code is working flawlessly.. gud job done buddy...

  2. Unknown User (rjjwsya)

    Hi Friend, 

     This code seems to have a small bug:

     When selecting data from DD03L to get the segment structure

     the field DD03L-Position field should also be retrieved,  and then all fields retrieved should be sorted by position fields ascending,

    otherwise all fields are sorted alphanumeric, when you assign edidd-sdata to <dyn_wa>, there will be wrong fields data assignment.

     Regards,

     Fei Li