【发布时间】:2011-11-08 10:22:37
【问题描述】:
我目前正在使用 com 对 Excel 进行一些 Python 自动化。它功能齐全,可以做我想做的事,但我发现了一些令人惊讶的事情。有时,我使用的某些 Excel 命令会因为没有明显原因的异常而失败。其他时候,他们会工作。
在我正在做的 VB 等效代码中,这个问题显然被认为是正常的,并且被 On Error Resume Next 声明所覆盖。 Python当然没有这种说法。
我不能在try except 循环中结束整个集合,因为它可能在中途“失败”并且无法正确完成。那么,将几个独立语句包装到 try except 块中的pythonic方法是什么?具体来说,比以下更干净的东西:
try:
statement
except:
pass
try:
statement
except:
pass
相关代码为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
更新:
也许需要对错误位进行一些解释。在我的测试机器上运行两次相同的代码,在同一个文件上,产生相同的结果。一次运行会为每个 xlInsideVertical 行引发异常。另一个为每个xlInsideHorizontal 抛出异常。最后,第三次运行完成,没有任何异常。
据我所知,Excel 认为这是正常行为,因为我正在克隆由 excel 的宏生成器构建的 VB 代码,而不是由人生成的 VB 代码。当然,这可能是一个错误的假设。
它会在包裹在 try except 块中的每一行起作用
更新2:
这是一个用于测试的已清理 CSV 文件:gist file
结论:
Vsekhar 提供的答案是完美的。它抽象出异常抑制,以便以后,如果有时间,我可以在异常发生时实际处理它们。它还允许记录异常,以便它们不会消失,不会停止其他异常,并且足够小,可以在六个月后轻松管理。
【问题讨论】:
-
一开始就让它不失败怎么样? Python 不是 PHP 或 Visual Basic,不幸的是它强制执行合理的错误处理:(
-
您能否将所有调用保存在一个列表中,然后在循环中使用单个 try 语句对其进行迭代?只是不知道如何“保存”这种调用。
-
@rpInt:语句不是 Python 中的一流对象——它们不能分配给变量并传递给函数
-
你能上传一个显示问题的虚拟表吗?您的代码似乎对我来说始终如一(在删除 xlDiagonalup 之后——注意小写的 u 行,这让我认为上面的代码不可能是您实际运行的代码)。
-
@Spencer Rathbun:感谢您发布示例文件。我在 07 年尝试了数百次,没有一次失败,所以我在 Excel 方面没有任何有用的建议,因为我无法让它崩溃。无用的事情涉及尝试选择哪个区域,看看(例如)它是否总是适用于小的 2x2 块,或者进行手动选择而不是接受区域等,但这些都是基于尝试想象 Excel 问题可能是什么的随机猜测。
标签: python excel vba com try-catch