Generischer Excel-Upload

Mit diesem Programm können Sie relativ einfach Daten, die in Excel-Tabellen gespeichert sind, in eine Tabelle geladen werden. Es wird dafür ein Excel-Objekt erzeugt und die Exceltabelle im Hintergrund ausgelesen. Anhand der Eigenschaften der R/3-Tabelle wird ein Subroutinenpool erstellt, der das Einlesen und Speichern vornimmt.

Info

Bei Programmstart muss die Excel-Tabelle angegeben werden sowie die Zeile und Spalte, bei denen angefangen werden soll, die Daten einzulesen.

Zudem muss natürlich auch die Dictionary-Tabelle angegeben werden, in die die Daten gespeichert werden sollen.

Die Daten werden Zeilenweise von links nach rechts eingelesen.

Sobald eine leere Zeile kommt, wird das Einlesen abgebrochen.

Technische Informationen

  • Es wird eine rudimentäre Anpassung der Daten in der Routine GET_VALUE vorgenommen. Dabei wird die Formatierung in der Excel-Tabelle berücksichtigt. Diese Routine sollten Sie an Ihre eigenen Bedürfnisse anpassen.
  • Es wird dynamisch ein Subroutinen-Pool erzeugt. Dieser beinhaltet die Routine „UPLOAD_TABLE“. Sollte die Generierung fehlschlagen, wird der Fehler ausgegeben.
  • Es wird das Makro „_ASCL“ benutzt (Add SourceCodeLine), um Quelltext an die interne Tabelle GT_QUELLTEXT zu hängen. Das Makro macht das Erzeugen sehr übersichtlich und bequem. Zudem können Variablen, wie „Programmname“ oder „Dictionarytabelle“ gleich ersetzt werden.
  • Das Programm erhebt keinen Anspruch auf generelle Fehlerfreiheit! Es beinhaltet alle notwendigen Funktionen, die eine Anpassung an eigene/ spezielle Bedürfnisse einfach machen. 

Quellcode

REPORT ZGUPL.
***********************************************************************
* Generischer Upload von Excel-Tabellen in R/3-Tabellen
***********************************************************************

INCLUDE OLE2INCL.

DATA:
  GV_SPALTE       TYPE I,
  GV_ZEILE        TYPE I,
  GV_FORMAT(30)   TYPE C,
  GV_TYPE         TYPE C,
  GV_VALUE(1000)  TYPE C,
  GV_LINE(1000)   TYPE C,
  GV_LEN          TYPE I,
  GV_TYPE_P(8)    TYPE P DECIMALS 4,
  GV_TYPE_N(100)  TYPE N,
  GV_TYPE_C(100)  TYPE N,

*** Subroutinenpool:
  GV_SUBROUTINEPOOL(30),
  GV_ERR_MESSAGE(200),
  GV_ERR_LINE     TYPE I,
  GT_QUELLTEXT    TYPE STANDARD TABLE OF LINE72,
  GV_QUELLTEXT    TYPE LINE72,
  GT_DD03L        LIKE DD03L OCCURS 0 WITH HEADER LINE,

*** Excel
  h_excel         TYPE ole2_object, “ Excel object
  h_book          TYPE ole2_object, “ list of workbooks
  h_active_window TYPE ole2_object,
  cell_out        TYPE ole2_object,                        “ cell
  cell_in         TYPE ole2_object.                        “ cell

*** Makro
DEFINE _ASCL.
*** Add Source-Code-Line ***
  GV_LINE = &1.
*** Tabellenname ersetzen
  REPLACE ‚%TAB%‘ WITH P_R3TAB INTO GV_LINE.
  CONDENSE GV_LINE.
*** Programmname für externen Perform-Aufruf ersetzen
  REPLACE ‚%REPID%‘ WITH SY-REPID INTO GV_LINE.
  CONDENSE GV_LINE.
*** ~Tilde durch Leerzeichen ersetzen
  TRANSLATE GV_LINE USING ‚~ ‚.
*** „Doppelte Anführungszeichen durch ‚einfache ersetzen
  TRANSLATE GV_LINE USING ‚““‘.
*** Quellcode anhängen
  APPEND GV_LINE TO GT_QUELLTEXT.
END-OF-DEFINITION.

*** Selektionsbild
PARAMETERS:
  P_XLSDAT TYPE LOCALFILE DEFAULT ‚C:temptest.xls‘, „Excel-Datei
  P_XLSCOL TYPE N         DEFAULT 1,                  „Start bei Spalte
  P_XLSROW TYPE N         DEFAULT 2,                  „Start bei Zeile
  P_R3TAB  TYPE TABELLE   DEFAULT ‚ZTEST‘.            „R3-Tabelle


*** F4-Hilfe für Dateiname
AT SELECTION-SCREEN ON VALUE-REQUEST FOR P_XLSDAT.

  CALL FUNCTION ‚F4_FILENAME‘
       EXPORTING
            PROGRAM_NAME  = SYST-CPROG
            DYNPRO_NUMBER = SYST-DYNNR
            FIELD_NAME    = ‚P_XLSDAT‘
       IMPORTING
            FILE_NAME     = P_XLSDAT.


*** Programmstart
START-OF-SELECTION.

  SELECT * FROM DD03L INTO TABLE GT_DD03L
   WHERE TABNAME = P_R3TAB.
  IF SY-SUBRC > 0.
    MESSAGE S000(VZ) WITH ‚Tabelle‘ P_R3TAB ‚existiert nicht!‘.
  ELSE.
    SORT GT_DD03L BY POSITION.
    PERFORM SUBROUTINEPOOL_BUILD.
    PERFORM SUBROUTINEPOOL_START.
  ENDIF.

*———————————————————————*
*       FORM START_EXCEL                                              *
*———————————————————————*

FORM START_EXCEL.

* start Excel
  CREATE OBJECT h_excel ‚EXCEL.APPLICATION‘.

* Excel nicht sichtbar ausführen
  SET PROPERTY OF H_EXCEL ‚Visible‘ = 0.

* Arbeitsblatt auswählen
  CALL METHOD OF h_excel ‚Workbooks‘ = h_book.

* bestehendes File öffnen
  CALL METHOD OF h_book ‚OPEN‘
       EXPORTING
          #1 = P_XLSDAT.

ENDFORM.

*———————————————————————*
*       FORM GET_VALUE                                                *
*———————————————————————*

FORM GET_VALUE USING F_ROW F_COL CHANGING F_VALUE.

  DESCRIBE FIELD F_VALUE TYPE GV_TYPE LENGTH GV_LEN.
*———————————————————–
* Zelle, aus der Ergebnis gelesen wird (C1)
  CALL METHOD OF h_excel ‚Cells‘ = cell_in
       EXPORTING
          #1 = F_ROW                                        „Zeile
          #2 = F_COL.                                       „Spalte

* Zellinhalt lesen
  GET PROPERTY OF CELL_IN ‚Value‘ = GV_VALUE.
  IF GV_VALUE = SPACE.
    CLEAR F_VALUE.
  ELSE.
* Zahlenformat
    GET PROPERTY OF CELL_IN ‚NumberFormat‘ = GV_FORMAT.

    CASE GV_TYPE.
      WHEN ‚C‘.
        CASE GV_FORMAT.
          WHEN ‚0‘.
            GV_TYPE_P = GV_VALUE.
            WRITE GV_TYPE_P TO GV_TYPE_C(GV_LEN)
                            DECIMALS 0 RIGHT-JUSTIFIED.
            IF GV_TYPE_P > 0.
              SHIFT GV_TYPE_C BY 1 PLACES RIGHT.
            ENDIF.
            OVERLAY GV_TYPE_C WITH GV_TYPE_N.
            F_VALUE = GV_TYPE_C.
          WHEN ‚0.0‘.
            GV_TYPE_P = GV_VALUE.
            WRITE GV_TYPE_P TO GV_TYPE_C(GV_LEN)
                            DECIMALS 1 RIGHT-JUSTIFIED.
            IF GV_TYPE_P > 0.
              SHIFT GV_TYPE_C BY 1 PLACES RIGHT.
            ENDIF.
            OVERLAY GV_TYPE_C WITH GV_TYPE_N.
            F_VALUE = GV_TYPE_C.
          WHEN ‚0.00‘.
            GV_TYPE_P = GV_VALUE.
            WRITE GV_TYPE_P TO GV_TYPE_C(GV_LEN)
                            DECIMALS 2 RIGHT-JUSTIFIED.
            IF GV_TYPE_P > 0.
              SHIFT GV_TYPE_C BY 1 PLACES RIGHT.
            ENDIF.
            OVERLAY GV_TYPE_C WITH GV_TYPE_N.
            F_VALUE = GV_TYPE_C.
          WHEN ‚General‘.
            F_VALUE = GV_VALUE.
          WHEN ‚@‘. „Text
            IF GV_VALUE CO ‚ .0123456789‘.
** Falls eine „Zahl“ als „Text“ formatiert ist, steht in
** GV_VALUE: „1234.00000“. Dies muss umgewandelt werden in „1234“.
              GV_TYPE_P = GV_VALUE.
              WRITE GV_TYPE_P TO GV_VALUE DECIMALS 0 NO-GROUPING
                                          LEFT-JUSTIFIED.
            ENDIF.
            F_VALUE = GV_VALUE.
          WHEN OTHERS.
            F_VALUE = GV_VALUE.
        ENDCASE.
      WHEN OTHERS.
        F_VALUE = GV_VALUE.
    ENDCASE.
  ENDIF. „Value <> space

ENDFORM.

*———————————————————————*
*       FORM STOPP_EXCEL                                              *
*———————————————————————*

FORM STOPP_EXCEL.

* Excel beenden
*———————————————————————–
* see
http://support.microsoft.com/default.aspx?scid=kb;de;503541
* Close without saving

* get active window
  CALL METHOD OF h_excel ‚ACTIVEWINDOW‘ = h_active_window.
* set active_window visible
  SET PROPERTY OF h_active_window ‚VISIBLE‘ = 1.
*———————————————————————–

* close active_window without saving
  CALL METHOD OF h_active_window ‚CLOSE‘
       EXPORTING #1 = 0.

* close Excel
  CALL METHOD OF h_excel ‚QUIT‘.
  FREE OBJECT: h_excel, h_active_window.

ENDFORM.

*———————————————————————*
*       FORM SUBROUTINEPOOL_BUILD                                     *
*———————————————————————*
FORM SUBROUTINEPOOL_BUILD.

  _ASCL:
    ‚REPORT zzz.‘,
    ‚FORM UPLOAD_TABLE USING value(f_zeile)‘,
    ‚                        value(f_spalte).‘,
    ‚DATA gt_itab   LIKE %TAB% OCCURS 0 WITH HEADER LINE.‘,
    ‚DATA lv_zeile  TYPE i.‘,
    ‚DATA lv_spalte TYPE i.‘,
    ‚PERFORM start_excel IN PROGRAM %REPID%.‘,
    ‚LV_ZEILE  = f_zeile.‘,
    ‚Do.‘,
    ‚LV_SPALTE = f_spalte.‘,
    ‚NEW-LINE.‘,
    ‚CLEAR GT_ITAB.‘.
  LOOP AT GT_DD03L.
    CHECK GT_DD03L-DATATYPE <> ‚CLNT‘.
    _ASCL:
      ‚PERFORM GET_VALUE in Program %REPID%‘,
      ‚USING lv_zeile lv_spalte CHANGING‘.
    CONCATENATE ‚GT_ITAB-‚ GT_DD03L-FIELDNAME ‚.‘ INTO GV_QUELLTEXT.
    _ASCL GV_QUELLTEXT.
    _ASCL ‚WRITE‘.
    _ASCL GV_QUELLTEXT.

    _ASCL ‚ADD 1 TO lv_spalte.‘.

  ENDLOOP.
  _ASCL:
    ‚IF GT_ITAB IS INITIAL.‘,
    ‚WRITE „Ende….“ COLOR col_positive.‘,
    ‚EXIT.‘,
    ‚ENDIF.‘,
    ‚INSERT INTO %TAB% VALUES GT_ITAB.‘,
    ‚WRITE sy-subrc COLOR = sy-subrc.‘,
    ‚Add 1 to lv_zeile.‘,
    ‚Enddo.‘,
    ‚PERFORM STOPP_EXCEL IN PROGRAM %REPID%.‘,
    ‚ENDFORM.‘.

ENDFORM.

*———————————————————————*
*       FORM SUBROUTINEPOOL_START                                     *
*———————————————————————*

FORM SUBROUTINEPOOL_START.

*** Subroutinenpool mit Unterprogramm „UPLOAD_TABLE“ generieren
  GENERATE SUBROUTINE POOL GT_QUELLTEXT NAME GV_SUBROUTINEPOOL
           MESSAGE GV_ERR_MESSAGE LINE GV_ERR_LINE.
  IF SY-SUBRC = 0.
*** Unterprogramm aufrufen
    PERFORM UPLOAD_TABLE IN PROGRAM (GV_SUBROUTINEPOOL)
      USING P_XLSROW P_XLSCOL.
  ELSE.
*** fehler
    FORMAT COLOR COL_TOTAL.
    WRITE: / ‚Fehler beim Generieren des Subroutinenpools:‘,
           / GV_ERR_MESSAGE,
           / ‚Zeile‘, GV_ERR_LINE,
           / ‚Returncode:‘, SY-SUBRC.
    ULINE.
    LOOP AT GT_QUELLTEXT INTO GV_QUELLTEXT.
      IF SY-TABIX = GV_ERR_LINE.
        FORMAT COLOR COL_NEGATIVE.
      ELSE.
        FORMAT COLOR OFF.
      ENDIF.
      WRITE / GV_QUELLTEXT.
    ENDLOOP.
  ENDIF.

ENDFORM.

image_pdfimage_print
Enno Wulff
follow me
Letzte Artikel von Enno Wulff (Alle anzeigen)