Attualmente sto eseguendo l'automazione Python di Excel con com. È perfettamente funzionante e fa ciò che voglio, ma ho scoperto qualcosa di sorprendente. A volte, alcuni dei comandi di Excel che uso falliscono con un'eccezione senza un motivo apparente. Altre volte, funzioneranno.Python clean way per racchiudere le singole istruzioni in una prova tranne il blocco
Nel codice equivalente VB per quello che sto facendo, questo problema è apparentemente considerato normale, ed è intonacato con una dichiarazione On Error Resume Next
. Python non ha detto affermazione, ovviamente.
Non riesco a concludere l'intero set in un ciclo try except
, perché potrebbe "fallire" a metà e non essere completato correttamente. Quindi, quale sarebbe un modo pitone per avvolgere diverse affermazioni indipendenti in un tentativo tranne il blocco? In particolare, qualcosa di più pulito di:
try:
statement
except:
pass
try:
statement
except:
pass
Il codice in questione è il bit excel.Selection.Borders
.
def addGridlines(self, infile, outfile):
"""convert csv to excel, and add gridlines"""
# set constants for excel
xlDiagonalDown = 5
xlDiagonalUp = 6
xlNone = -4142
xlContinuous = 1
xlThin = 2
xlAutomatic = -4105
xlEdgeLeft = 7
xlEdgeTop = 8
xlEdgeBottom = 9
xlEdgeRight = 10
xlInsideVertical = 11
xlInsideHorizontal = 12
# open file
excel = win32com.client.Dispatch('Excel.Application')
workbook = excel.Workbooks.Open(infile)
worksheet = workbook.Worksheets(1)
# select all cells
worksheet.Range("A1").CurrentRegion.Select()
# add gridlines, sometimes some of these fail, so we have to wrap each in a try catch block
excel.Selection.Borders(xlDiagonalDown).LineStyle = xlNone
excel.Selection.Borders(xlDiagonalUp).LineStyle = xlNone
excel.Selection.Borders(xlDiagonalUp).LineStyle = xlNone
excel.Selection.Borders(xlEdgeLeft).LineStyle = xlContinuous
excel.Selection.Borders(xlEdgeLeft).Weight = xlThin
excel.Selection.Borders(xlEdgeLeft).ColorIndex = xlAutomatic
excel.Selection.Borders(xlEdgeTop).LineStyle = xlContinuous
excel.Selection.Borders(xlEdgeTop).Weight = xlThin
excel.Selection.Borders(xlEdgeTop).ColorIndex = xlAutomatic
excel.Selection.Borders(xlEdgeBottom).LineStyle = xlContinuous
excel.Selection.Borders(xlEdgeBottom).Weight = xlThin
excel.Selection.Borders(xlEdgeBottom).ColorIndex = xlAutomatic
excel.Selection.Borders(xlEdgeRight).LineStyle = xlContinuous
excel.Selection.Borders(xlEdgeRight).Weight = xlThin
excel.Selection.Borders(xlEdgeRight).ColorIndex = xlAutomatic
excel.Selection.Borders(xlInsideVertical).LineStyle = xlContinuous
excel.Selection.Borders(xlInsideVertical).Weight = xlThin
excel.Selection.Borders(xlInsideVertical).ColorIndex = xlAutomatic
excel.Selection.Borders(xlInsideHorizontal).LineStyle = xlContinuous
excel.Selection.Borders(xlInsideHorizontal).Weight = xlThin
excel.Selection.Borders(xlInsideHorizontal).ColorIndex = xlAutomatic
# refit data into columns
excel.Cells.Select()
excel.Cells.EntireColumn.AutoFit()
# save new file in excel format
workbook.SaveAs(outfile, FileFormat=1)
workbook.Close(False)
excel.Quit()
del excel
Aggiornamento:
Forse è necessario un po 'di spiegazioni sul bit di errore. Due esecuzioni identiche sulla mia macchina di prova, con codice identico, sullo stesso file, producono lo stesso risultato. Una corsa genera eccezioni per ogni riga xlInsideVertical
. L'altra genera eccezioni per ogni xlInsideHorizontal
. Infine, una terza prova completa senza eccezioni.
Per quanto mi riguarda posso dire Excel considera questo comportamento normale, perché sto clonazione del codice VB costruito da macro generatore di Excel, non il codice VB prodotto da una persona. Questa potrebbe essere un'assunzione errata, ovviamente.
Funzionerà con ogni linea racchiusa in una prova tranne blocco Volevo solo qualcosa di più breve e più ovvio, perché 20 linee avvolte nei propri tentativi di cattura loop è solo per chiedere guai in seguito.
Update2:
Questo è un file CSV fregati per il test: gist file
Conclusione:
La risposta fornita da Vsekhar è perfetto. Elimina la soppressione delle eccezioni, in modo che in seguito, se e quando avrò tempo, posso effettivamente gestire le eccezioni man mano che si verificano. Consente inoltre di registrare le eccezioni in modo che non scompaiano, non interrompe altre eccezioni ed è abbastanza piccolo da essere facilmente gestibile tra sei mesi.
Che ne dici di non farlo fallire in primo luogo? Python non è PHP o Visual Basic e sfortunatamente impone una sana gestione degli errori :( –
Potresti salvare tutte le chiamate in un elenco e poi scorrere su di esse con una singola istruzione try nel ciclo? Solo non so come "salvare" questo tipo di chiamate: – rplnt
@rpInt: le istruzioni non sono oggetti di prima classe in Python - non possono essere assegnate a variabili e passate in funzioni –