Ich mache derzeit einige Python-Automatisierung von Excel mit com. Es ist voll funktionsfähig und tut was ich will, aber ich habe etwas Überraschendes entdeckt. Manchmal werden einige der Excel-Befehle, die ich verwende, mit einer Ausnahme ohne ersichtlichen Grund fehlschlagen. Zu anderen Zeiten werden sie arbeiten.
Im VB-äquivalenten Code für das, was ich mache, wird dieses Problem offensichtlich als normal betrachtet und mit einer On Error Resume Next
-Anweisung überlagert. Python hat diese Aussage natürlich nicht.
Ich kann nicht den ganzen Satz in einer try except
-Schleife einpacken, weil es auf halbem Weg "fehlschlagen" und nicht richtig abgeschlossen werden kann. Also, was wäre ein Python-Weg, um mehrere unabhängige Aussagen in einen Versuch außer Block zu verpacken? Genauer gesagt, etwas sauberer als:
Der relevante Code ist das excel.Selection.Borders
-Bit.
Aktualisieren :
Vielleicht ist ein bisschen Erklärung des Fehlerbits erforderlich. Zwei identische Läufe auf meiner Testmaschine mit identischem Code in der gleichen Datei erzeugen das gleiche Ergebnis. Ein Lauf löst Ausnahmen für jede xlInsideVertical
-Zeile aus. Der andere gibt Ausnahmen für jedes xlInsideHorizontal
aus. Schließlich wird ein dritter Lauf ohne Ausnahmen abgeschlossen.
Soweit ich das beurteilen kann Excel berücksichtigt dieses normale Verhalten, weil ich den VB-Code kloniere, der durch den Makrogenerator von Excel erzeugt wurde, nicht den von einer Person erzeugten VB-Code. Dies könnte natürlich eine falsche Annahme sein.
Es wird funktionieren mit jeder Zeile in einem Versuch verpackt außer Block Ich wollte nur etwas kürzer und offensichtlicher, weil 20 Zeilen in ihre eigenen Versuch fangen Schleifen nur um Ärger später gefragt.
Update2 :
Dies ist eine geschrubbte CSV-Datei zum Testen: gist-Datei
Fazit :
Die Antwort von Vsekhar ist perfekt. Es abstrahiert die Ausnahmeunterdrückung, so dass ich später, falls und wenn ich Zeit habe, tatsächlich mit den Ausnahmen umgehen kann, wenn sie auftreten. Es erlaubt auch, die Ausnahmen zu protokollieren, damit sie nicht verschwinden, andere Ausnahmen nicht stoppen und klein genug ist, um in sechs Monaten leicht zu verwalten zu sein.
Ziehen Sie in Betracht, die Unterdrückung zu abstrahieren. Und zu Aarons Punkt, schlucke Ausnahmen generell nicht.
%Vor%Dann notieren Sie im Traceback Ihres aktuellen Codes genau, welche Ausnahme ausgelöst wird, und erstellen Sie einen Suppressor nur für diese Ausnahme:
%Vor%Auf diese Weise erhalten Sie eine zeilenweise Ausführung (so dass Ihre Rückverfolgungen immer noch hilfreich sind), und Sie unterdrücken nur die Ausnahmen, die Sie explizit beabsichtigt haben. Andere Ausnahmen verbreiten sich wie üblich.
Ausnahmen treten niemals "ohne ersichtlichen Grund" auf. Es gibt immer einen Grund und dieser Grund muss behoben werden. Andernfalls wird Ihr Programm beginnen, "zufällige" Daten zu produzieren, wobei "zufällig" dem Fehler, den Sie verstecken, ausgeliefert ist.
Aber natürlich brauchen Sie eine Lösung für Ihr Problem. Hier ist mein Vorschlag:
Erstellen Sie eine Wrapper-Klasse, die alle von Ihnen benötigten Methoden implementiert und an die reale Excel-Instanz delegiert.
Fügen Sie einen Decorator vor jeder Methode hinzu, die die Methode in einem try except
-Block umschließt und die Ausnahme protokolliert. Ausnahmen nicht verschlingen
Nun funktioniert der Code für Ihren Kunden, der Ihnen etwas Zeit gibt, um die Ursache des Problems herauszufinden. Meine Vermutung ist, dass a) Excel keine sinnvolle Fehlermeldung erzeugt oder b) der Wrapper-Code die wirkliche Ausnahme verschluckt und Sie im Dunkeln bleiben oder c) die Excel-Methode einen Fehlercode zurückgibt (wie "false" für "failed") und Sie müssen eine andere Excel-Methode aufrufen, um festzustellen, wo die Ursache des Problems liegt.
[BEARBEITEN] Basierend auf dem folgenden Kommentar, der auf "Mein Chef ist mir egal und ich kann nichts tun" hinausläuft: Du verpasst einen entscheidenden Punkt: Es sind deine Bosse em> duty um die Entscheidung zu treffen, aber es Ihre Pflicht ist, ihr eine Liste von Optionen zusammen mit Pros / Contras zu geben, damit sie eine fundierte Entscheidung treffen kann. Nur dazusitzen und zu sagen: "Ich kann nichts", bringt dich in Schwierigkeiten, die du vermeiden willst.
Beispiel:
Pro: Geringster Arbeitsaufwand Con: Es besteht die Möglichkeit, dass die resultierenden Daten falsch oder zufällig sind. Wenn wichtige Geschäftsentscheidungen darauf basieren, besteht ein hohes Risiko, dass diese Entscheidungen falsch sind.
Pro: Wenig Arbeit, Benutzer können anfangen, die Ergebnisse schnell zu verwenden, Zeit kaufen, um die Quelle des Problems herauszufinden Con: "Wenn du es heute nicht reparieren kannst, was lässt dich denken, dass du morgen Zeit hast es zu reparieren?" Außerdem kann es lange dauern, bis Sie die Ursache des Problems gefunden haben, weil Sie kein Experte sind.
Suchen Sie einen Experten auf dem Gebiet und helfen Sie ihm, die Lösung zu suchen / verbessern.
Pro: Wird viel schneller eine Lösung finden, als sich mit COM vertraut zu machen Con: Teuer, aber hohe Erfolgschancen. Wird auch Probleme finden, von denen wir nicht einmal wissen.
...
Ich denke, Sie sehen das Muster. Chefs treffen falsche Entscheidungen, weil wir sie (willentlich) zulassen. Jeder Boss auf der Welt freut sich über harte Fakten und Input, wenn er eine Entscheidung treffen muss (nun, diejenigen, die das nicht tun, sollten keine Chefs sein, also ist dies eine todsichere Art zu wissen, wann man nach einem neuen Job sucht) .
Wenn Sie Lösung Nr. 2 auswählen, wählen Sie den Wrapper-Ansatz. In den Dokumenten erfahren Sie, wie Sie einen Decorator schreiben ( Beispiel von IBM ). Es ist nur ein paar Minuten Arbeit, um alle Methoden zu verpacken, und es wird Ihnen etwas geben, mit dem Sie arbeiten können.
Der nächste Schritt besteht darin, ein kleineres Beispiel zu erstellen, das manchmal fehlschlägt, und dann spezifische Fragen zu Python, Excel und dem COM-Wrapper zu stellen, um den Grund für die Probleme herauszufinden.
[EDIT2] Hier ist ein Code, der die "gefährlichen" Teile in einer Hilfsklasse umschließt und das Aktualisieren der Stile vereinfacht:
%Vor%Verwendung:
%Vor% Dies schließt nur Funktionsaufrufe ein, aber Sie können es erweitern, um auch den Attributzugriff zu behandeln und die Ergebnisse der geschachtelten Attributzugriffe als Proxy zu übernehmen und schließlich den __setattr__
in Ihren try:except
-Block zu wickeln.
Es könnte sinnvoll sein, in Ihrem Fall nur bestimmte Ausnahmetypen zu schlucken (wie @vsekhar sagt).
%Vor%Beispiel:
%Vor%