Data Dictionary Program

*&---------------------------------------------------------------------*
*& Report  ZAPODDPROGRAM
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT  ZAPODDPROGRAM NO STANDARD PAGE HEADING.


TYPE-POOLS: SLIS.

TYPES: BEGIN OF TY_EXCEL_FIELD,
        EXCEL_INDEX TYPE SY-INDEX,
        FIELD_NAME TYPE STRING,
        FIELD_VALUE TYPE STRING,
      END OF TY_EXCEL_FIELD.

DATA: IS_EXCEL_FIELD TYPE TY_EXCEL_FIELD.
DATA: IT_EXCEL_FIELD TYPE TABLE OF TY_EXCEL_FIELD.

*Internal tables to hold table information
DATA: IT_TABLES TYPE TABLE OF DD02V.
DATA: IS_TABLES TYPE DD02V.
DATA: IT_TABL_INF_TMP TYPE DD02V.

DATA: IT_TABL_TECHNICS TYPE TABLE OF DD09L.
DATA: IS_TABL_TECHNICS TYPE DD09L.
DATA: IS_TABL_TECHNICS_TMP TYPE DD09L.

DATA: IT_TABL_FIELDS TYPE DD03P OCCURS 0.
DATA: IT_TABL_FIELDS_TMP TYPE DD03P OCCURS 0.
DATA: IS_TABL_FIELDS TYPE DD03P.

*Internal tables to hold domain information
DATA: IT_DOMAINS TYPE TABLE OF DD01V.
DATA: IS_DOMAINS TYPE DD01V.
DATA: IS_DOMAINS_TMP TYPE DD01V.

DATA: IT_DOMA_VALUES TYPE DD07V OCCURS 0.
DATA: IT_DOMA_VALUES_TMP TYPE DD07V OCCURS 0.
DATA: IS_DOMA_VALUES TYPE DD07V.

*Internal tables to hold data element information
DATA: IT_DATAELEMENTS TYPE TABLE OF DD04V.
DATA: IS_DATAELEMENTS TYPE DD04V.
DATA: IS_DATAELEMENTS_TMP TYPE DD04V.

*Internal table to hold messages
TYPES: BEGIN OF TY_MESSAGES,
        MANDT TYPE SY-MANDT,
        MSGID TYPE SY-MSGID,
        MSGTY TYPE SY-MSGTY,
        MSGNO TYPE SY-MSGNO,
        MSGV1 TYPE SY-MSGV1,
        MSGV2 TYPE SY-MSGV2,
        MSGV3 TYPE SY-MSGV3,
        MSGV4 TYPE SY-MSGV4,
        TEXT  TYPE T100-TEXT,
      END OF TY_MESSAGES.

DATA: IS_MESSAGES TYPE TY_MESSAGES.
DATA: IT_MESSAGES TYPE TABLE OF TY_MESSAGES.

*Variables to hold message information
DATA: 	 V_MSGID TYPE SY-MSGID,
        V_MSGTY TYPE SY-MSGTY,
        V_MSGNO TYPE SY-MSGNO,
        V_MSGV1 TYPE SY-MSGV1,
        V_MSGV2 TYPE SY-MSGV2,
        V_MSGV3 TYPE SY-MSGV3,
        V_MSGV4 TYPE SY-MSGV4,
        V_TEXT TYPE T100-TEXT.


*Variables
DATA: LINE(100) TYPE C.
DATA: V_TABLE_NAME_CHECK TYPE TBATG-TABNAME.
DATA: V_EXT TYPE DDREFSTRUC-FLAG.
DATA: V_CREATE(1) TYPE C.

*Field symbols
FIELD-SYMBOLS:%LTFS_VALUE%GT TYPE ANY.

*Constants
CONSTANTS: C_X(1)      VALUE 'X',
           C_SPACE(1)  VALUE '',
           C_YES(1)    VALUE 'Y'.

DATA: V_EXIST(1) TYPE C.
*---------------------------------------------------------------------*
*End of Data declarations for table maintenance generator
*---------------------------------------------------------------------*
DATA: V_CURRENT_CELL_INDEX TYPE SY-INDEX.
DATA: V_MERGED_CELLS TYPE SY-INDEX.
DATA: V_AN_INTEGER_STRING TYPE STRING.
DATA: V_AN_INT TYPE I.

*EXCEL XML file name
DATA: V_RLGRAP_EXCEL_XML_FILE TYPE STRING.

*Main iXML factory
DATA: G_IXML TYPE REF TO IF_IXML.

*XML data bytes size
DATA: V_XML_CODE_BYTES TYPE I.

*XML data
DATA: V_XML_DATA(500) OCCURS 0.

*Stream factory.
DATA: G_STREAMFACTORY TYPE REF TO IF_IXML_STREAM_FACTORY.

*XML istream
DATA: G_ISTREAM TYPE REF TO IF_IXML_ISTREAM.

*XML parser
DATA: G_PARSER TYPE REF TO IF_IXML_PARSER.

*XML DOM object
DATA: G_OBJ_DOM_XML TYPE REF TO IF_IXML_DOCUMENT.

*EXCEL root element
  DATA: G_OBJ_EXCEL_WORKBOOK TYPE REF TO IF_IXML_ELEMENT.

*Excel XML workbook name
DATA: G_EXCEL_WORKBOOK_NAME TYPE STRING.

*To hold the all the Worksheet under the Excel's Workbook element
DATA: G_OBJ_WORKSHEET_COLLECTIONS TYPE REF TO IF_IXML_NODE_COLLECTION.

*To hold the iterator for the Worksheet elements collection
DATA: G_OBJ_WORKSHEET_ITR TYPE REF TO IF_IXML_NODE_ITERATOR.

*To hold a Worksheet node.
DATA: V_OBJ_A_WORKSHEET_NODE TYPE REF TO IF_IXML_NODE.

*To hold a Worksheet element.
DATA: V_OBJ_A_WORKSHEET_ELEMENT TYPE REF TO IF_IXML_ELEMENT.

*To hold the Worksheet name
DATA: V_WORKSHEET_SS_NAME TYPE STRING.

*To hold a Worksheet/Table element.
DATA: V_OBJ_A_TABLE_ELEMENT TYPE REF TO IF_IXML_ELEMENT.

*To hold the all the Row elements under the Table element
DATA: V_OBJ_ROW_COLLECTIONS TYPE REF TO IF_IXML_NODE_COLLECTION.

*To hold the iterator for the Row elements collection
DATA: V_OBJ_ROW_ITR TYPE REF TO IF_IXML_NODE_ITERATOR.

*To hold a Row node.
DATA: V_OBJ_A_ROW_NODE TYPE REF TO IF_IXML_NODE.

*To hold a Row element.
DATA: V_OBJ_A_ROW_ELEMENT TYPE REF TO IF_IXML_ELEMENT.

*To hold the all the Cell elements under the Row element
DATA: V_OBJ_CELL_COLLECTIONS TYPE REF TO IF_IXML_NODE_COLLECTION.

*To hold the iterator for the Cell elements collection
DATA: V_OBJ_CELL_ITR TYPE REF TO IF_IXML_NODE_ITERATOR.

*To hold a Cell node.
DATA: V_OBJ_A_CELL_NODE TYPE REF TO IF_IXML_NODE.

*To hold a Cell element.
DATA: V_OBJ_A_CELL_ELEMENT TYPE REF TO IF_IXML_ELEMENT.

*To hold a Data element.
DATA: V_OBJ_A_DATA_ELEMENT TYPE REF TO IF_IXML_ELEMENT.

* To hold text nodes
DATA: V_OBJ_TEXT_LST TYPE REF TO IF_IXML_NODE_LIST.
DATA: V_OBJ_TEXT_ITR TYPE REF TO IF_IXML_NODE_ITERATOR.

* To hold a text value
DATA: V_TXT_VAL TYPE STRING.

*To hold a text node.
DATA: V_OBJ_A_TXT_NODE  TYPE REF TO IF_IXML_NODE.

*Type casting
DATA: G_CAST TYPE REF TO IF_IXML_UNKNOWN.

*To hold the node type
DATA: V_TXT_TYPE TYPE I.
DATA: V_SUBRC TYPE I.

**************SELECTION-SCREEN*****************************
*Input file name
SELECTION-SCREEN BEGIN OF BLOCK B1 WITH FRAME TITLE TEXT-001.
  PARAMETER: P_FILE TYPE RLGRAP-FILENAME.
SELECTION-SCREEN END OF BLOCK B1.

*Browse for input file
AT SELECTION-SCREEN ON VALUE-REQUEST FOR P_FILE.
  PERFORM F001_FILE_VALUE_REQUEST USING P_FILE.

**************AT SELECTION-SCREEN**************************

AT SELECTION-SCREEN.

*Validate files
  PERFORM F_FILE_CHECK.

*************START-OF-SELECTION**************************
START-OF-SELECTION.

*Read data from file
  PERFORM F004_GET_FILE_DATA.

*Create domains
  PERFORM F007_CREATE_DOMAINS.

*Create data elements
  PERFORM F008_CREATE_DATAELEMENTS.

*Create tables
  PERFORM F009_CREATE_TABLES.

*************END-OF-SELECTION**************************
END-OF-SELECTION.
  PERFORM F011_DISPLAY_MESSAGES.
  PERFORM F_FREE_MEMORY.

*---------------------------------------------------------------------*
*FORM F001_FILE_FOR_VALUE_REQUEST
*---------------------------------------------------------------------*
FORM F001_FILE_VALUE_REQUEST USING FILE TYPE RLGRAP-FILENAME.

  CALL FUNCTION 'KD_GET_FILENAME_ON_F4'
       EXPORTING
            MASK      = ''
            STATIC    = 'X'
       CHANGING
            FILE_NAME = FILE.
ENDFORM.

*----------------------------------------------------------------------*
*FORM F004_GET_FILE_DATA
*----------------------------------------------------------------------*
*Before proceeding further, the developers must understand completely
*the structure of an XML file and a few terms associated with the XML.

*XML Version     :
*Workbook        :
*Worksheet       :
*Table           :
*Column          :
*Row             :
*Cell            :
*Data            :
*----------------------------------------------------------------------*
*STEP 1: Read the XML file data into V_XML_CODE
*        The output in V_XML_CODE will be the complete XML raw data
*        which is not understandable manually.
*----------------------------------------------------------------------*
FORM F004_GET_FILE_DATA.

*Convert to right case
  V_RLGRAP_EXCEL_XML_FILE = P_FILE.

*Upload the excel file
    CALL METHOD cl_gui_frontend_services=%GTgui_upload
      EXPORTING
        filename   = V_RLGRAP_EXCEL_XML_FILE
        filetype   = 'BIN'
      IMPORTING
        filelength = V_XML_CODE_BYTES
      CHANGING
        data_tab   = V_XML_DATA.

  IF SY-SUBRC %LT%GT 0.
* Cannot open the Presentation Server file.
    WRITE: / 'Cannot open/read the Presentation Server file',
           V_RLGRAP_EXCEL_XML_FILE.
    EXIT.
  ENDIF.

*---------------------------------------------------------------------*
*STEP 2:Initialize the EXCEL DOM object and get
*       the root element.
*---------------------------------------------------------------------*
*CL_IXML is the standard class provided by SAP to handle
*any XML applications.
* Load ixml library
  CLASS CL_IXML DEFINITION LOAD.

*Create the main factory for the iXML library. G_IXML is exactly
*similar to the class CL_IXML.
*Note that CREATE is a static method, hence we use '=%GT'
  G_IXML = CL_IXML=%GTCREATE( ).

* Create a main stream factory.
  CALL METHOD G_IXML-%GTCREATE_STREAM_FACTORY
  RECEIVING
    RVAL   = G_STREAMFACTORY.

* Create a stream for the itab containg XML raw content.
  CALL METHOD G_STREAMFACTORY-%GTCREATE_ISTREAM_ITABLE
  EXPORTING
    SIZE   = V_XML_CODE_BYTES
    TABLE  = V_XML_DATA[]
  RECEIVING
    RVAL   = G_ISTREAM.

* Create a new DOM object.
  CALL METHOD G_IXML-%GTCREATE_DOCUMENT
  RECEIVING
    RVAL = G_OBJ_DOM_XML.

* Create a parser.
  CALL METHOD G_IXML-%GTCREATE_PARSER
  EXPORTING
    STREAM_FACTORY = G_STREAMFACTORY
    ISTREAM = G_ISTREAM
    DOCUMENT = G_OBJ_DOM_XML
  RECEIVING
    RVAL = G_PARSER.

* Parse the XML source.
  CALL METHOD G_PARSER-%GTPARSE
  RECEIVING
    RVAL   = V_SUBRC.

  IF V_SUBRC %LT%GT 0.
* Parsing failed for XML file, Make sure valid XML is found.
    WRITE: / 'Parsing failed for XML file, Make sure valid ' &
             'XML is found.'.
    EXIT.
  ENDIF.

* close the opened stream and thereby the opened xml file.
  CALL METHOD G_ISTREAM-%GTCLOSE.


* Get the root element of the Excel XML.
  CALL METHOD G_OBJ_DOM_XML-%GTGET_ROOT_ELEMENT
  RECEIVING
    RVAL = G_OBJ_EXCEL_WORKBOOK.

  IF G_OBJ_EXCEL_WORKBOOK IS INITIAL.
*   The DOM object for the Excel_XML does not seems to be initialized.
    WRITE: / 'The DOM object for the Excel_XML does not seems' &
             'to be initialized.'.
    EXIT.
  ENDIF.

* validate for Excel
* Get the root element name
  CALL METHOD G_OBJ_EXCEL_WORKBOOK-%GTGET_NAME
    RECEIVING
      RVAL = G_EXCEL_WORKBOOK_NAME.

  CONDENSE G_EXCEL_WORKBOOK_NAME.

* Check if the name is Workbook
  IF G_EXCEL_WORKBOOK_NAME %LT%GT 'Workbook'.
    WRITE: / 'The EXCEL XML root element name should be ' &
             'Workbook and not', G_EXCEL_WORKBOOK_NAME.
    EXIT.
  ENDIF.

*---------------------------------------------------------------------*
*STEP 3:Get worksheets
*---------------------------------------------------------------------*
* Get all the Worksheet elements
  CALL METHOD G_OBJ_EXCEL_WORKBOOK-%GTGET_ELEMENTS_BY_TAG_NAME
  EXPORTING
    NAME = 'Worksheet'
*    NAMESPACE = ''
    DEPTH = 1
  RECEIVING
    RVAL = G_OBJ_WORKSHEET_COLLECTIONS.

* Make sure the collection is valid
  IF G_OBJ_WORKSHEET_COLLECTIONS IS INITIAL.
    WRITE: / 'The Excel workbook does not contain any Worksheets.'.
    EXIT.
  ENDIF.

* create an iterator for Worksheet elements
  CALL METHOD G_OBJ_WORKSHEET_COLLECTIONS-%GTCREATE_ITERATOR
  RECEIVING
    RVAL = G_OBJ_WORKSHEET_ITR.

* Make sure the iterator is valid.
  IF G_OBJ_WORKSHEET_ITR IS INITIAL.
    WRITE: / 'The Excel workbook does not contain any Worksheets.'.
    EXIT.
  ENDIF.


* step  3.1  get the first worksheet
 CALL METHOD G_OBJ_WORKSHEET_ITR-%GTGET_NEXT
  RECEIVING
    RVAL = V_OBJ_A_WORKSHEET_NODE.

* Validate of not null before proceeding.
  IF V_OBJ_A_WORKSHEET_NODE IS INITIAL.
    WRITE: / 'The Excel workbook does not contain any Worksheets.'.
    EXIT.
  ENDIF.

* Lets type cast THE NODE OBJECT to ELEMENT OBJECT
    CLEAR G_CAST.
    CALL METHOD V_OBJ_A_WORKSHEET_NODE-%GTQUERY_INTERFACE
      EXPORTING
        IID    = 130 "IXML_IID_ELEMENT
      RECEIVING
        RVAL   = G_CAST.
    V_OBJ_A_WORKSHEET_ELEMENT ?= G_CAST.

* Make sure the casting was success
  IF V_OBJ_A_WORKSHEET_ELEMENT IS INITIAL.
    WRITE: / 'The Excel workbook does not contain any Worksheets.'.
    EXIT.
  ENDIF.

* Get the value for the attribute ss:Name
  CALL METHOD V_OBJ_A_WORKSHEET_ELEMENT-%GTGET_ATTRIBUTE
  EXPORTING
  NAME = 'Name'
  NAMESPACE = 'ss'
  RECEIVING
    RVAL = V_WORKSHEET_SS_NAME.

  CONDENSE V_WORKSHEET_SS_NAME.

  TRANSLATE V_WORKSHEET_SS_NAME TO UPPER CASE.

* step  3.3  Loop (1) get each worksheet one by one,
*            Note: it’s assumed that the name of the worksheet is
*            same as the table name.

* lets loop through all the Worksheet elements
  DO."Worksheets

*    DATA_COUNT = 0.

    IF SY-INDEX = 1. " Special case for the first
      IF V_WORKSHEET_SS_NAME = '#QUERY'.
*     get the next element of the iterator.
        CALL METHOD G_OBJ_WORKSHEET_ITR-%GTGET_NEXT
          RECEIVING
            RVAL = V_OBJ_A_WORKSHEET_NODE.
      ENDIF.
    ELSE.
*     get the next element of the iterator.
      CALL METHOD G_OBJ_WORKSHEET_ITR-%GTGET_NEXT
        RECEIVING
          RVAL = V_OBJ_A_WORKSHEET_NODE.
    ENDIF.


*   Validate of not null before proceeding.
    IF V_OBJ_A_WORKSHEET_NODE IS INITIAL.
      EXIT.
    ENDIF.

*   Lets type cast THE NODE OBJECT to ELEMENT OBJECT
    CLEAR G_CAST.
    CALL METHOD V_OBJ_A_WORKSHEET_NODE-%GTQUERY_INTERFACE
      EXPORTING
        IID    = 130 "IXML_IID_ELEMENT
      RECEIVING
        RVAL   = G_CAST.
    V_OBJ_A_WORKSHEET_ELEMENT ?= G_CAST.

*   Make sure the casting was success
    IF V_OBJ_A_WORKSHEET_ELEMENT IS INITIAL.
      CONTINUE.
    ENDIF.

*   Get the value for the attribute ss:Name
    CALL METHOD V_OBJ_A_WORKSHEET_ELEMENT-%GTGET_ATTRIBUTE
    EXPORTING
      NAME = 'Name'
      NAMESPACE = 'ss'
    RECEIVING
        RVAL = V_WORKSHEET_SS_NAME.

    CONDENSE V_WORKSHEET_SS_NAME.

*   The worksheet name is empty, so just dont consider
*   that worksheet
    IF V_WORKSHEET_SS_NAME = ''.
      CONTINUE.
    ENDIF.

*---------------------------------------------------------------------*
*STEP 4:Get the first row of the table element.
*---------------------------------------------------------------------*
*   clear all cached records of the itab
*   IT_EXCEL_FIELD for every new worksheet
    CLEAR: IS_EXCEL_FIELD, IT_EXCEL_FIELD[].

*   Get the Table element, under the Worksheet.
    CALL METHOD V_OBJ_A_WORKSHEET_ELEMENT-%GTFIND_FROM_NAME
    EXPORTING
      NAME = 'Table'
      NAMESPACE = ''
      DEPTH = 1
    RECEIVING
      RVAL = V_OBJ_A_TABLE_ELEMENT.

    IF V_OBJ_A_TABLE_ELEMENT IS INITIAL.
      CONTINUE.
    ENDIF.


*   Get all the Row elements
    CALL METHOD V_OBJ_A_TABLE_ELEMENT-%GTGET_ELEMENTS_BY_TAG_NAME
      EXPORTING
        NAME = 'Row'
*         NAMESPACE = ''
        DEPTH = 1
      RECEIVING
        RVAL = V_OBJ_ROW_COLLECTIONS.

*   Make sure the collection is valid
    IF V_OBJ_ROW_COLLECTIONS IS INITIAL.
      CONTINUE.
    ENDIF.

*   create an iterator for Row elements
    CALL METHOD V_OBJ_ROW_COLLECTIONS-%GTCREATE_ITERATOR
      RECEIVING
        RVAL = V_OBJ_ROW_ITR.

*   Make sure the iterator is valid.
    IF V_OBJ_ROW_ITR IS INITIAL.
      CONTINUE.
    ENDIF.

*   Get the first Row element.
    CALL METHOD V_OBJ_ROW_ITR-%GTGET_NEXT
      RECEIVING
        RVAL = V_OBJ_A_ROW_NODE.

*   Make sure the Row element is valid
    IF V_OBJ_A_ROW_NODE IS INITIAL.
      CONTINUE.
    ENDIF.

*   Lets type cast THE NODE OBJECT to ELEMENT OBJECT
    CLEAR G_CAST.
    CALL METHOD V_OBJ_A_ROW_NODE-%GTQUERY_INTERFACE
      EXPORTING
        IID    = 130 "IXML_IID_ELEMENT
      RECEIVING
        RVAL   = G_CAST.
    V_OBJ_A_ROW_ELEMENT ?= G_CAST.

*   Make sure the casting was success
    IF V_OBJ_A_ROW_ELEMENT IS INITIAL.
      CONTINUE.
    ENDIF.


*---------------------------------------------------------------------*
*STEP 5:Get the column names of the current table these are
*       the fields defined under the table and cache them
*       with together with the index.
*       Also take into consideration the fields missing
*       and merging of cells.
*---------------------------------------------------------------------*
*   Get all the Cell elements
    CALL METHOD V_OBJ_A_ROW_ELEMENT-%GTGET_ELEMENTS_BY_TAG_NAME
      EXPORTING
        NAME = 'Cell'
        DEPTH = 1
      RECEIVING
        RVAL = V_OBJ_CELL_COLLECTIONS.

*   Make sure the collection is valid
    IF V_OBJ_CELL_COLLECTIONS IS INITIAL.
      CONTINUE.
    ENDIF.

*   create an iterator for Cell elements
    CALL METHOD V_OBJ_CELL_COLLECTIONS-%GTCREATE_ITERATOR
      RECEIVING
        RVAL = V_OBJ_CELL_ITR.

*   Make sure the iterator is valid.
    IF V_OBJ_CELL_ITR IS INITIAL.
      CONTINUE.
    ENDIF.

*   Reset the current Cell index before the first column
*   The first column index is always one (1)
*   Thus to reset it before the first column is value 0
    V_CURRENT_CELL_INDEX = 0.

*   Reset the merged Cells to 0, which means no
*   cells are merged.
    V_MERGED_CELLS = 0.


*   loop through all the Cell elements
    DO.

*     First clear any garbage objects
      CLEAR V_OBJ_A_CELL_NODE.
      CLEAR V_OBJ_A_CELL_ELEMENT.

*     Lets skip the index for the merged Cells
      V_CURRENT_CELL_INDEX =
      V_CURRENT_CELL_INDEX + V_MERGED_CELLS.

*     Get the next Cell element.
      CALL METHOD V_OBJ_CELL_ITR-%GTGET_NEXT
        RECEIVING
          RVAL = V_OBJ_A_CELL_NODE.

*     Make sure the Cell element is valid
      IF V_OBJ_A_CELL_NODE IS INITIAL.
        EXIT.
      ENDIF.

*     Lets type cast THE NODE OBJECT to ELEMENT OBJECT
      CLEAR G_CAST.
      CALL METHOD V_OBJ_A_CELL_NODE-%GTQUERY_INTERFACE
        EXPORTING
          IID    = 130 "IXML_IID_ELEMENT
        RECEIVING
          RVAL   = G_CAST.
      V_OBJ_A_CELL_ELEMENT ?= G_CAST.

*     Make sure the casting was success
      IF V_OBJ_A_CELL_ELEMENT IS INITIAL.
        EXIT.
      ENDIF.

*     Calculate the current absolute Horizontal Index
*     of the cell.

*     First priority is to get any index value mentioned
*     in the Cell as ss:Index attribute.

*     Second priority is to predict based on the prevous
*     value.

*     get the attribute ss:Index of the current Cell element
      V_AN_INT = 0.
      CALL METHOD V_OBJ_A_CELL_ELEMENT-%GTGET_ATTRIBUTE
      EXPORTING
        NAME = 'Index'
        NAMESPACE = 'ss'
      RECEIVING
          RVAL = V_AN_INTEGER_STRING.

      CONDENSE V_AN_INTEGER_STRING.

*     A Index attribute was received.
      IF V_AN_INTEGER_STRING %LT%GT ''.
        CATCH SYSTEM-EXCEPTIONS CONVT_NO_NUMBER = 1.
          V_AN_INT = V_AN_INTEGER_STRING.
        ENDCATCH.
      ENDIF.

*     Make sure a valid index is avaliable
      IF V_AN_INT %GT 0.
*       Its visually set in the Excel Cell itself, so use it.
        V_CURRENT_CELL_INDEX = V_AN_INT.
      ELSE.
*       no index is mentioned, so assume the next value
        V_CURRENT_CELL_INDEX = V_CURRENT_CELL_INDEX + 1.
      ENDIF.


*     if required, cache the number of merged cells,
*     as per the value mentioned in the attribute
*     ss:MergeAcross.
*
*     This can definitly occur when two or more cells
*     are merged into one.

*     Lets first assume there is no merged Cells
      V_MERGED_CELLS = 0.

*     get the attribute ss:MergeAcross of the current
*     Cell element
      V_AN_INT = 0.

      CALL METHOD V_OBJ_A_CELL_ELEMENT-%GTGET_ATTRIBUTE
      EXPORTING
        NAME = 'MergeAcross'
        NAMESPACE = 'ss'
      RECEIVING
          RVAL = V_AN_INTEGER_STRING.

      CONDENSE V_AN_INTEGER_STRING.

*     A MergeAcross attribute was received.
      IF V_AN_INTEGER_STRING %LT%GT ''.
        CATCH SYSTEM-EXCEPTIONS CONVT_NO_NUMBER = 1.
          V_AN_INT = V_AN_INTEGER_STRING.
        ENDCATCH.
      ENDIF.

*     Make sure a valid MergeAcross attribute is avaliable
      IF V_AN_INT %GT 0.
        V_MERGED_CELLS = V_AN_INT.
      ELSE.
        V_MERGED_CELLS = 0.
      ENDIF.


*     get the Data element under the Cell element.
      CALL METHOD V_OBJ_A_CELL_ELEMENT-%GTFIND_FROM_NAME
        EXPORTING
          NAME = 'Data'
*            namespace = ''
          DEPTH = 1
        RECEIVING
          RVAL = V_OBJ_A_DATA_ELEMENT.

      IF V_OBJ_A_DATA_ELEMENT IS INITIAL.
        CONTINUE.
      ENDIF.

*     get the text element under the Data element.
      CALL METHOD V_OBJ_A_DATA_ELEMENT-%GTGET_CHILDREN
        RECEIVING
          RVAL = V_OBJ_TEXT_LST.

      IF V_OBJ_TEXT_LST IS INITIAL.
        CONTINUE.
      ENDIF.

*     Create an iterator
      CALL METHOD V_OBJ_TEXT_LST-%GTCREATE_ITERATOR
        RECEIVING
          RVAL = V_OBJ_TEXT_ITR.

      IF V_OBJ_TEXT_ITR IS INITIAL.
        CONTINUE.
      ENDIF.

      V_TXT_VAL = ''.
      DO.
*       get the next element of the iterator.
        CALL METHOD V_OBJ_TEXT_ITR-%GTGET_NEXT
          RECEIVING
            RVAL = V_OBJ_A_TXT_NODE.

*       Validate of not null before proceeding.
        IF V_OBJ_A_TXT_NODE IS INITIAL.
          EXIT.
        ENDIF.

*       Get the current node type
        CALL METHOD V_OBJ_A_TXT_NODE-%GTGET_TYPE
          RECEIVING
            RVAL = V_TXT_TYPE.

*       We are only concentrating on text type nodes
        IF V_TXT_TYPE %LT%GT IF_IXML_NODE=%GTCO_NODE_TEXT.
          CONTINUE.
        ENDIF.

*       We are only expecting one text node.
*       If the DOM id is parsed from a document, only
*       one text node will be present.

*       Also its not standard to add more than one
*       text nodes
        CALL METHOD V_OBJ_A_TXT_NODE-%GTGET_VALUE
          RECEIVING
            RVAL = V_TXT_VAL.
        EXIT.
      ENDDO.

      CONDENSE V_TXT_VAL.

*     Make sure the field name is not empty
      IF V_TXT_VAL = ''.
        CONTINUE.
      ENDIF.

*     cache these values in the itab IT_EXCEL_FIELD
*     with excel index as the master key for the field name
*     resolving.
      CLEAR IS_EXCEL_FIELD.
      IS_EXCEL_FIELD-EXCEL_INDEX = V_CURRENT_CELL_INDEX.
      IS_EXCEL_FIELD-FIELD_NAME = V_TXT_VAL.

      INSERT IS_EXCEL_FIELD INTO TABLE IT_EXCEL_FIELD.


    ENDDO.


    IF NOT IT_EXCEL_FIELD[] IS INITIAL.

* Loop (2) through all the remaining rows of the
*          Current table.
      DO.

*       Clear any previous header field details.
        LOOP AT IT_EXCEL_FIELD INTO IS_EXCEL_FIELD.
          CLEAR IS_EXCEL_FIELD-FIELD_VALUE.
         MODIFY IT_EXCEL_FIELD FROM IS_EXCEL_FIELD INDEX SY-TABIX.
        ENDLOOP.


*       Clear an previous values
        CLEAR V_OBJ_A_ROW_NODE.
        CLEAR V_OBJ_A_ROW_ELEMENT.

*       Get the next row node
        CALL METHOD V_OBJ_ROW_ITR-%GTGET_NEXT
          RECEIVING
            RVAL = V_OBJ_A_ROW_NODE.

*       Make sure the Row element is valid
        IF V_OBJ_A_ROW_NODE IS INITIAL.
          EXIT.
        ENDIF.

*       Lets type cast THE NODE OBJECT to ELEMENT OBJECT
*        V_OBJ_A_ROW_ELEMENT ?=
*        V_OBJ_A_ROW_NODE-%GTQUERY_INTERFACE( IXML_IID_ELEMENT ).


CLEAR G_CAST.
CALL METHOD V_OBJ_A_ROW_NODE-%GTQUERY_INTERFACE
  EXPORTING
    IID    = 130 "IXML_IID_ELEMENT
  RECEIVING
    RVAL   = G_CAST.
V_OBJ_A_ROW_ELEMENT ?= G_CAST.

*       Make sure the casting was success
        IF V_OBJ_A_ROW_ELEMENT IS INITIAL.
          CONTINUE.
        ENDIF.

*       Loop through each Cell/Data element.

*       Clear any garbage objects
        CLEAR V_OBJ_CELL_COLLECTIONS.
        CLEAR V_OBJ_CELL_ITR.

*       Get all the Cell elements
        CALL METHOD V_OBJ_A_ROW_ELEMENT-%GTGET_ELEMENTS_BY_TAG_NAME
          EXPORTING
            NAME = 'Cell'
*           NAMESPACE = ''
            DEPTH = 1
          RECEIVING
            RVAL = V_OBJ_CELL_COLLECTIONS.

*       Make sure the collection is valid
        IF V_OBJ_CELL_COLLECTIONS IS INITIAL.
          CONTINUE.
        ENDIF.

*       create an iterator for Cell elements
        CALL METHOD V_OBJ_CELL_COLLECTIONS-%GTCREATE_ITERATOR
          RECEIVING
            RVAL = V_OBJ_CELL_ITR.

*       Make sure the iterator is valid.
        IF V_OBJ_CELL_ITR IS INITIAL.
          CONTINUE.
        ENDIF.

*       Reset the current Cell index before the first column
*       The first column index is always one (1)
*       Thus to reset it before the first column is value 0
        V_CURRENT_CELL_INDEX = 0.

*       Reset the merged Cells to 0, which means no
*       cells are merged.
        V_MERGED_CELLS = 0.


*       loop(3) through all the Cell elements
        DO.

*         Lets skip the index for the merged Cells
          V_CURRENT_CELL_INDEX =
          V_CURRENT_CELL_INDEX + V_MERGED_CELLS.

*         First clear any garbage objects
          CLEAR V_OBJ_A_CELL_NODE.
          CLEAR V_OBJ_A_CELL_ELEMENT.

*         Get the next Cell element.
          CALL METHOD V_OBJ_CELL_ITR-%GTGET_NEXT
            RECEIVING
              RVAL = V_OBJ_A_CELL_NODE.

*         Make sure the Cell element is valid
          IF V_OBJ_A_CELL_NODE IS INITIAL.
            EXIT.
          ENDIF.

*         Lets type cast THE NODE OBJECT to ELEMENT OBJECT
*          V_OBJ_A_CELL_ELEMENT ?=
*          V_OBJ_A_CELL_NODE-%GTQUERY_INTERFACE( IXML_IID_ELEMENT ).


CLEAR G_CAST.
CALL METHOD V_OBJ_A_CELL_NODE-%GTQUERY_INTERFACE
  EXPORTING
    IID    = 130 "IXML_IID_ELEMENT
  RECEIVING
    RVAL   = G_CAST.
V_OBJ_A_CELL_ELEMENT ?= G_CAST.

*         Make sure the casting was success
          IF V_OBJ_A_CELL_ELEMENT IS INITIAL.
            EXIT.
          ENDIF.


*         Calculate the current absolute Horizontal Index
*         of the cell.

*         First priority is to get any index value mentioned
*         in the Cell as ss:Index attribute.

*         Second priority is to predict based on the prevous
*         value.

*         get the attribute ss:Index of the current Cell element
          V_AN_INT = 0.
          CALL METHOD V_OBJ_A_CELL_ELEMENT-%GTGET_ATTRIBUTE
          EXPORTING
            NAME = 'Index'
            NAMESPACE = 'ss'
          RECEIVING
              RVAL = V_AN_INTEGER_STRING.

          CONDENSE V_AN_INTEGER_STRING.

*         A Index attribute was received.
          IF V_AN_INTEGER_STRING %LT%GT ''.
            CATCH SYSTEM-EXCEPTIONS CONVT_NO_NUMBER = 1.
              V_AN_INT = V_AN_INTEGER_STRING.
            ENDCATCH.
          ENDIF.

*         Make sure a valid index is avaliable
          IF V_AN_INT %GT 0.
*           Its visually set in the Excel Cell itself, so use it.
            V_CURRENT_CELL_INDEX = V_AN_INT.
          ELSE.
*           no index is mentioned, so assume the next value
            V_CURRENT_CELL_INDEX = V_CURRENT_CELL_INDEX + 1.
          ENDIF.

*         if required, cache the number of merged cells,
*         as per the value mentioned in the attribute
*         ss:MergeAcross.
*
*         This can definitly occur when two or more cells
*         are merged into one.


*         Lets first assume there is no merged Cells
          V_MERGED_CELLS = 0.

*         get the attribute ss:MergeAcross of the current
*         Cell element
          V_AN_INT = 0.

          CALL METHOD V_OBJ_A_CELL_ELEMENT-%GTGET_ATTRIBUTE
          EXPORTING
            NAME = 'MergeAcross'
            NAMESPACE = 'ss'
          RECEIVING
              RVAL = V_AN_INTEGER_STRING.

          CONDENSE V_AN_INTEGER_STRING.

*         A MergeAcross attribute was received.
          IF V_AN_INTEGER_STRING %LT%GT ''.
            CATCH SYSTEM-EXCEPTIONS CONVT_NO_NUMBER = 1.
              V_AN_INT = V_AN_INTEGER_STRING.
            ENDCATCH.
          ENDIF.

*         Make sure a valid MergeAcross attribute is avaliable
          IF V_AN_INT %GT 0.
            V_MERGED_CELLS = V_AN_INT.
          ELSE.
            V_MERGED_CELLS = 0.
          ENDIF.


*         Resolve the field id based on its Horizontal Index
*         from the itab IT_EXCEL_FIELD.


*         get the Data element under the Cell element.
          CALL METHOD V_OBJ_A_CELL_ELEMENT-%GTFIND_FROM_NAME
            EXPORTING
              NAME = 'Data'
*              namespace = ''
              DEPTH = 1
            RECEIVING
              RVAL = V_OBJ_A_DATA_ELEMENT.

          IF V_OBJ_A_DATA_ELEMENT IS INITIAL.
            CONTINUE.
          ENDIF.

*         get the text element under the Data element.
          CALL METHOD V_OBJ_A_DATA_ELEMENT-%GTGET_CHILDREN
            RECEIVING
              RVAL = V_OBJ_TEXT_LST.

          IF V_OBJ_TEXT_LST IS INITIAL.
            CONTINUE.
          ENDIF.

*         Create an iterator
          CALL METHOD V_OBJ_TEXT_LST-%GTCREATE_ITERATOR
            RECEIVING
              RVAL = V_OBJ_TEXT_ITR.

          IF V_OBJ_TEXT_ITR IS INITIAL.
            CONTINUE.
          ENDIF.

          V_TXT_VAL = ''.
          DO.

*           get the next element of the iterator.
            CALL METHOD V_OBJ_TEXT_ITR-%GTGET_NEXT
              RECEIVING
                RVAL = V_OBJ_A_TXT_NODE.

*           Validate of not null before proceeding.
            IF V_OBJ_A_TXT_NODE IS INITIAL.
              EXIT.
            ENDIF.

*           Get the current node type
            CALL METHOD V_OBJ_A_TXT_NODE-%GTGET_TYPE
              RECEIVING
                RVAL = V_TXT_TYPE.

*           We are only concentrating on text type nodes
            IF V_TXT_TYPE %LT%GT IF_IXML_NODE=%GTCO_NODE_TEXT.
              CONTINUE.
            ENDIF.

*           We are only expecting one text node.
*           If the DOM id is parsed from a document, only
*           one text node will be present.

*           Also its not standard to add more than one
*           text nodes
            CALL METHOD V_OBJ_A_TXT_NODE-%GTGET_VALUE
              RECEIVING
                RVAL = V_TXT_VAL.
            EXIT.
          ENDDO.

          CONDENSE V_TXT_VAL.

*         Make sure the field name is not empty
          IF V_TXT_VAL = ''.
            CONTINUE.
          ENDIF.

*         Clear any previous header line
          CLEAR IS_EXCEL_FIELD.

*         Read the table IT_EXCEL_FIELD for the
*         corrosponding entry.
          READ TABLE IT_EXCEL_FIELD INTO IS_EXCEL_FIELD
          WITH KEY EXCEL_INDEX = V_CURRENT_CELL_INDEX
          BINARY SEARCH.

*         Make sure the read was success
          IF SY-SUBRC %LT%GT 0.
            CONTINUE.
          ENDIF.

          CLEAR IS_EXCEL_FIELD-FIELD_VALUE.
          IS_EXCEL_FIELD-FIELD_VALUE = V_TXT_VAL.
          MODIFY IT_EXCEL_FIELD FROM IS_EXCEL_FIELD
          INDEX V_CURRENT_CELL_INDEX.

*         Endo of loop (3)
        ENDDO.


*---------------------------------------------------------------------*
*STEP 6:
*At this stage, we have all the XML data in the internal table
*IT_EXCEL_FIELD. Now, populate the internal tables representing
*individual data dictionary objects.
*---------------------------------------------------------------------*
        CLEAR IS_EXCEL_FIELD.
        READ TABLE IT_EXCEL_FIELD INTO IS_EXCEL_FIELD INDEX 1.
        IF SY-SUBRC = 0.

*If the data corresponds to DOMAINS
          IF IS_EXCEL_FIELD-FIELD_NAME = 'DOMNAME'.

*Loop over the Excel table and
*populate the internal tables representing DOMAINS
            CLEAR IS_EXCEL_FIELD.
            LOOP AT IT_EXCEL_FIELD INTO IS_EXCEL_FIELD.

              CONCATENATE 'IS_DOMAINS-' IS_EXCEL_FIELD-FIELD_NAME
              INTO LINE.
              UNASSIGN %LTFS_VALUE%GT.
              ASSIGN (LINE) TO %LTFS_VALUE%GT.
              IF %LTFS_VALUE%GT IS ASSIGNED.

                %LTFS_VALUE%GT = IS_EXCEL_FIELD-FIELD_VALUE.

              ENDIF.

            ENDLOOP.

            APPEND IS_DOMAINS TO IT_DOMAINS.
            CLEAR IS_DOMAINS.


            CLEAR IS_EXCEL_FIELD.
            LOOP AT IT_EXCEL_FIELD INTO IS_EXCEL_FIELD.

              CONCATENATE 'IS_DOMA_VALUES-' IS_EXCEL_FIELD-FIELD_NAME
              INTO LINE.
              UNASSIGN %LTFS_VALUE%GT.
              ASSIGN (LINE) TO %LTFS_VALUE%GT.
              IF %LTFS_VALUE%GT IS ASSIGNED.

                %LTFS_VALUE%GT = IS_EXCEL_FIELD-FIELD_VALUE.

              ENDIF.

            ENDLOOP.

            APPEND IS_DOMA_VALUES TO IT_DOMA_VALUES.
            CLEAR IS_DOMA_VALUES.

          ENDIF. "IT_EXCEL_FIELD-FIELD_NAME = 'DOMANAME'

*If the data corresponds to DATAELEMENTS
          IF IS_EXCEL_FIELD-FIELD_NAME = 'ROLLNAME'.

*Loop over the Excel table and
*populate the internal tables representing DATA ELEMENTS
            CLEAR IS_EXCEL_FIELD.
            LOOP AT IT_EXCEL_FIELD INTO IS_EXCEL_FIELD.

              CONCATENATE 'IS_DATAELEMENTS-' IS_EXCEL_FIELD-FIELD_NAME
              INTO LINE.
              UNASSIGN %LTFS_VALUE%GT.
              ASSIGN (LINE) TO %LTFS_VALUE%GT.
              IF %LTFS_VALUE%GT IS ASSIGNED.

                %LTFS_VALUE%GT = IS_EXCEL_FIELD-FIELD_VALUE.

              ENDIF.

            ENDLOOP.

            APPEND IS_DATAELEMENTS TO IT_DATAELEMENTS.
            CLEAR IS_DATAELEMENTS.


          ENDIF. "IT_EXCEL_FIELD-FIELD_NAME = 'DTELNAME'.

*If the data corresponds to TABLES
          IF IS_EXCEL_FIELD-FIELD_NAME = 'TABNAME'.

*Loop over the Excel table and
*populate the internal tables representing TABLES
            CLEAR IS_EXCEL_FIELD.
            LOOP AT IT_EXCEL_FIELD INTO IS_EXCEL_FIELD.

              CONCATENATE 'IS_TABLES-' IS_EXCEL_FIELD-FIELD_NAME
              INTO LINE.
              UNASSIGN %LTFS_VALUE%GT.
              ASSIGN (LINE) TO %LTFS_VALUE%GT.
              IF %LTFS_VALUE%GT IS ASSIGNED.

                %LTFS_VALUE%GT = IS_EXCEL_FIELD-FIELD_VALUE.

              ENDIF.

            ENDLOOP.

            APPEND IS_TABLES TO IT_TABLES.
            CLEAR IS_TABLES.

            CLEAR IS_EXCEL_FIELD.
            LOOP AT IT_EXCEL_FIELD INTO IS_EXCEL_FIELD.

              CONCATENATE 'IS_TABL_TECHNICS-' IS_EXCEL_FIELD-FIELD_NAME
              INTO LINE.
              UNASSIGN %LTFS_VALUE%GT.
              ASSIGN (LINE) TO %LTFS_VALUE%GT.
              IF %LTFS_VALUE%GT IS ASSIGNED.

                %LTFS_VALUE%GT = IS_EXCEL_FIELD-FIELD_VALUE.

              ENDIF.

            ENDLOOP.

            APPEND IS_TABL_TECHNICS TO IT_TABL_TECHNICS.
            CLEAR IS_TABL_TECHNICS.


            CLEAR IS_EXCEL_FIELD.
            LOOP AT IT_EXCEL_FIELD INTO IS_EXCEL_FIELD.

              CONCATENATE 'IS_TABL_FIELDS-' IS_EXCEL_FIELD-FIELD_NAME
              INTO LINE.
              UNASSIGN %LTFS_VALUE%GT.
              ASSIGN (LINE) TO %LTFS_VALUE%GT.
              IF %LTFS_VALUE%GT IS ASSIGNED.

                %LTFS_VALUE%GT = IS_EXCEL_FIELD-FIELD_VALUE.

              ENDIF.

            ENDLOOP.

            APPEND IS_TABL_FIELDS TO IT_TABL_FIELDS.
            CLEAR IS_TABL_FIELDS.


          ENDIF. "IT_EXCEL_FIELD-FIELD_NAME = 'TABLNAME'.


        ENDIF. "READ TABLE IT_EXCEL_FIELD


      ENDDO.

    ENDIF. "IF NOT IT_EXCEL_FIELD[] IS INITIAL.

  ENDDO."Worksheets

*---------------------------------------------------------------------*
*STEP 7: Perform Data readiness
*---------------------------------------------------------------------*
*Delete duplicates
  DELETE ADJACENT DUPLICATES FROM IT_TABLES COMPARING TABNAME.
  DELETE ADJACENT DUPLICATES FROM IT_TABL_TECHNICS COMPARING TABNAME.

  DELETE IT_TABLES WHERE TABNAME = SPACE.
  DELETE IT_TABL_TECHNICS WHERE TABNAME = SPACE.

*The table category is always TRANSPARANT.
  CLEAR:IS_TABLES.
  LOOP AT IT_TABLES INTO IS_TABLES.
    IS_TABLES-TABCLASS = 'TRANSP'.
    MODIFY IT_TABLES INDEX SY-TABIX FROM IS_TABLES.
  ENDLOOP.

*Sort data by object name
  SORT IT_DOMAINS BY DOMNAME.
  SORT IT_DOMA_VALUES BY DOMNAME.
  SORT IT_DATAELEMENTS BY ROLLNAME.

  SORT IT_TABLES BY TABNAME.
  SORT IT_TABL_TECHNICS BY TABNAME.
  SORT IT_TABL_FIELDS BY TABNAME POSITION.

ENDFORM.

*---------------------------------------------------------------------*
*F007_CREATE_DOMAINS.
*---------------------------------------------------------------------*
FORM F007_CREATE_DOMAINS.

DATA: LS_RETURN TYPE BAPIRET2.

  CLEAR:IS_DOMAINS, V_EXT.
  LOOP AT IT_DOMAINS INTO IS_DOMAINS.

    CLEAR: LS_RETURN.
*Check whether domain exists or not
    CALL FUNCTION 'DD_CHECK_NAME'
         EXPORTING
              NAME            = IS_DOMAINS-DOMNAME
              OBJTYP          = 'DOMA'
         IMPORTING
              OBJ_EXISTS      = V_EXT.

*If domain exists, populate information message
    IF V_EXT EQ C_X.
              CLEAR V_TEXT.
              V_TEXT = 'Already Created'.
              V_MSGID = SPACE.
              V_MSGTY = 'I'.
              V_MSGNO = SPACE.
              V_MSGV1 = 'R3TR'.
              V_MSGV2 = 'DOMA'.
              V_MSGV3 = IS_DOMAINS-DOMNAME.
              V_MSGV4 = SPACE.
              PERFORM F012_POPULATE_MESSAGES
               USING
                 V_MSGID
                 V_MSGTY
                 V_MSGNO
                 V_MSGV1
                 V_MSGV2
                 V_MSGV3
                 V_MSGV4
                 V_TEXT.
    ENDIF.

*If domain doesn’t exist
    IF V_EXT %LT%GT C_X.
       CLEAR: V_CREATE.
       V_CREATE = C_YES.
    ENDIF. "V_EXT %LT%GT C_X

*Create the domain
      IF V_CREATE = C_YES.

*Get domain attributes
        CLEAR IS_DOMAINS_TMP.
        MOVE IS_DOMAINS TO IS_DOMAINS_TMP.

*Get domain range of values
*        CLEAR:IS_DOMA_VALUES.
*        LOOP AT IT_DOMA_VALUES INTO IS_DOMA_VALUES
*           WHERE DOMNAME = IS_DOMAINS-DOMNAME.
*
*          APPEND IS_DOMA_VALUES TO IT_DOMA_VALUES_TMP.
*
*        ENDLOOP.

* Create domain
          CALL FUNCTION 'COM_GEN_DOMAIN_CREATE'
            EXPORTING
              IV_DOMAIN_NAME       = IS_DOMAINS-DOMNAME
              IV_DEVCLASS          = '$TMP'
              IV_ACTIVATE          = 'X'
              IS_DD01V             = IS_DOMAINS_TMP
              IT_DD07V             = IT_DOMA_VALUES_TMP
              IV_GENFLAG           = 'T'
            IMPORTING
              ES_RETURN            = LS_RETURN.

*Populate success message
          IF LS_RETURN-TYPE NE 'E'.
              CLEAR V_TEXT.
              V_TEXT = 'Created Successfully'.
              V_MSGID = SPACE.
              V_MSGTY = 'S'.
              V_MSGNO = SPACE.
              V_MSGV1 = 'R3TR'.
              V_MSGV2 = 'DOMA'.
              V_MSGV3 = IS_DOMAINS-DOMNAME.
              V_MSGV4 = SPACE.
              PERFORM F012_POPULATE_MESSAGES
               USING
                 V_MSGID
                 V_MSGTY
                 V_MSGNO
                 V_MSGV1
                 V_MSGV2
                 V_MSGV3
                 V_MSGV4
                 V_TEXT.
          ENDIF.

*Populate messages
          IF LS_RETURN-TYPE EQ 'E'.
            CLEAR V_TEXT.
            PERFORM F012_POPULATE_MESSAGES
             USING
               LS_RETURN-ID
               LS_RETURN-TYPE
               LS_RETURN-NUMBER
               LS_RETURN-MESSAGE_V1
               LS_RETURN-MESSAGE_V2
               LS_RETURN-MESSAGE_V3
               LS_RETURN-MESSAGE_V4
               V_TEXT.
          ENDIF.

      ENDIF. "V_CREATE = C_YES

    CLEAR: IT_DOMA_VALUES_TMP, IT_DOMA_VALUES_TMP[].
    CLEAR: V_CREATE.

  ENDLOOP. "IT_DOMAINS

  CLEAR: IS_DOMAINS_TMP, IT_DOMAINS, IT_DOMAINS[].

ENDFORM.

*---------------------------------------------------------------------*
*F008_CREATE_DATAELEMENTS.
*---------------------------------------------------------------------*
FORM F008_CREATE_DATAELEMENTS.

  DATA: LS_RETURN TYPE BAPIRET2.

  CLEAR: IS_DATAELEMENTS, V_EXT.
  LOOP AT IT_DATAELEMENTS INTO IS_DATAELEMENTS.

*Check whether data element exists or not
    CALL FUNCTION 'DD_CHECK_NAME'
         EXPORTING
              NAME            = IS_DATAELEMENTS-ROLLNAME
              OBJTYP          = 'DTEL'
         IMPORTING
              OBJ_EXISTS      = V_EXT.

*If exists, populate information message
    IF V_EXT EQ C_X.
              CLEAR V_TEXT.
              V_TEXT = 'Already Created'.
              V_MSGID = SPACE.
              V_MSGTY = 'I'.
              V_MSGNO = SPACE.
              V_MSGV1 = 'R3TR'.
              V_MSGV2 = 'DTEL'.
              V_MSGV3 = IS_DATAELEMENTS-ROLLNAME.
              V_MSGV4 = SPACE.
              PERFORM F012_POPULATE_MESSAGES
               USING
                 V_MSGID
                 V_MSGTY
                 V_MSGNO
                 V_MSGV1
                 V_MSGV2
                 V_MSGV3
                 V_MSGV4
                 V_TEXT.
    ENDIF.

*If data element doesn’t exist
    IF V_EXT %LT%GT C_X.
       CLEAR: V_CREATE.
       V_CREATE = C_YES.
    ENDIF. "V_EXT %LT%GT C_X

IF V_CREATE = C_YES.

*Get data element attributes
      CLEAR: IS_DATAELEMENTS_TMP.
      MOVE IS_DATAELEMENTS  TO IS_DATAELEMENTS_TMP.

*Check if the domain exists, if not throw error
    CLEAR: V_EXIST.

    CALL FUNCTION 'DD_CHECK_NAME'
         EXPORTING
              NAME            = IS_DATAELEMENTS_TMP-DOMNAME
              OBJTYP          = 'DOMA'
         IMPORTING
              OBJ_EXISTS      = V_EXIST.

*If domain does not exist
IF V_EXIST = C_SPACE.
    CLEAR:LINE, V_TEXT.
    CONCATENATE 'Domain' IS_DATAELEMENTS_TMP-DOMNAME
                'does not exist to create Data Element'
                IS_DATAELEMENTS-ROLLNAME
                INTO LINE SEPARATED BY SPACE.

    V_TEXT = LINE.
    V_MSGV3 = IS_DATAELEMENTS-ROLLNAME.
    PERFORM F012_POPULATE_MESSAGES
     USING
       SPACE
       'E'
       V_MSGNO
       'R3TR'
       'DTEL'
       V_MSGV3
       V_MSGV4
       V_TEXT.
ENDIF.

*If domain exists
    IF V_EXIST = C_X.

*Create data element
      CLEAR: LS_RETURN.
      CALL FUNCTION 'COM_GEN_DATAELEMENT_CREATE'
        EXPORTING
          IV_DTEL_NAME       = IS_DATAELEMENTS-ROLLNAME
          IV_DEVCLASS        = '$TMP'
          IV_ACTIVATE        = 'X'
          IS_DD04V           = IS_DATAELEMENTS_TMP
        IMPORTING
          ES_RETURN          = LS_RETURN.

*Populate success message
          IF LS_RETURN-TYPE NE 'E'.
              CLEAR V_TEXT.
              V_TEXT = 'Created Successfully'.
              V_MSGID = SPACE.
              V_MSGTY = 'S'.
              V_MSGNO = SPACE.
              V_MSGV1 = 'R3TR'.
              V_MSGV2 = 'DATE'.
              V_MSGV3 = IS_DATAELEMENTS-ROLLNAME.
              V_MSGV4 = SPACE.
              PERFORM F012_POPULATE_MESSAGES
               USING
                 V_MSGID
                 V_MSGTY
                 V_MSGNO
                 V_MSGV1
                 V_MSGV2
                 V_MSGV3
                 V_MSGV4
                 V_TEXT.
          ENDIF.

*Populate messages
          IF LS_RETURN-TYPE EQ 'E'.
            CLEAR V_TEXT.
            PERFORM F012_POPULATE_MESSAGES
             USING
               LS_RETURN-ID
               LS_RETURN-TYPE
               LS_RETURN-NUMBER
               LS_RETURN-MESSAGE_V1
               LS_RETURN-MESSAGE_V2
               LS_RETURN-MESSAGE_V3
               LS_RETURN-MESSAGE_V4
             V_TEXT.
          ENDIF.

    ENDIF. "V_EXIST = C_X

    ENDIF. "V_CREATE = C_YES

  ENDLOOP. "IT_DATAELEMENTS

  CLEAR: IT_DATAELEMENTS, IT_DATAELEMENTS[], IS_DATAELEMENTS_TMP.

ENDFORM.

*---------------------------------------------------------------------*
*F009_CREATE_TABLES.
*---------------------------------------------------------------------*
FORM F009_CREATE_TABLES.

DATA: LS_RETURN TYPE BAPIRET2.

  CLEAR:IS_TABLES, V_EXT.
  LOOP AT IT_TABLES INTO IS_TABLES.

    CLEAR:V_TABLE_NAME_CHECK.
    V_TABLE_NAME_CHECK = IS_TABLES-TABNAME.

*Check whether table exists or not
    CALL FUNCTION 'DD_CHECK_NAME'
         EXPORTING
              NAME       = V_TABLE_NAME_CHECK
              OBJTYP     = 'TABL'
         IMPORTING
              OBJ_EXISTS = V_EXT.

*If exists, populate information message
    IF V_EXT EQ C_X.
              CLEAR V_TEXT.
              V_TEXT = 'Already Created'.
              V_MSGID = SPACE.
              V_MSGTY = 'I'.
              V_MSGNO = SPACE.
              V_MSGV1 = 'R3TR'.
              V_MSGV2 = 'TABL'.
              V_MSGV3 = V_TABLE_NAME_CHECK.
              V_MSGV4 = SPACE.
              PERFORM F012_POPULATE_MESSAGES
               USING
                 V_MSGID
                 V_MSGTY
                 V_MSGNO
                 V_MSGV1
                 V_MSGV2
                 V_MSGV3
                 V_MSGV4
                 V_TEXT.
    ENDIF.

*If table doesn’t exist
    IF V_EXT %LT%GT C_X.
      CLEAR: V_CREATE.
      V_CREATE = C_YES.
    ENDIF. "V_EXT %LT%GT C_X

IF V_CREATE = C_YES.

*Get table header information
      CLEAR: IT_TABL_INF_TMP.
      MOVE IS_TABLES TO IT_TABL_INF_TMP.

*Get table technics
      CLEAR: IS_TABL_TECHNICS, IS_TABL_TECHNICS_TMP.
      READ TABLE IT_TABL_TECHNICS INTO IS_TABL_TECHNICS WITH KEY TABNAME
 = IS_TABLES-TABNAME.
      IF SY-SUBRC = 0.
        MOVE IS_TABL_TECHNICS TO IS_TABL_TECHNICS_TMP.
      ENDIF.

*Get table fields
      LOOP AT IT_TABL_FIELDS INTO IS_TABL_FIELDS
      WHERE TABNAME = IS_TABLES-TABNAME.
        APPEND IS_TABL_FIELDS TO IT_TABL_FIELDS_TMP.
        CLEAR IS_TABL_FIELDS.
      ENDLOOP.

*Check if all the data elements exists or not
      CLEAR: V_EXIST.
      LOOP AT IT_TABL_FIELDS_TMP INTO IS_TABL_FIELDS.

          CLEAR:V_EXIST.
          CALL FUNCTION 'DD_CHECK_NAME'
               EXPORTING
                    NAME            = IS_TABL_FIELDS-ROLLNAME
                    OBJTYP          = 'DTEL'
               IMPORTING
                    OBJ_EXISTS      = V_EXIST.

          IF V_EXIST = C_X.

             CONTINUE.

          ELSE.

              CLEAR:LINE, V_TEXT.
              CONCATENATE 'Data Element' IS_TABL_FIELDS-ROLLNAME
                          'does not exist to create Table'
                          IS_TABL_FIELDS-TABNAME
                          INTO LINE SEPARATED BY SPACE.

              V_TEXT = LINE.
              V_MSGV3 = IS_TABL_FIELDS-TABNAME.
              PERFORM F012_POPULATE_MESSAGES
               USING
                 SPACE
                 'E'
                 V_MSGNO
                 'R3TR'
                 'TABL'
                 V_MSGV3
                 V_MSGV4
                 V_TEXT.

             EXIT.

          ENDIF.

      ENDLOOP. "IT_TABL_FIELDS_TMP
      CLEAR: IS_TABL_FIELDS.

*If all data elements exist
      IF V_EXIST = C_X.

*Create tables
        CLEAR: LS_RETURN.
        CALL FUNCTION 'COM_GEN_DBTABLE_CREATE'
          EXPORTING
            IV_DBTABLE_NAME            = IS_TABLES-TABNAME
            IV_DEVCLASS                = '$TMP'
            IV_ACTIVATE                = 'X'
            IT_DD03P                   = IT_TABL_FIELDS_TMP
            IS_DD02V                   = IT_TABL_INF_TMP
            IS_DD09L                   = IS_TABL_TECHNICS_TMP
            IV_GENFLAG                 = 'T'
         IMPORTING
            ES_RETURN                  = LS_RETURN.

*Populate success message
          IF LS_RETURN-TYPE NE 'E'.
              CLEAR V_TEXT.
              V_TEXT = 'Created Successfully'.
              V_MSGID = SPACE.
              V_MSGTY = 'S'.
              V_MSGNO = SPACE.
              V_MSGV1 = 'R3TR'.
              V_MSGV2 = 'TABL'.
              V_MSGV3 = IS_TABLES-TABNAME.
              V_MSGV4 = SPACE.
              PERFORM F012_POPULATE_MESSAGES
               USING
                 V_MSGID
                 V_MSGTY
                 V_MSGNO
                 V_MSGV1
                 V_MSGV2
                 V_MSGV3
                 V_MSGV4
                 V_TEXT.
          ENDIF.

    IF LS_RETURN-TYPE EQ 'E'.
      CLEAR V_TEXT.
      PERFORM F012_POPULATE_MESSAGES
       USING
         LS_RETURN-ID
         LS_RETURN-TYPE
         LS_RETURN-NUMBER
         LS_RETURN-MESSAGE_V1
         LS_RETURN-MESSAGE_V2
         LS_RETURN-MESSAGE_V3
         LS_RETURN-MESSAGE_V4
       V_TEXT.
    ENDIF.

     ENDIF. "V_EXIST = C_X

    ENDIF. "V_CREATE = C_YES

    CLEAR:IT_TABL_FIELDS_TMP,IT_TABL_INF_TMP, IS_TABL_TECHNICS_TMP.
    REFRESH:IT_TABL_FIELDS_TMP.

  ENDLOOP. "IT_TABLES

ENDFORM.

*---------------------------------------------------------------------*
*      Form  F011_DISPLAY_MESSAGES
*---------------------------------------------------------------------*
FORM F011_DISPLAY_MESSAGES.

DATA: LT_FIELDCAT TYPE SLIS_T_FIELDCAT_ALV,
      LS_FIELDCAT TYPE SLIS_FIELDCAT_ALV.
DATA: LV_REPID TYPE SY-REPID.

LV_REPID = SY-REPID.

  IF IT_MESSAGES IS INITIAL.
    MESSAGE I002(SY) WITH 'No data available for processing'.
    LEAVE PROGRAM.
  ENDIF.

  IF NOT IT_MESSAGES IS INITIAL.

    LS_FIELDCAT-COL_POS = 1.
    LS_FIELDCAT-FIELDNAME = 'MANDT'.
    LS_FIELDCAT-SELTEXT_L = 'Client'.
    LS_FIELDCAT-OUTPUTLEN = 7.
    APPEND LS_FIELDCAT TO LT_FIELDCAT.

    LS_FIELDCAT-COL_POS = 2.
    LS_FIELDCAT-FIELDNAME = 'MSGID'.
    LS_FIELDCAT-SELTEXT_L = 'Message ID'.
    LS_FIELDCAT-OUTPUTLEN = 12.
    APPEND LS_FIELDCAT TO LT_FIELDCAT.

    LS_FIELDCAT-COL_POS = 3.
    LS_FIELDCAT-FIELDNAME = 'MSGTY'.
    LS_FIELDCAT-SELTEXT_L = 'Type'.
    LS_FIELDCAT-OUTPUTLEN = 5.
    APPEND LS_FIELDCAT TO LT_FIELDCAT.

    LS_FIELDCAT-COL_POS = 4.
    LS_FIELDCAT-FIELDNAME = 'MSGNO'.
    LS_FIELDCAT-SELTEXT_L = 'Number'.
    LS_FIELDCAT-OUTPUTLEN = 7.
    APPEND LS_FIELDCAT TO LT_FIELDCAT.

    LS_FIELDCAT-COL_POS = 5.
    LS_FIELDCAT-FIELDNAME = 'MSGV1'.
    LS_FIELDCAT-SELTEXT_L = 'Variable 1'.
    LS_FIELDCAT-OUTPUTLEN = 15.
    APPEND LS_FIELDCAT TO LT_FIELDCAT.

    LS_FIELDCAT-COL_POS = 6.
    LS_FIELDCAT-FIELDNAME = 'MSGV2'.
    LS_FIELDCAT-SELTEXT_L = 'Variable 2'.
    LS_FIELDCAT-OUTPUTLEN = 15.
    APPEND LS_FIELDCAT TO LT_FIELDCAT.

    LS_FIELDCAT-COL_POS = 7.
    LS_FIELDCAT-FIELDNAME = 'MSGV3'.
    LS_FIELDCAT-SELTEXT_L = 'Variable 3'.
    LS_FIELDCAT-OUTPUTLEN = 15.
    APPEND LS_FIELDCAT TO LT_FIELDCAT.

    LS_FIELDCAT-COL_POS = 8.
    LS_FIELDCAT-FIELDNAME = 'MSGV4'.
    LS_FIELDCAT-SELTEXT_L = 'Variable 4'.
    LS_FIELDCAT-OUTPUTLEN = 15.
    APPEND LS_FIELDCAT TO LT_FIELDCAT.

    LS_FIELDCAT-COL_POS = 9.
    LS_FIELDCAT-FIELDNAME = 'TEXT'.
    LS_FIELDCAT-SELTEXT_L = 'Text'.
    LS_FIELDCAT-OUTPUTLEN = 50.
    APPEND LS_FIELDCAT TO LT_FIELDCAT.

*List display
    CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
      EXPORTING
        I_CALLBACK_PROGRAM = LV_REPID
        I_GRID_TITLE       = 'Messages'
        IT_FIELDCAT        = LT_FIELDCAT
      TABLES
        T_OUTTAB           = IT_MESSAGES.

  ENDIF.

ENDFORM.                    "F011_DISPLAY_MESSAGES

*--------------------------------------------------------------------*
*      Form  F012_POPULATE_MESSAGES
*--------------------------------------------------------------------*
FORM  F012_POPULATE_MESSAGES  USING V_MSGID TYPE SY-MSGID
                                    V_MSGTY TYPE SY-MSGTY
                                    V_MSGNO TYPE SY-MSGNO
                                    V_MSGV1 TYPE SY-MSGV1
                                    V_MSGV2 TYPE SY-MSGV2
                                    V_MSGV3 TYPE SY-MSGV3
                                    V_MSGV4 TYPE SY-MSGV4
                                    V_TEXT TYPE ANY.

*If message text is not available
  IF V_TEXT = C_SPACE.

    IS_MESSAGES-MANDT = SY-MANDT.
    IS_MESSAGES-MSGID = V_MSGID.
    IS_MESSAGES-MSGTY = V_MSGTY.
    IS_MESSAGES-MSGNO = V_MSGNO.
    IS_MESSAGES-MSGV1 = V_MSGV1.
    IS_MESSAGES-MSGV2 = V_MSGV2.
    IS_MESSAGES-MSGV3 = V_MSGV3.
    IS_MESSAGES-MSGV4 = V_MSGV4.

*Build the message text
    CALL FUNCTION 'FORMAT_MESSAGE'
         EXPORTING
              ID        = V_MSGID
              LANG      = 'E'
              NO        = V_MSGNO
              V1        = V_MSGV1
              V2        = V_MSGV2
              V3        = V_MSGV3
              V4        = V_MSGV4
         IMPORTING
              MSG       = IS_MESSAGES-TEXT
         EXCEPTIONS
              NOT_FOUND = 1
              OTHERS    = 2.

    IF SY-SUBRC %LT%GT 0 OR IS_MESSAGES-TEXT = C_SPACE.
      IS_MESSAGES-TEXT = 'MESSAGE TEXT NOT FOUND'.
    ENDIF.

    APPEND IS_MESSAGES TO IT_MESSAGES.
    CLEAR IS_MESSAGES.

  ELSE. "V_TEXT = C_SPACE

    IS_MESSAGES-MANDT = SY-MANDT.
    IS_MESSAGES-MSGID = V_MSGID.
    IS_MESSAGES-MSGTY = V_MSGTY.
    IS_MESSAGES-MSGNO = V_MSGNO.
    IS_MESSAGES-MSGV1 = V_MSGV1.
    IS_MESSAGES-MSGV2 = V_MSGV2.
    IS_MESSAGES-MSGV3 = V_MSGV3.
    IS_MESSAGES-MSGV4 = V_MSGV4.
    IS_MESSAGES-TEXT  = V_TEXT.

    APPEND IS_MESSAGES TO IT_MESSAGES.
    CLEAR IS_MESSAGES.

  ENDIF. "V_TEXT = C_SPACE.

ENDFORM.                    "F012_POPULATE_MESSAGES

*&---------------------------------------------------------------------*
*&      Form  F_FILE_CHECK
*&---------------------------------------------------------------------*
FORM F_FILE_CHECK.

*Input file should not be blank
  IF P_FILE = C_SPACE.
    SET CURSOR FIELD 'P_FILE'.
    MESSAGE E002(SY) WITH 'Enter Input File Name!'.
  ENDIF.

ENDFORM.                    " F_FILE_CHECK
*&---------------------------------------------------------------------*
*&      Form  f_top_of_page
*&---------------------------------------------------------------------*
FORM F_TOP_OF_PAGE.
  CLEAR:LINE.
  CONCATENATE 'Customized Database Tables Generation by'
              SY-UNAME
              INTO LINE SEPARATED BY SPACE.
  WRITE :/ LINE.
  WRITE :/10 'DATE:',SY-DATUM.

ENDFORM.      " F_TOP_OF_PAGE
*&---------------------------------------------------------------------*
*&      Form  f_end_of_page
*&---------------------------------------------------------------------*

FORM F_END_OF_PAGE.
  WRITE:SY-ULINE(90).
  WRITE:/30 'PAGE:',SY-PAGNO CENTERED.

ENDFORM.     " F_END_OF_PAGE

*&---------------------------------------------------------------------*
*&      Form  F_FREE_MEMORY
*&---------------------------------------------------------------------*
FORM F_FREE_MEMORY.

*Clear internal tables.
  CLEAR:
  IT_TABLES,
  IT_TABL_INF_TMP,
  IT_TABL_TECHNICS,
  IS_TABL_TECHNICS_TMP,
  IT_TABL_FIELDS,
  IT_TABL_FIELDS_TMP,
  IT_DOMAINS,
  IS_DOMAINS_TMP,
  IT_DOMA_VALUES,
  IT_DOMA_VALUES_TMP,
  IT_DATAELEMENTS,
  IS_DATAELEMENTS_TMP,
  IT_MESSAGES.


*Refresh internal tables
  REFRESH:
  IT_TABLES,
  IT_TABL_TECHNICS,
  IT_TABL_FIELDS,
  IT_TABL_FIELDS_TMP,
  IT_DOMAINS,
  IT_DOMA_VALUES,
  IT_DOMA_VALUES_TMP,
  IT_DATAELEMENTS,
  IT_MESSAGES.


*Free internal tables/work areas
  FREE:
  IT_TABLES,
  IT_TABL_INF_TMP,
  IT_TABL_TECHNICS,
  IS_TABL_TECHNICS_TMP,
  IT_TABL_FIELDS,
  IT_TABL_FIELDS_TMP,
  IT_DOMAINS,
  IS_DOMAINS_TMP,
  IT_DOMA_VALUES,
  IT_DOMA_VALUES_TMP,
  IT_DATAELEMENTS,
  IS_DATAELEMENTS_TMP,
  IT_MESSAGES.


*Clear variables
  CLEAR:
  V_MSGID ,
  V_MSGTY,
  V_MSGNO,
  V_MSGV1,
  V_MSGV2,
  V_MSGV3,
  V_MSGV4,
  V_TEXT,
  LINE,
  V_TABLE_NAME_CHECK,
  V_EXT,
  V_EXIST.

*Free variables
  FREE:
  V_MSGID ,
  V_MSGTY,
  V_MSGNO,
  V_MSGV1,
  V_MSGV2,
  V_MSGV3,
  V_MSGV4,
  V_TEXT,
  LINE,
  V_TABLE_NAME_CHECK,
  V_EXT,
  V_EXIST.

*Unassign field symbols
  UNASSIGN %LTFS_VALUE%GT.

ENDFORM.                    " F_FREE_MEMORY


*Selection texts
*----------------------------------------------------------
* P_FILE         FileName


*Messages
*----------------------------------------------------------
*
* Message class: SY
*002   &


*Selection texts
*----------------------------------------------------------
* P_FILE         FileName


*Messages
*----------------------------------------------------------
*
* Message class: SY
*002   &


*Selection texts
*----------------------------------------------------------
* P_FILE         FileName


*Messages
*----------------------------------------------------------
*
* Message class: SY
*002   &
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.