Schreiben in eine geöffnete Excel Datei

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
JaSyMa
User
Beiträge: 30
Registriert: Sonntag 3. September 2023, 10:52

Hallo zusammen,

ich würde gern ein skript per VBA aus Excel starten. Dieses soll dann eine Berechnung anstellen und das Ergebnis in die geöffnete Datei schreiben (von der das Skript gestartet wurde).

Jetzt geht dies auf direktem Weg nicht, da das direkte Schreiben in die geöffnete Datei nicht funktioniert.

Gibt es irgendeinen workaround, wie ich das Ergebnis in die geöffnete Datei bekomme? An sich gefällt mir die Idee, mit einer Datei zu arbeiten ohne diese direkt öffnen zu müssen, aber hier brauche ich explizit die Möglichkeit, da die zu beschreibende Datei der "Trigger" des Skripts ist.

Habt Ihr dafür eine schlaue Idee?

BG
JaSyMa
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

So zB: https://stackoverflow.com/questions/721 ... and-python

Du kannst natürlich auch den Umweg über eine temporäre Datei machen, die das Python Skript anlegt. Und ggf geht auch das fernsteuern von Excel via COM.
JaSyMa
User
Beiträge: 30
Registriert: Sonntag 3. September 2023, 10:52

Danke für Dein schnelles feedback. Den Weg über die Temp Datei gehe ich aktuell, aber direkt schreiben wäre natürlich effizienter. So muss ich via VBA die TempDatei immer erst wieder öffnen, was den Performancegewinn von Python wieder egalisiert. Alternativ Zugriff auf die geschlossene Datei via ADO o.ä., aber alles eben "umständlich um die Ecke"...

Hatte gehofft; dass die Datei als aufrufende ihre Zugriffsberechtigungen vererben kann oder Python das Ergebnis Array irgendwo zwischen speichert und ich es via VBA von dort holen kann. In etwa wie Berechnungen im Arbeitsspeicher, die ich dann mit einem Rutsch wieder zurück ins (aufrufende) Excel kippe...
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das du eine Datei beschreiben kannst, die gleichzeitig von einem laufenden Programm als aktulles Dokmuent dient, ist schlicht unrealistisch. Das geht schon mit simplen Textdateien nicht, sowas komplexes wie Excel muss da erst recht kapitulieren. Und die gezeigte IPC-loesung ist doch letztlich nix anderes als shared memory.
Sirius3
User
Beiträge: 17759
Registriert: Sonntag 21. Oktober 2012, 17:20

Denke nicht kompliziert, benutze DCOM.
JaSyMa
User
Beiträge: 30
Registriert: Sonntag 3. September 2023, 10:52

Sirius3 hat geschrieben: Montag 4. September 2023, 06:41 Denke nicht kompliziert, benutze DCOM.
Habe davon leider überhaupt keine Ahnung. Hab es gegoogelt, aber krieg damit nicht den Umsetzungsweg für meinen konkreten use case hin. Kannst Du ein wenig helfen?
Sirius3
User
Beiträge: 17759
Registriert: Sonntag 21. Oktober 2012, 17:20

Wie sieht denn Dein konkreter Use-Case aus?
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

@JaSyMa:

2010 hab ich das ungefähr so gemacht:

Code: Alles auswählen

import win32com.client as com

filename = ...
data_rows = ...
top = ...
left = ...
right = ...

# Excel starten:
xl = com.Dispatch('Excel.Application')

# Datei öffnen und auf das erste Sheet zugreifen:
xls = xl.Workbooks.Open(filename).Worksheets(1)

# data_rows in den ausgewählten Bereich schreiben:
xls.Range(
    xls.Cells(top, left),
    xls.Cells(top + len(data_rows) - 1, right)
).Value = data_rows

# Speichern nicht vergessen:
xls.Parent.SaveAs()

# Excel wieder schließen:
xl.Quit()
Ob das heute noch genauso geht - keine Ahnung.
In specifications, Murphy's Law supersedes Ohm's.
August1328
User
Beiträge: 65
Registriert: Samstag 27. Februar 2021, 12:18

Wie ein anderes Foren Mitglied vor 2 Wochen schon gepostet hat, kann man (gewissen) Python Code inzwischen direkt in Excel ausführen:

https://techcommunity.microsoft.com/t5/ ... -p/3893439

Ich selber habe es noch nicht getestet, aber vielleicht hilft das bei Deinem use-case, da man in der selben Datei bleibt.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das Problem ist hier ja die schno laufenden Anwendung, mit geoeffneter Datei. Genauso wird das also nix, aber aehnlich ist es natuerlich schon. Siehe zB http://timgolden.me.uk/python/win32_how ... tance.html
Benutzeravatar
grubenfox
User
Beiträge: 433
Registriert: Freitag 2. Dezember 2022, 15:49

August1328 hat geschrieben: Montag 4. September 2023, 09:15 Wie ein anderes Foren Mitglied vor 2 Wochen schon gepostet hat, kann man (gewissen) Python Code inzwischen direkt in Excel ausführen:

https://techcommunity.microsoft.com/t5/ ... -p/3893439

Ich selber habe es noch nicht getestet, aber vielleicht hilft das bei Deinem use-case, da man in der selben Datei bleibt.
Ich bin da eher für ein lokal installiertes xlwings statt so ein Python das irgendwo in Excel365 in der Cloud läuft...

(habe auch ich aber bisher noch nicht selbst ernsthaft getestet)
JaSyMa
User
Beiträge: 30
Registriert: Sonntag 3. September 2023, 10:52

Sirius3 hat geschrieben: Montag 4. September 2023, 08:55 Wie sieht denn Dein konkreter Use-Case aus?
Wie im Eingangspost versucht zu beschreiben will ich aus einer geöffneten Exceldatei via VBA ein Python Skript callen und das Ergebnis wieder in die geöffnete Datei schreiben.
grubenfox hat geschrieben: Montag 4. September 2023, 09:56 [quote=August1328 post_id=422835 time=<a href="tel:1693815304">1693815304</a> user_id=26522]
Wie ein anderes Foren Mitglied vor 2 Wochen schon gepostet hat, kann man (gewissen) Python Code inzwischen direkt in Excel ausführen:

https://techcommunity.microsoft.com/t5/ ... -p/3893439

Ich bin da eher für ein lokal installiertes xlwings statt so ein Python das irgendwo in Excel365 in der Cloud läuft...
Das Cloudthema sehe ich auch kritisch. Weniger w/“Datengeheimnissen”, sondern der Abhängigkeit vom Internet, Microsoftserver etc. Dinge also, die meine Anwendung einschränken können und außerhalb meines Einflussbereichs sind.

Was ist denn mit xlwings? Das scheint doch das ganze in einer lokalen Umgebung möglich zu machen. Wo sind die Nachteile?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das es selbst eine Datei bearbeitet, was du ausweislich nicht willst.
JaSyMa
User
Beiträge: 30
Registriert: Sonntag 3. September 2023, 10:52

Für mich haben sich die Beispiele so gelesen, dass die Funktion “RunPython” ein Skript startet und dies dann auch die Ergebnisse (dort illustriert an einem Diagramm) in die aufrufende Datei zurückschreibt. Aber Ihr versteht sehr viel mehr davon und wenn es das nicht ist werde ich wohl die Berechnungsergebnisse I. Python in ein JSON Schreiben und das dann nach Rückgabe vom VBA in die Datei schreiben lassen…
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das stimmt schon, das schreibt zurück. Es geht nur nicht, weil Excel die Datei in dem Moment schon auf hat.
JaSyMa
User
Beiträge: 30
Registriert: Sonntag 3. September 2023, 10:52

__deets__ hat geschrieben: Montag 4. September 2023, 09:19 Das Problem ist hier ja die schno laufenden Anwendung, mit geoeffneter Datei. Genauso wird das also nix, aber aehnlich ist es natuerlich schon. Siehe zB http://timgolden.me.uk/python/win32_how ... tance.html
Ich wollte den Code von Tim mal probieren. Leider scheitert es schon beim Schreiben in die mit wb geöffnete Datei mit dem Fehler:

TypeError: a bytes-like object is required, not 'str'

Öffne ich mit 'w' kommt der Fehler wird die Schleife (for i in range...) in die temp csv geschrieben, aber das script schreibt dennoch am Ende nicht in meine geöffnete Exceldatei. Die csv bleibt am ende als in excel geöffnete Datei offen.

Was mache ich falsch?
Sirius3
User
Beiträge: 17759
Registriert: Sonntag 21. Oktober 2012, 17:20

pillmuncher hat Dir doch jetzt auch noch schönen Beispielcode geliefert. Warum benutzt Du nicht das, was vorgesehen ist, um mit Excel zu arbeiten?
Für eine offene Datei sieht das dann so aus:

Code: Alles auswählen

import win32com.client as com

excel = com.Dispatch('Excel.Application')
sheet = excel.ActiveSheet

# data_rows in den ausgewählten Bereich schreiben:
sheet.Range("A1:H8").Value = data_rows
JaSyMa
User
Beiträge: 30
Registriert: Sonntag 3. September 2023, 10:52

Das klappt super, danke Sirius3. Ich hatte deets mit
__deets__ hat geschrieben: Montag 4. September 2023, 09:19 Das Problem ist hier ja die schno laufenden Anwendung, mit geoeffneter Datei. Genauso wird das also nix
falsch verstanden, da ich dachte diese Anmerkung bezieht sich auf den code von pillmuncher.

Bei den Berechnungen durchlaufe ich eine Schleife, die nacheinander 240 Werte berechnet (für vier Parameter jeweils 60 Monate). Das bedeutet ich habe eine 4*60 Matrix. Ich habe es jetzt getestet, indem jeder der 240 Werte direkt nach der jeweiligen Berechnung in das Excel geschrieben wird. Ich vermute, dass ist sehr viel langsamer als einmal alle 240 Werte zu berechnen, das ganze in ein Array (in Python dictionary?) zu schreiben und dann am Stück in die Datei zu kippen.

Macht letzteres Sinn und wie kann ich (i) das array/dictionary aufbauen und es (ii) in einem Stück in die Datei einfügen?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Na mindestens mal fuer eine Spalte mach Sirus3 das doch vor. Aber das klingt auch alles sehr nach gefuehlten Performance-Problemen. Mach es erstmal korrekt, und wenn du dann Probleme hast, und nicht nur antizipierst, *dann* optimiert man da rum.
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

@JaSyMa: In meinem Beispiel habe ich doch gezeigt, wie man ganze Bereiche in Excel einfügt, nicht nur einzelne Werte in einzelne Zellen. Der zugewiesene Wert muss einfach eine Liste von Listen mit denselben Dimensionen sein, wie der ausgewählte Bereich (Range) im Excel Sheet.
In specifications, Murphy's Law supersedes Ohm's.
Antworten