*---------------------------------------------------------------------*
* Z _ B J H _ E X C E L *
* *
* Autor: Bernd Haase (BJH Software) *
*---------------------------------------------------------------------*
* Beispielprogramm, um von SAP Microsoft-Excel aufzurufen und ein *
* Datenblatt der Tabelle mit Werten vorzubelegen. Zu Testzwecken *
* sollen einige Felder der Positionen einer Bestellung angezeigt *
* werden, die zuvor über Parameter selektiert wurden. *
*---------------------------------------------------------------------*
* (X) Excel_out *
*---------------------------------------------------------------------*
* 04.02.2004 BHaa: Programm erstellt *
* 30.05.2005 BHaa: Bildschirmanzeige oder Hintergrundprozeß *
*---------------------------------------------------------------------*
REPORT z_bjh_excel .
TABLES:
ekpo. "Einkaufsbelegposition
DATA:
wa_ekpo LIKE ekpo,
itab_ekpo LIKE TABLE OF ekpo,
anzahl(5) TYPE n,
wa_wert(3) TYPE p DECIMALS 2.
*---------------------------------------------------------------------*
* *
* A u s w a h l b i l d s c h i r m *
* *
*---------------------------------------------------------------------*
* Eingabe der Bestellnummer
SELECTION-SCREEN: BEGIN OF BLOCK a1 WITH FRAME TITLE text-901.
PARAMETERS:
* Bestellnummer
pmebeln LIKE ekpo-ebeln,
* Bildschirmanzeige (zeigt Excel am Bildschirm)
pmx_bild RADIOBUTTON GROUP grp1 DEFAULT 'X',
* Hintergrund (es wird eine Datei gespeichert)
pmx_job RADIOBUTTON GROUP grp1,
* Dateiname (nur bei Hintergrundprozeß)
pmout LIKE rlgrap-filename.
SELECTION-SCREEN: END OF BLOCK a1.
INITIALIZATION.
pmout = 'c:/bjh/sap_excel.xls'.
***********************************************************************
* *
* P R O G R A M M S T A R T *
* *
***********************************************************************
START-OF-SELECTION.
* alle Positionen der ausgewählten Bestellung einlesen
SELECT * FROM ekpo INTO wa_ekpo
WHERE ebeln = pmebeln.
APPEND wa_ekpo TO itab_ekpo.
ENDSELECT.
* ermitteln, ob überhaupt Werte / Datensätze gefunden wurden und
* entsprechend weiter verzweigen
DESCRIBE TABLE itab_ekpo LINES anzahl.
IF anzahl = 0.
WRITE: / 'Keine Positionen zur Bestellung', pmebeln, 'gefunden'.
ELSE.
PERFORM upro-excel.
ENDIF.
END-OF-SELECTION.
EXIT.
*---------------------------------------------------------------------*
* E X C E L *
*---------------------------------------------------------------------*
* Vorbesetzen und Füllen der Datenfelder einer Excel-Tabelle, alle *
* Aktionen im Hintergrund. *
*---------------------------------------------------------------------*
FORM upro-excel.
* Include-Baustein für OLE-Verarbeitungen
INCLUDE ole2incl.
*******
* OLE *
*******
* globale Variablen für OLE-Call
STATICS:
excel TYPE ole2_object,
application TYPE ole2_object,
books TYPE ole2_object,
book TYPE ole2_object,
sheet TYPE ole2_object,
cell TYPE ole2_object,
column TYPE ole2_object.
* Zeilen- und Spaltenzähler innerhalb der Excel-Tabelle
DATA:
zeile TYPE i,
sp TYPE i,
chr_zeile(5) TYPE n,
formel(80) TYPE c.
* MS Excel ausführen mit OLE und Daten exportieren
CREATE OBJECT excel 'EXCEL.SHEET'.
IF sy-subrc <> 0.
* MS Excel konnte nicht per OLE gestartet werden
* Nachrichtenklasse und Fehlercode anpassen, als Platzhalter definiert
MESSAGE ID 'SU' TYPE 'E' NUMBER '000' WITH text-001.
EXIT.
ENDIF.
GET PROPERTY OF excel 'Application' = application.
* Hintergrund oder Bildschirmanzeige
IF pmx_job = 'X'.
SET PROPERTY OF application 'VISIBLE' = 0. "0 = unsichtbar
ELSE.
SET PROPERTY OF application 'Visible' = 1. "1 = sichtbar
ENDIF.
CALL METHOD OF application 'Workbooks' = books.
* Wert muß an die vorherige Variable anknüpfen
CALL METHOD OF books 'Add' = book.
* Das erste Datenblatt nehmen für die Kopfdaten
* die Anweisung 'No Flush' verhindert die direkte Ausführung des Befehls
* und generiert eine Queue mit allen Befehlen. Diese Queue wird über die
* Funktion 'Flush' ausgeführt.
* sheet = 1 bezeichnet das erste Datenblatt unter Excel
CALL METHOD OF book 'Worksheets' = sheet NO FLUSH
EXPORTING #1 = 1.
* Namen des Datenblattes der Tabelle setzen
SET PROPERTY OF sheet 'Name' = 'Bestellpositionen' no flush.
*---------------------------------------------------------------------*
* Überschriften einpflegen *
* diese sollen in der zweiten Zeile stehen, beginnend mit der ersten *
* Spalte und dann fortlaufend (fix/fest programmiert) *
* Exporting #1 = Zeile, #2=Spalte, Wertzuweisung über Set Property *
*---------------------------------------------------------------------*
zeile = 2.
MOVE 1 TO sp.
PERFORM upro-excel_w USING sheet cell zeile sp 'Bestellnummer'.
PERFORM upro-excel_w USING sheet cell zeile sp 'Bestellposition'.
PERFORM upro-excel_w USING sheet cell zeile sp 'Materialnummer'.
PERFORM upro-excel_w USING sheet cell zeile sp 'Menge'.
PERFORM upro-excel_w USING sheet cell zeile sp 'Bestellmengeneinheit'.
PERFORM upro-excel_w USING sheet cell zeile sp 'Nettobestellwert'.
PERFORM upro-excel_w USING sheet cell zeile sp 'Bruttobestellwert'.
PERFORM upro-excel_w USING sheet cell zeile sp 'Prozentwert'.
*---------------------------------------------------------------------*
* Daten zeilenweise aufbereiten und einpflegen
* Daten werden ab Zeile 4 eingefügt, Spaltenzuordnung entsprechend der*
* Überschrift im Block zuvor
*---------------------------------------------------------------------*
zeile = 3.
LOOP AT itab_ekpo INTO wa_ekpo.
ADD 1 TO zeile.
MOVE 1 TO sp.
* Bestellnummer
PERFORM upro-excel_w USING sheet cell zeile sp wa_ekpo-ebeln.
* Bestellposition
PERFORM upro-excel_w USING sheet cell zeile sp wa_ekpo-ebelp.
* Materialnummer
PERFORM upro-excel_w USING sheet cell zeile sp wa_ekpo-matnr.
* Menge
PERFORM upro-excel_w USING sheet cell zeile sp wa_ekpo-menge.
* Bestellmengeneinheit
PERFORM upro-excel_w USING sheet cell zeile sp wa_ekpo-meins.
* Nettobestellwert
PERFORM upro-excel_w USING sheet cell zeile sp wa_ekpo-netwr.
* Bruttobestellwert
PERFORM upro-excel_w USING sheet cell zeile sp wa_ekpo-brtwr.
* Summe (im Beispiel: wieviel Prozent bildet der Nettowert gegenüber
* dem Bruttowert)
chr_zeile = zeile.
* bei Formel bitte die englischen Schreibweisen verwenden
CONCATENATE '=SUM(F' chr_zeile
'* 100 / G' chr_zeile
')'
INTO formel.
CONDENSE formel.
PERFORM upro-excel_w USING sheet cell zeile sp formel.
* Spaltenzähler wieder zu einen zurück, dieser soll auf das eben
* berechnete Ergebnis zeigen (Unterprogramm erhöht immer)
SUBTRACT 1 FROM sp.
* um den Wert der Berechnung wieder zurückzuholen, wird nun umgekehrt
* verfahren und aus der Tabelle gelesen. Die übergebene Variable bleibt
* ohne weitere Nutzung, es soll nur das Verfahren erläutert werden
PERFORM upro-excel_l
USING sheet cell zeile sp wa_wert.
ENDLOOP.
* optimale Weite der Spalten, im Beispiel wird dieses die Breite der
* Überschriften sein.
CALL METHOD OF sheet 'Columns' = column NO FLUSH.
FREE OBJECT sheet NO FLUSH.
CALL METHOD OF column 'Autofit' NO FLUSH.
FREE OBJECT column NO FLUSH.
* für Hintergrundverarbeitung, Excelliste sichern und Excel verlassen
IF pmx_job = 'X'.
CALL METHOD OF book 'SaveAs' EXPORTING #1 = pmout.
CALL METHOD OF books 'CLOSE'.
CALL METHOD OF excel 'QUIT'.
ENDIF.
* starten der Export-Queue über function call
CALL FUNCTION 'FLUSH'.
* alle OLE-Objekte plattmachen in der entgegengesetzten Reihenfolge
* wie sie geöffnet wurden, LIFO-Prinzip
FREE OBJECT: book, books, application, excel.
ENDFORM.
*---------------------------------------------------------------------*
* E X C E L _ W E R T E *
*---------------------------------------------------------------------*
* =>] sheet: *
* =>] cell: *
* =>] zeile: Zeile, in welcher Excel den Wert ablegen soll *
* <=> spalte: Spalte für den Wert, wird im Upro erhöht *
* =>] wert: Zelleninhalt,welcher an Reihe/Spalte gesetzt werden soll*
*---------------------------------------------------------------------*
FORM upro-excel_w
USING sheet TYPE ole2_object
cell TYPE ole2_object
value(p_zeile)
p_spalte
value(p_wert).
DATA:
h_font TYPE ole2_object.
CALL METHOD OF sheet 'Cells' = cell NO FLUSH
EXPORTING #1 = p_zeile
#2 = p_spalte.
* Eigenschaften zur Excel-Zelle setzen
SET PROPERTY OF cell 'Value' = p_wert no flush.
GET PROPERTY OF cell 'Font' = h_font.
* 1=Fettdruck oder 0=Normal
SET PROPERTY OF h_font 'Bold' = 1.
* Farben: 1=Schwarz, 2=weiss, 3=rot, 4=grün, 5=blau, 6=gelb *
SET PROPERTY OF h_font 'ColorIndex' = 4.
SET PROPERTY OF h_font 'Size' = 12.
* FREE OBJECT cell NO FLUSH.
ADD 1 TO p_spalte.
ENDFORM.
*---------------------------------------------------------------------*
* E X C E L _ W E R T E _ L E S E N *
*---------------------------------------------------------------------*
* den Wert zu einer Zelle (Reihe / Spalte) einlesen und bekommen, um *
* diesen dann anderswo weiterverarbeiten zu können *
*---------------------------------------------------------------------*
* ]=> p_wert: Wert, welcher in der Zelle zu der Reihe / Spalte *
* gespeichert ist *
*---------------------------------------------------------------------*
FORM upro-excel_l
USING sheet TYPE ole2_object
cell TYPE ole2_object
value(p_zeile)
p_spalte
p_wert.
CALL METHOD OF sheet 'Cells' = cell NO FLUSH
EXPORTING #1 = p_zeile
#2 = p_spalte.
GET PROPERTY OF cell 'VALUE' = p_wert.
ADD 1 TO p_spalte.
ENDFORM.
*---------------------------------------------------------------------*
* Zum Schluß noch ein paar Helferlein *
*---------------------------------------------------------------------*
* Textformatierung. Um sicher zu gehen, daß eine Zahl als Text auch
* wirklich geschrieben wird und nicht als E-Zahl ('1.23E05'), sind 3
* Methodiken anwendbar
* 1.) Formatierung
*CALL METHOD OF excel 'COLUMNS' = columnObj
* EXPORTING #1 = 2. "betroffene Spalte
*SET PROPERTY OF columnObj 'ColumnWidth' = 10.
*SET PROPERTY OF columnObj 'NumberFormat' = '@'.
* 2.) ab und an kann Schritt 1 nicht immer erfolgreich sein. Wenn nicht,
* sollten Sie es mit Hochkomma um die Zahl versuchen und diese dann
* übergeben
* 3.) wenn alle Daten geschrieben sind, kann auch mit der Markierfunk-
* tion versucht werden, Herr des problems zu werden
FORM f_copy_paste_special
USING excel
p_start_reihe
p_end_reihe
p_spalte.
*******
* OLE *
*******
* globale Variablen für OLE-Call
STATICS:
von_zelle TYPE ole2_object,
bis_zelle TYPE ole2_object,
range TYPE ole2_object.
* Startpunkt setzen
CALL METHOD OF excel 'CELLS' = von_zelle
EXPORTING
#1 = p_start_reihe
#2 = p_spalte.
* Endpunkt setzen (es wird nur eine Spalte markiert
CALL METHOD OF excel 'CELLS' = bis_zelle
EXPORTING
#1 = p_end_reihe
#2 = p_spalte.
* den Bereich einstellen
CALL METHOD OF excel 'RANGE' = range
EXPORTING
#1 = von_zelle
#2 = bis_zelle.
* auswählen, kopieren und einfügen
CALL METHOD OF range 'SELECT'.
CALL METHOD OF range 'COPY'.
CALL METHOD OF range 'PASTESPECIAL'
EXPORTING
#1 = 12. "paste value and format
* #2 =
* #3 = 'FALSE'
* #4 = 'FALSE'.
FREE OBJECT: von_zelle, bis_zelle, range.
ENDFORM.
***** Ende *****
* Copyright BJH Software, Datei überarbeitet am: 11.6.2005