Python: 使用Win32 COM Api打开Excel工作簿

11

我正在使用以下代码在Excel中打开和显示一个工作簿:

import win32com.client as win32
excel = win32.gencache.EnsureDispatch('Excel.Application')
wb = excel.Workbooks.Open('my_sheet.xlsm')
ws = wb.Worksheets('blaaaa') 
excel.Visible = True

当文件 "my_sheet.xlsm" 已经打开时,Excel 会询问我是否要重新打开它而不保存。

我如何事先检查工作簿是否已经打开,并在这种情况下将其置于前台?

编辑:现在已找到:

if excel.Workbooks.Count > 0:
    for i in range(1, excel.Workbooks.Count+1):
        if excel.Workbooks.Item(i).Name is 'my_sheet.xlsm':
            wb = excel.Workbooks.Item(i)
            break

还有一个问题:我的工作表包含一些启用了过滤的标题。所以当设置过滤器并从Python打开Workbook时,它有时会要求我输入一个唯一名称来保存过滤器。为什么会这样?下面是对话框:

enter image description here

编辑 好的,在这里(德语)说,后面的问题是2007和2010文件中已知的错误:https://social.msdn.microsoft.com/Forums/de-DE/3dce9f06-2262-4e22-a8ff-5c0d83166e73/excel-api-interne-namen,如果您以编程方式打开Excel文件,则似乎会出现此问题。不知道是否有解决方法。

1个回答

18

如果你已经找到了解决方案,考虑使用try/except/finally块。当前,即使你关闭可见的工作表,你的代码仍会在后台运行Excel.exe进程(如果使用Windows,请检查任务管理器)。顺便提一下,在Python或任何其他语言中,如VBA,任何外部API(如此COM接口)都应该在应用程序代码期间进行清理。

下面的解决方案使用一个定义好的函数openWorkbook()去尝试两个可能的路径:1)首先尝试重新启动指定的工作簿,假设它已经打开了;2)如果当前没有打开,就启动该位置的新工作簿对象。最后嵌套的try/except用于处理Workbooks.Open()方法失败的情况,例如文件名不正确。

import win32com.client as win32

def openWorkbook(xlapp, xlfile):
    try:        
        xlwb = xlapp.Workbooks(xlfile)            
    except Exception as e:
        try:
            xlwb = xlapp.Workbooks.Open(xlfile)
        except Exception as e:
            print(e)
            xlwb = None                    
    return(xlwb)

try:
    excel = win32.gencache.EnsureDispatch('Excel.Application')
    wb = openWorkbook(excel, 'my_sheet.xlsm')
    ws = wb.Worksheets('blaaaa') 
    excel.Visible = True

except Exception as e:
    print(e)

finally:
    # RELEASES RESOURCES
    ws = None
    wb = None
    excel = None

这很完美 :-) - tim
@Parfait你的try/except/finally解决方案太棒了!不过最近我发现我有几个文件在后台运行时被卡住了,我无法通过任务管理器将其释放。虽然我想删除这些文件,但它们显示正在编辑中。我不想每次都重启系统来解决这个问题,有什么方法可以解锁它们吗? - user13412850
没有更多关于这些文件如何运行的上下文,我无法提供帮助。此解决方案仅释放它生成的资源。然而,这个特定的答案启动Excel应用程序到屏幕并保持应用程序和工作簿打开。为了在后台保持隐藏并释放进程,请在try块中使用以下代码:excel.Visible = Falsewb.Close(True)excel.Quit - Parfait

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接