EXCEL und Grafik erstellen

Nutzung, Komponenten, .NET

Moderator: Moderatoren

Antworten
Benutzeravatar
Rudolf
Programmier-Gott
Programmier-Gott
Beiträge: 1418
Registriert: Mo, 02. Jan 2006 23:03
Wohnort: Salzburg/Österreich
Kontaktdaten:

EXCEL und Grafik erstellen

Beitrag von Rudolf »

Hallo,
hat jemand ein Beispiel, wie ich eine Chart im EXCEL über ActiveX erstelle ?
Grüsse
Rudolf
Alfred
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 476
Registriert: Do, 03. Mai 2007 12:37
Wohnort: München

Beitrag von Alfred »

Hallo Rudolf,

am einfachsten eine *.xls anlegen und im 1. Worksheet die Daten übergeben und das 2. Worksheet enthält die fertige Graphik.

Wegen der Datenübergabe siehe hier im Forum mein oder Jimmys
Beispiel unter "Daten aus Excel einlesen".

Wenn alles vollautomatisch erstellt werden soll, müsste man wissen
was Du willst. In meinem Buch "MS Office Automation with Visual FoxPro"
von Granor/Martin ist alles so genau erläutert, dass man das Excelbeispiel
von Alaska nach seinen Wünschen anpassen kann.

Gruß
Alfred
Benutzeravatar
Rudolf
Programmier-Gott
Programmier-Gott
Beiträge: 1418
Registriert: Mo, 02. Jan 2006 23:03
Wohnort: Salzburg/Österreich
Kontaktdaten:

Beitrag von Rudolf »

Hallo Alfred,
danke für die schnelle Antwort, mit Schreiben funktioniert alles bis auf das hier gepostete Problem mit dem Absturz wenn man in die Tabelle clickt. Ich brauche nur noch die Kommandos um für einen bestimmten Bereich eine Chart zu erstellen.
Grüsse
Rudolf
Alfred
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 476
Registriert: Do, 03. Mai 2007 12:37
Wohnort: München

Beitrag von Alfred »

Hallo Rudolf,

habe noch keine Graphik angelegt. Werde es heute abend mal testen.

Kannst Du mir sagen wie die Graphik aussehen soll. Balken, Linien oder Kreise? Wie viele Spalten und Reihen an Daten gibt es denn?

Gruß
Alfred
Benutzeravatar
Rudolf
Programmier-Gott
Programmier-Gott
Beiträge: 1418
Registriert: Mo, 02. Jan 2006 23:03
Wohnort: Salzburg/Österreich
Kontaktdaten:

Beitrag von Rudolf »

Hallo Alfred,
habe aus einer einfachen Tabelle die ich erstelle mal die Grafik gemacht und mit Macrorecorder aufgenommen. Scheint einfach zu sein, wenn man weiss wie es geht ;-) Ich glaub wenn ich das Prinzip mal raushabe die Macros umzusetzen, ist der Rest einfach.


so erstelle ich das Sheet

Code: Alles auswählen

    oApp:Application:Worksheets(2):activate()
    oApp:Application:Worksheets(2):name:='Spartenumsätze'
    oSheet := oApp:Worksheets(2):cells
    oSheet:Columns('A'):ColumnWidth  := 14
    oSheet:Columns('B'):ColumnWidth  :=  7
    oSheet:Columns('C'):ColumnWidth  :=  7
    oSheet:Columns('D'):ColumnWidth  :=  7
    oSheet:Columns('E'):ColumnWidth  :=  7
    oSheet:Columns('F'):ColumnWidth  :=  7
    oSheet:Columns('G'):ColumnWidth  :=  7
    oSheet:RANGE('A1:H1'):Font:Bold      := .T.
    oSheet:Range( "A1:G1" ):Interior:ColorIndex := 15
    oSheet:item(1,1):Value  := 'Sparte'
    oSheet:item(1,2):Value  := 'Anzahl '
    oSheet:item(1,3):Value  := 'Storno'
    oSheet:item(1,4):Value  := 'Guts.'
    oSheet:item(1,5):Value  := 'Verk.'
    oSheet:item(1,6):Value  := 'Preis'
    oSheet:item(1,7):Value  := 'Umsatz'
    for x := 1 to len(aSparten)
          oSheet:item(x+1,1):Value  := aSparten[x,1]
          oSheet:item(x+1,2):Value  := aSparten[x,2]
          oSheet:item(x+1,3):Value  := aSparten[x,3]
          oSheet:item(x+1,4):Value  := aSparten[x,4]
          oSheet:item(x+1,5):Value  := aSparten[x,5]
          oSheet:item(x+1,6):Value  := aSparten[x,6]
          oSheet:item(x+1,7):Value  := aSparten[x,7]
    next x
----------- und jetzt sollte daneben das Chartobjekt erscheinen ------------

Makro:

Charts.Add
ActiveChart.ChartType = xlPie
ActiveChart.SetSourceData Source:=Sheets("Spartenumsätze").Range("G2:G21"), _
PlotBy:=xlColumns
ActiveChart.Location Where:=xlLocationAsObject, Name:="Spartenumsätze"
ActiveChart.HasTitle = False

-------------------------------------------------------------------------------

Grüsse
Rudolf
Alfred
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 476
Registriert: Do, 03. Mai 2007 12:37
Wohnort: München

Beitrag von Alfred »

Hallo Rudolf,

ein erstes Zwischenergebnis:

Code: Alles auswählen

oChart := oSheet1:ChartObjects:Add(45,173,320,190)
oChart:Activate
ChartObjects ist für eine leere Graphik innerhalb eines Worksheets zuständig.
Ohne Activate sieht man nichts :)

Gruß
Alfred
Alfred
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 476
Registriert: Do, 03. Mai 2007 12:37
Wohnort: München

Beitrag von Alfred »

Hallo Rudolf,

hier der Rest:

Code: Alles auswählen

oExcel:ActiveChart:SetSourceData(oSheet1:Range('G2:G21'))

Bei mir ist oExcel := CreateObject("Excel.Application")

Gruß
Alfred
Benutzeravatar
Rudolf
Programmier-Gott
Programmier-Gott
Beiträge: 1418
Registriert: Mo, 02. Jan 2006 23:03
Wohnort: Salzburg/Österreich
Kontaktdaten:

Beitrag von Rudolf »

Hallo Alfred,
bei mir funkts leider nicht, bekomme immer die Meldung dass das Objekt Chartobjects nicht existiert. Hier mein ganzer Code
Grüsse
Rudolf

Code: Alles auswählen

  oApp := CreateObject( "Excel.Application" )

  IF NIL == oApp
    wmeld("EXCEL konnte nicht geöffnet werden",4)
*    ? "Error: ", ComLastError()
*    ? "Description:"
*    ? ComLastMessage()
  ELSE

    oApp:visible := .T.                         // i want to see something
    oApp:Application:DisplayAlerts := .F.
    oApp:Application:Workbooks:new()
    oApp:Application:Workbooks:add()
    oApp:Application:Worksheets(2):activate()
    oApp:Application:Worksheets(2):name:='Spartenumsätze'
    oSheet := oApp:Worksheets(2):cells
    oSheet:Columns('A'):ColumnWidth  := 14
    oSheet:Columns('B'):ColumnWidth  :=  7
    oSheet:Columns('C'):ColumnWidth  :=  7
    oSheet:Columns('D'):ColumnWidth  :=  7
    oSheet:Columns('E'):ColumnWidth  :=  7
    oSheet:Columns('F'):ColumnWidth  :=  7
    oSheet:Columns('G'):ColumnWidth  :=  7
    oSheet:RANGE('A1:H1'):Font:Bold      := .T.
    oSheet:Columns('B'):NumberFormat := "#0,00"
    oSheet:Columns('D'):NumberFormat := "#0,00"
    oSheet:Columns('D'):NumberFormat := "#0,00"
    oSheet:Columns('E'):NumberFormat := "#0,00"
    oSheet:Columns('F'):NumberFormat := "#0,00"
    oSheet:Columns('G'):NumberFormat := "#0,00"
    oSheet:Range( "A1:G1" ):Interior:ColorIndex := 15

    oSheet:item(1,1):Value  := 'Sparte'
    oSheet:item(1,2):Value  := 'Anzahl '
    oSheet:item(1,3):Value  := 'Storno'
    oSheet:item(1,4):Value  := 'Guts.'
    oSheet:item(1,5):Value  := 'Verk.'
    oSheet:item(1,6):Value  := 'Preis'
    oSheet:item(1,7):Value  := 'Umsatz'
    for x := 1 to len(aSparten)
          oSheet:item(x+1,1):Value  := aSparten[x,1]
          oSheet:item(x+1,2):Value  := aSparten[x,2]
          oSheet:item(x+1,3):Value  := aSparten[x,3]
          oSheet:item(x+1,4):Value  := aSparten[x,4]
          oSheet:item(x+1,5):Value  := aSparten[x,5]
          oSheet:item(x+1,6):Value  := aSparten[x,6]
          oSheet:item(x+1,7):Value  := aSparten[x,7]
    next x

      oChart := oSheet:ChartObjects:Add(45,173,320,190) // !!!!!!!!!
      oChart:Activate
      oSheet:ActiveChart:SetSourceData(oSheet:Range('G2:G21'))
Benutzeravatar
Rudolf
Programmier-Gott
Programmier-Gott
Beiträge: 1418
Registriert: Mo, 02. Jan 2006 23:03
Wohnort: Salzburg/Österreich
Kontaktdaten:

Beitrag von Rudolf »

Hallo,
hab noch was rausgefunden: Den Typ kann man einfach aus der Include Date EXCEL.CH rausfinden, und wenn die Legende nicht neben der Datenspalte liegt, kann man zuerst die Legendenspalte angeben und dann mit Strichpunkt getrennt die Datenspalte:

oChart := oSheet:ChartObjects:Add(350,50,320,190)
ochart:Activate
oExcel:ActiveChart:ChartType := 5
oExcel:ActiveChart:SetSourceData(oSheet:Range('A1:A21;G1:G21'))

Grüsse
Rudolf
Bernd Reinhardt
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 159
Registriert: So, 16. Apr 2006 11:12
Wohnort: Öhringen

Beitrag von Bernd Reinhardt »

Hallo

Das Beispiel ist genau das was ich auch schon gesucht habe. Habe es gleich ausprobiert, leider stürzt das Programm immer bei dem Befehl ab:

oChart := oSheet:ChartObjects:Add(350,50,320,190)

oSheet ist vom Typ automationobject. Die Zellen in der Exceldatei werden ja auch schön (leider recht langsam) gefüllt.
Standard appsys. Ist das ein Problem?

Die xpperror.log meldet:
FEHLERPROTOKOLL von "C:\Alaska\mysamples\exceltest\main.EXE" Datum: 01.09.2007 20:00:28

Xbase++ Version : Xbase++ (R) Version 1.90.331
Betriebssystem : Windows 2000 05.00 Build 02195 Service Pack 4
------------------------------------------------------------------------------
oError:args :
-> VALTYPE: C VALUE: ChartObjects
oError:canDefault : J
oError:canRetry : N
oError:canSubstitute: J
oError:cargo : NIL
oError:description : Unbekannter Name.
Member-Variable ist f r dieses Objekt unbekannt
oError:filename : NIL
oError:genCode : NIL
oError:operation : ChartObjects
oError:osCode : -2147352570
oError:severity : 2
oError:subCode : 6500
oError:subSystem : Automation
oError:thread : 1
oError:tries : NIL
------------------------------------------------------------------------------
CALLSTACK:
------------------------------------------------------------------------------

Called from FEXCELTEST(84)
Called from MAIN(15)

Was mach ich da noch falsch.
Danke
Bernd
Bernd Reinhardt
fa.reinhardt@gmx.de
Benutzeravatar
Rudolf
Programmier-Gott
Programmier-Gott
Beiträge: 1418
Registriert: Mo, 02. Jan 2006 23:03
Wohnort: Salzburg/Österreich
Kontaktdaten:

Beitrag von Rudolf »

Hallo,
das Problem hatte ich auch, weil ich
oSheet := oApp:Worksheets(1):cells
hatte, und damit funkt's nicht.

Hier ein komplettes Beispiel:

Code: Alles auswählen

function umsatz_excel()
******************************************************************
local cFile := addpath(al_path,"export\umsatz_sparten.xls")
local aSel := saveopen("UMS"),nLine := 2
if empty(aSel)
     return .f.
endif
altd()
oExcel := CreateObject( "Excel.Application" )
IF empty(oExcel)
     wmeld("EXCEL Datei " + cFile + " konnte nicht erstellt werden",4)
     return .f.
endif
oExcel:Application:DisplayAlerts := .F.
oExcel:Application:Workbooks:new()
oExcel:visible := .T.               // i want to see something
oWorkbook = oExcel:Workbooks:Add()  //oWorkbook besser zum Suchen
oSheet := oWorkbook:Worksheets(1)   //Referenz auf das 1. Worksheet
oExcel:Application:Worksheets(1):name:='Tagesumsätze'

oSheet:Columns('A'):ColumnWidth  :=  10
oSheet:Columns('B'):ColumnWidth  :=  12
oSheet:Columns('C'):ColumnWidth  :=  20
oSheet:Columns('D'):ColumnWidth  :=  20
oSheet:Columns('E'):ColumnWidth  :=  7
oSheet:Columns('F'):ColumnWidth  :=  7
oSheet:Columns('G'):ColumnWidth  :=  7
oSheet:Columns('H'):ColumnWidth  :=  7
oSheet:Columns('I'):ColumnWidth  :=  7
oSheet:Columns('J'):ColumnWidth  :=  7
oSheet:Columns('K'):ColumnWidth  :=  7

oSheet:RANGE('A1:K1'):Font:Bold      := .T.

oSheet:Columns('E'):NumberFormat := "#0,00"
oSheet:Columns('F'):NumberFormat := "#0,00"
oSheet:Columns('G'):NumberFormat := "#0,00"
oSheet:Columns('H'):NumberFormat := "#0,00"
oSheet:Columns('I'):NumberFormat := "#0,00"
oSheet:Columns('J'):NumberFormat := "#0,00"
oSheet:Columns('K'):NumberFormat := "#0,00"

oSheet:Range( "A1:K1" ):Interior:ColorIndex := 15

oSheet:cells(1,1):Value  := 'Datum'
oSheet:cells(1,2):Value  := 'Sparte'
oSheet:cells(1,3):Value  := 'Outlet'
oSheet:cells(1,4):Value  := 'Bezeichnung'
oSheet:cells(1,5):Value  := 'Menge'
oSheet:cells(1,6):Value  := 'Umsatz'
oSheet:cells(1,7):Value  := 'Verk'
oSheet:cells(1,8):Value  := 'Guts'
oSheet:cells(1,9):Value  := 'Storno'
oSheet:cells(1,10):Value := 'Hauptg.Kost'
oSheet:cells(1,11):Value := 'Kost'

ums->(dbgotop())
nLine := 2
do while !ums->(eof())
     set_msg(dtoc(ums->datum) + ums->sparte + ums->bezeichn)
     oSheet:cells(nLine,1):Value  := shortdate(ums->datum)
     oSheet:cells(nLine,2):Value  := alltrim(ums->sparte)
     oSheet:cells(nLine,3):Value  := alltrim(ums->outletbez)
     oSheet:cells(nLine,4):Value  := alltrim(ums->bezeichn)
     oSheet:cells(nLine,5):Value  := ums->menge
     oSheet:cells(nLine,6):Value  := ums->umsatz
     oSheet:cells(nLine,7):Value  := ums->verk
     oSheet:cells(nLine,8):Value  := ums->guts
     oSheet:cells(nLine,9):Value  := ums->storno
     oSheet:cells(nLine,10):Value := ums->hauptgkost
     oSheet:cells(nLine,11):Value := ums->kost
     nLine++
     ums->(skip())
enddo
oExcel:application:workbooks(1):saveas(cFile)
oExcel:Application:Quit()
oExcel:Quit()
oExcel:destroy()
return .t.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15696
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hi,

ich habe eben mein erstes Excel Ergebnis erzeugt.
Dank der Hilfe hier ging es auch ganz flott ... danke :!:

Ich habe mich fast dusslig gesucht, da das mit dem Selection.xxx (aus Basic) nicht funktionieren wollte. Dann fiel mir auf, dass man gleiche Werte für mehrere Collumns zusammenfassen kann, und dass die Selection von Basic bei uns mit Range ersetzt werden kann:

Code: Alles auswählen


statt einzelne Aufrufe ...

oSheet:Columns('E'):ColumnWidth  :=  7
oSheet:Columns('F'):ColumnWidth  :=  7
oSheet:Columns('G'):ColumnWidth  :=  7
oSheet:Columns('H'):ColumnWidth  :=  7
oSheet:Columns('I'):ColumnWidth  :=  7
oSheet:Columns('J'):ColumnWidth  :=  7
oSheet:Columns('K'):ColumnWidth  :=  7

ein Aufruf:

oSheet:Columns('E:K'):ColumnWidth  :=  7
oSheet:Columns('E:K'):NumberFormat := "#0,00"

Wenn im VB-Macro   
   
   xxx.Select
   Selection.xxxx

steht, können wir die 
             
   oSheet:RANGE('A1:K1'):Font:Bold      := .T.

nutzen. Hier mit Beispiel FETT ein. 

Gerade weil die Macros so langsam sind, sollte man möglichst viele Bereichsbefehle statt vieler einzelner nutzen.
Gruß
Hubert
Benutzeravatar
Rudolf
Programmier-Gott
Programmier-Gott
Beiträge: 1418
Registriert: Mo, 02. Jan 2006 23:03
Wohnort: Salzburg/Österreich
Kontaktdaten:

Beitrag von Rudolf »

Hallo Hubert,
danke, guter Tip, Geschwindigkeitsoptimierung kann ich gut brauchen ;-)
Grüsse
Rudolf
Antworten