Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
venkatesh298
Explorer

I was new to IDocs. A recent assignment forced me to learn it. I realized that certain portions of Idoc creation could be easily programmed. So, explored a bit and wrote the code to auto-generate them. It worked like a charm. The code (or report: zzz_create_idoc_wizard) is pasted below. Enjoy :smile:

The below report has 5 mandatory parameters. Refer the comments against each of the parameters. Key in valid inputs and execute the report. (Based on your logged on SAP GUI security settings, you may get a security popup to take your confirmation to create/update a file in your local system. Just confirm by clicking 'Allow' or 'OK' button). The output of this report is a text file that gets saved in the path mentioned under parameter m_path. Copy the entire content of this text file. This is it. You can directly paste this 'ready-to-use code' either into a new report or a function module or a subroutine or a class-method. (Isn't it cool? :smile: )

In the auto generated text file, refer the comments mentioned. (By default, I have set the value to 'X'. You can either use this defaulted value for testing purposes. For productive use, replace the defaulted values with your own custom SELECT SQLs or custom logic to populate the segments' internal tables of your IDoc). Save and activate this new code. You are ready. :smile: The possible limits (max and min limit for each segment is also mentioned as comments in the code). This will be handy while preparing the internal tables for each segment of the IDoc.

Both 'basic' and extended' IDoc types are supported. This saves tons of coding time of developers who intend to write, test and rewrite iDocs.

The developer only needs to add the relevant functional/business logic under the specific commented sections of the code in reference to the productive usage of the IDoc (which of course cannot be automated. Are you crazy? :razz: )


REPORT  zzz_create_idoc_wizard.
PARAMETERS: m_obj    TYPE edi_idcobj    OBLIGATORY. "Existing IDoc Object Name
PARAMETERS: m_mestyp TYPE edidc-mestyp  OBLIGATORY. "Message Type
PARAMETERS: m_rcvprt TYPE edidc-rcvprt  OBLIGATORY. "Partner Type of Receiver
PARAMETERS: m_rcvprn TYPE edidc-rcvprn  OBLIGATORY. "Partner Number of Receiver
PARAMETERS: m_path   TYPE rlgrap-filename OBLIGATORY DEFAULT 'C:\temp\idoc.txt'. "Local folder path to save the result or output file
AT SELECTION-SCREEN ON VALUE-REQUEST FOR m_path.
   DATA: lv_path TYPE string.
   CALL METHOD cl_gui_frontend_services=>directory_browse
     EXPORTING
       window_title    = 'Select Directory'
     CHANGING
       selected_folder = lv_path
     EXCEPTIONS
       cntl_error      = 1.
   CALL METHOD cl_gui_cfw=>flush
     EXCEPTIONS
       cntl_system_error = 1
       cntl_error        = 2.
   m_path = lv_path && '\idoc.txt'.
START-OF-SELECTION.
* validate input
   DATA l_attributes TYPE edi_iapi01.
   CALL FUNCTION 'IDOCTYPE_EXISTENCE_CHECK'
     EXPORTING
       pi_idoctyp    = m_obj
     IMPORTING
       pe_attributes = l_attributes
     EXCEPTIONS
       OTHERS        = 1.
   IF l_attributes IS INITIAL.
     MESSAGE 'Invalid object' TYPE 'S' DISPLAY LIKE 'E'. EXIT.
   ENDIF.
* process
   DATA: lt_code TYPE TABLE OF string.
   DATA: ls_code LIKE LINE OF lt_code.
   ls_code = `**** Wizard generated code to create IDoc ` && m_obj && ` ****`.
   APPEND ls_code TO lt_code.
   APPEND INITIAL LINE TO lt_code.
   APPEND 'DATA: control_record LIKE edidc.' TO lt_code.
   APPEND 'DATA: i_communication LIKE edidc OCCURS 0 WITH HEADER LINE,' TO lt_code.
   APPEND '      lt_data LIKE edidd OCCURS 0 WITH HEADER LINE,' TO lt_code.
   APPEND '      ls_data LIKE LINE OF lt_data.' TO lt_code.
   APPEND INITIAL LINE TO lt_code.
   APPEND '**** Set the control record details' TO lt_code.
   ls_code = 'control_record-idoctp = ''' && m_obj && '''.'.       APPEND ls_code TO lt_code.
   ls_code = 'control_record-mestyp = ''' && m_mestyp && '''.'.  APPEND ls_code TO lt_code.
   ls_code = 'control_record-rcvprt = ''' && m_rcvprt && '''.'.  APPEND ls_code TO lt_code.
   ls_code = 'control_record-rcvprn = ''' && m_rcvprn && '''.'.  APPEND ls_code TO lt_code.
   APPEND INITIAL LINE TO lt_code.
   APPEND '**** Logic to populate internal table LT_DATA[] ****' TO lt_code.
   PERFORM custom_logic USING m_obj CHANGING lt_code.
   APPEND INITIAL LINE TO lt_code.
   APPEND '**** End of logic to populate internal table LT_DATA[] ****' TO lt_code.
   APPEND INITIAL LINE TO lt_code.
   APPEND 'CHECK LT_DATA[] IS NOT INITIAL.' TO lt_code.
   APPEND INITIAL LINE TO lt_code.
   APPEND '**** IDoc creation' TO lt_code.
   APPEND '    CALL FUNCTION ''MASTER_IDOC_DISTRIBUTE''' TO lt_code.
   APPEND '      EXPORTING' TO lt_code.
   APPEND '        master_idoc_control            = control_record' TO lt_code.
   APPEND '      TABLES' TO lt_code.
   APPEND '        communication_idoc_control     = i_communication' TO lt_code.
   APPEND '        master_idoc_data               = LT_DATA' TO lt_code.
   APPEND '      EXCEPTIONS' TO lt_code.
   APPEND '        error_in_idoc_control          = 1' TO lt_code.
   APPEND '        error_writing_idoc_status      = 2' TO lt_code.
   APPEND '        error_in_idoc_data             = 3' TO lt_code.
   APPEND '        sending_logical_system_unknown = 4' TO lt_code.
   APPEND '        OTHERS                         = 5.' TO lt_code.
   APPEND '    IF sy-subrc <> 0.' TO lt_code.
   APPEND '      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno' TO lt_code.
   APPEND '              WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.' TO lt_code.
   APPEND '    ELSE.' TO lt_code.
   APPEND '      LOOP AT i_communication.' TO lt_code.
   APPEND '        WRITE: ''IDOC GENERATED'', i_communication-docnum. "check in tcode: WE05' TO lt_code.
   APPEND '      ENDLOOP.' TO lt_code.
   APPEND '      COMMIT WORK.' TO lt_code.
   APPEND '    ENDIF.' TO lt_code.
   DATA lv_path TYPE string.
   lv_path = m_path.
   CALL METHOD cl_gui_frontend_services=>gui_download
     EXPORTING
       filename = lv_path
       filetype = 'DAT'
     CHANGING
       data_tab = lt_code[].
   CALL METHOD cl_gui_frontend_services=>execute
     EXPORTING
       document               = lv_path  " m_path+Name to Document
     EXCEPTIONS
       cntl_error             = 1
       error_no_gui           = 2
       bad_parameter          = 3
       file_not_found         = 4
       path_not_found         = 5
       file_extension_unknown = 6
       error_execute_failed   = 7
       synchronous_failed     = 8
       not_supported_by_gui   = 9
       OTHERS                 = 10.
   IF sy-subrc <> 0.
     "   do nothing
   ENDIF.
*&---------------------------------------------------------------------*
*&      Form  GENERATE_LINES
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_OBJ  text
*      <--P_LT_CODE  text
*----------------------------------------------------------------------*
FORM custom_logic  USING    p_obj LIKE m_obj
                      CHANGING p_lt_code LIKE lt_code.
   DATA l_idoctyp TYPE edi_idoctp.
   DATA g_idoctyp_attr TYPE edi_iapi01.
   DATA :
         gt_idocsyn      LIKE edi_iapi02   OCCURS 20 WITH HEADER LINE,
         gt_prev_idocsyn LIKE edi_iapi02   OCCURS 20 WITH HEADER LINE,
         gs_prev_idocsyn LIKE LINE OF gt_prev_idocsyn.
   DATA: gt_tnode           LIKE snodetext    OCCURS 20 WITH HEADER LINE,
         gt_attr            LIKE sed5attr     OCCURS 20 WITH HEADER LINE,
         gs_attr            LIKE LINE OF gt_attr.
* read basis type
   l_idoctyp = p_obj.
   CALL FUNCTION 'IDOCTYPE_READ'
     EXPORTING
       pi_idoctyp    = l_idoctyp
     IMPORTING
       pe_attributes = g_idoctyp_attr
     TABLES
       pt_syntax     = gt_idocsyn
       pt_pre_syntax = gt_prev_idocsyn.
   DATA lv_variable TYPE string VALUE 'DATA : LT_& TYPE TABLE OF &, LS_& LIKE LINE OF LT_&.'.
   DATA lv_variable_temp TYPE string.
   LOOP AT gt_idocsyn INTO gs_prev_idocsyn.
     lv_variable_temp = lv_variable.
     REPLACE ALL OCCURRENCES OF '&' IN lv_variable_temp WITH gs_prev_idocsyn-segtyp.
     APPEND lv_variable_temp TO p_lt_code.
   ENDLOOP.
   CALL FUNCTION 'CONVERT_IDOC_SYNTAX_TO_TREE'
     EXPORTING
       pi_idoctyp      = l_idoctyp
       pi_descrp       = ''" g_idoctyp_attr-descrp
       pi_e2display    = ''
       pi_e2segrel     = ''
     TABLES
       lt_idocsyn      = gt_idocsyn
       lt_prev_idocsyn = gt_prev_idocsyn
       lt_tree         = gt_tnode
       lt_attr         = gt_attr.
   LOOP AT gt_attr INTO gs_attr.
     APPEND INITIAL LINE TO lt_code.
     lv_variable_temp = `**** Process segment: ` && gs_attr-segtyp.
     APPEND lv_variable_temp TO lt_code.
     lv_variable_temp = 'REFRESH LT_&. CLEAR LT_&[]. CLEAR LS_&.'.
     REPLACE ALL OCCURRENCES OF '&' IN lv_variable_temp WITH gs_attr-segtyp.
     APPEND lv_variable_temp TO lt_code.
     DATA lt_ddic_info TYPE  ddfields.
     DATA ls_ddic_info LIKE LINE OF lt_ddic_info.
*get ddic fields
     CALL FUNCTION 'CATSXT_GET_DDIC_FIELDINFO'
       EXPORTING
         im_structure_name = gs_attr-segtyp
       IMPORTING
         ex_ddic_info      = lt_ddic_info
       EXCEPTIONS
         failed            = 1
         OTHERS            = 2.
     IF sy-subrc <> 0.
       " do nothing
     ENDIF.
     APPEND INITIAL LINE TO lt_code.
     SHIFT gs_attr-occmax LEFT DELETING LEADING '0'.
     lv_variable_temp = `**** Write your custom logic here. Note that the maximum limit for segment ` && gs_attr-segtyp && ` = ` && gs_attr-occmax.
     APPEND lv_variable_temp TO lt_code.
     IF gs_attr-occmax > 1.
       lv_variable_temp = '**** You may cutom code your logic (or copy by referring below statements) for a maximum limit of #' && gs_attr-occmax && ' times'.
       APPEND lv_variable_temp TO lt_code.
     ENDIF.
     LOOP AT lt_ddic_info INTO ls_ddic_info.
       CASE ls_ddic_info-datatype.
         WHEN 'CHAR'. lv_variable_temp = 'X'.
         WHEN ''. "enhance for other types: I, P, date, time, etc
         WHEN OTHERS. lv_variable_temp = 'X'. "default 'X' should work for most random cases
       ENDCASE.
       lv_variable_temp = 'LS_' && gs_attr-segtyp && '-' && ls_ddic_info-fieldname && ' = ''' && lv_variable_temp && '''.'.
       APPEND lv_variable_temp TO lt_code.
     ENDLOOP.
     IF lt_ddic_info IS NOT INITIAL.
       lv_variable_temp = 'APPEND LS_& TO LT_&.'.
       REPLACE ALL OCCURRENCES OF '&' IN lv_variable_temp WITH gs_attr-segtyp.
       APPEND lv_variable_temp TO lt_code.
       APPEND INITIAL LINE TO lt_code.
     ENDIF.
     lv_variable_temp = 'LOOP AT LT_& INTO LS_&.'.
     REPLACE ALL OCCURRENCES OF '&' IN lv_variable_temp WITH gs_attr-segtyp.
     APPEND lv_variable_temp TO lt_code.
     lv_variable_temp = `  LS_DATA-segnam = '&'. LS_DATA-sdata = LS_&. APPEND LS_DATA TO LT_DATA.`.
     REPLACE ALL OCCURRENCES OF '&' IN lv_variable_temp WITH gs_attr-segtyp.
     APPEND lv_variable_temp TO lt_code.
     APPEND 'ENDLOOP.' TO lt_code.
   ENDLOOP.
ENDFORM.                    " GENERATE_LINES






Labels in this area