PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Excel als COM-Server mit Python - Performanceprobleme


Xmas
2003-10-27, 01:12:40
Hola,
ich habe folgendes Problem:

Ich habe ein Python-Programm, das eine gewisse Anzahl (150+) an Listen bestimmter Wörter produzert. Eine solche Liste kann z.B. so aussehen:
[ "Text", "Zahl", "-", "Zahl" "." "Satz" ]
[ "Zahl", "Datum", "Nr", "Zahl" ]

Die Anzahl möglicher Wörter ist recht begrenzt, ca. 30. Um nun die visuelle Analyse dieser Sequenzen zu erleichtern, will ich diese in Tabellenform darstellen, so dass jedes Wort in einer Zelle steht und eine bestimmte vom Wort abhängige Hintergrundfarbe hat. Also kam mir natürlich Excel in den Sinn. Leider kann ich nun z.B. mit CSV keine Farben angeben, also dachte ich mir, dass ich Excel als COM-Server gebrauche, ein Workbook/Worksheet erstelle und darauf die Zellen direkt verändere. Der Code dazu sieht folgendermaßen aus:


xlApp = win32com.client.Dispatch("Excel.Application")
xlApp.Visible = 0
xlWb = xlApp.Workbooks.Add()
xlSheet = xlApp.ActiveSheet
row = 1
for toliindex in xrange(0, len(totalist)):
# ...
column = 2
for tok in tolilist[toliindex]:
xlSheet.Cells(row, column).Value = tok
if tok in colordict.keys():
xlSheet.Cells(row, column).Interior.ColorIndex = colordict[tok]
column += 1
row += 1
xlApp.Visible = 1
try:
xlWb.SaveAs(os.path.join(os.curdir, "tabelle.xls"))
except:
pass
xlApp.Quit()
del xlApp


Das funktioniert auch, ist aber übelst langsam. Der "inner loop", also das Zuweisen von Farbe und Wert zur Zelle kriecht geradezu. Wenn ich Visible vorher schon auf 1 setze, kann ich dem Ausfüllen der Zellen geruhsam zuschauen.

Kann mir jemand sagen ob man das einigermaßen beschleunigen kann, oder auch einen anderen Weg verraten, wie man die Zellen färben kann?

Crushinator
2003-10-27, 03:12:58
Ich habe Deinen Code eben in etwa (nur mit random Werten) kurz in VB umgesetzt und kann bei 100 Rows und nur einem Column den Ablauf nicht mit dem Auge verfolgen -> In 4 Sekunden ist es durch, inklusive Aufruf von Excel.

Das würde ja bedeuten, daß entweder die COM-Schnittstelle von Python das Kriechen verursacht oder die Zeit bei Deinem "inner loop" anderweitig flöten geht. :ratlos:

Crushinator
2003-10-27, 03:56:37
Ich glaub', ich hab' jetzt das richtige gefunden:
http://mail.python.org/pipermail/python-list/2002-October/127610.html

COM ist anscheinend tatsächlich zu lahm implementiert. Also, Arrays verwenden wie dort angegeben wird, genauer gesagt 2 Arrays, einmal für Werte und einmal für Farben. In der Schleife werden also nur Arrays gefüllt und dann in einem Schlag übergeben. Ich habe es gerade ausprobiert, es klappt auch wunderbar mit den Colors.

In etwas so das Beispiel:

(...)
aLen=5
array=(("row 1 col A","row 1 col B"),
("row 2 col A","row 2 col B"),
("row 3 col A","row 3 col B"),
("row 4 col A","row 4 col B"),
("row 5 col A","row 5 col B"))
xlSheet.Range(xSheet.Cells(row,col), \
xlSheet.Cells(row+aLen-1,col+1)).Value = array
(...)

100 Werte (von A1 ausgegangen) aufeinmal in row 1 schreiben:

xlSheet.Range(xSheet.Cells(1,1), xSheet.Cells(1,100)).Value = WerteArray
xlSheet.Range(xSheet.Cells(1,1), xSheet.Cells(1,100)).Interior.ColorIndex = ColorArray

Ich glaube, das geht auch mit Mehrdimensionalen (X,Y) Arrays, dann geht's noch schneller. Ich probier's jetzt aber nicht mehr aus -> Bett ruft. =)

/edit: (Nach'm Aufstehen)
Mehrdimensionales geht nur mit den Values und dauert bei mir mit 100 x 1000 Werten + jeweils Farben insgesamt 15 Sekunden ohne Anzeige. :)

Xmas
2003-10-29, 16:40:40
Danke, das hilft mir schon mal weiter. Leider kann man bei den Farben gar keine Arrays verwenden, hier wird immer der erste Wert für die gesamte Range genommen. Nun ja, womöglich ist es am besten wenn ich da einfach ein VBA-Makro importiere, das diese Aufgabe übernimmt.

Crushinator
2003-10-29, 17:35:11
Original geschrieben von Xmas
(...) Leider kann man bei den Farben gar keine Arrays verwenden, hier wird immer der erste Wert für die gesamte Range genommen. (...) :o Sorry, vielleicht hätte ich verschiedene Werte in das ColorArray schreiben sollen, bevor ich mich freute. :banghead: :sulkoff:

Birdman
2003-10-29, 19:22:28
wieso z.B. keine HTML Datei erzeugen ?
Diese kann man notfalls auch problemlos mit einem Excel öffnen, falls es mal darum geht da was raus zu copy&pasten.

Xmas
2003-10-29, 19:47:11
Hervorragende Idee, und Excel kann damit auch problemlos um. Seltsam ist lediglich, dass alle freien Zellen dann komplett weiß sind. Und ich muss wieder die Indexfarben in RGB umwandeln, damit die Farben auch einmalig sind.

Am wichtigsten ist eigentlich, dass man die Zeilen gruppiert sortieren kann, und da bietet sich eben Excel an.

Birdman
2003-10-30, 19:31:21
Original geschrieben von Xmas
Seltsam ist lediglich, dass alle freien Zellen dann komplett weiß sind.
Das ist bei den meisten Browsern (bewusst) der Fall und ich umgehe das i.d.R. immer indem ich ein "& nbsp;" in die Zelle reinmache - doch sowas würde bei dir wohl eher stören.

Xmas
2003-10-31, 04:50:22
Original geschrieben von Birdman
Das ist bei den meisten Browsern (bewusst) der Fall und ich umgehe das i.d.R. immer indem ich ein "& nbsp;" in die Zelle reinmache - doch sowas würde bei dir wohl eher stören.
Ich meinte eigentlich nicht im Browser, sondern in Excel, und dass man die weißen Zellen auch nicht wegbekommt wenn man das ganze als xls speichert. Lediglich wenn man die Daten kopiert und in eine andere Tabelle einfügt, wird daraus eine "normale" Excel-Tabelle.