为什么我基于哪个IDE执行代码在Excel COM中获得打开的工作簿的不同列表?

时间:2018-09-29 19:50:49

标签: python excel pywin32 win32com

import win32com.client as win32

excel = win32.gencache.EnsureDispatch('Excel.Application')
for wb in excel.Workbooks:
    print(wb.Name)

当我使用Sublime Text运行此脚本时: 打印打开的工作簿的名称列表。

当我使用PyCharm运行此脚本时: 我得到一个空白清单。

两者都在同一台PC上,并且使用的是同一版本的Python(3.5 32位)。

不确定这条信息是否有所作为,但是当我第一次下载PyCharm时,我从未运行过PyCharm安装程序。我下载了zip文件,每次都从解压缩的文件夹中运行PyCharm.exe。这可能是原因吗?

1 个答案:

答案 0 :(得分:2)

原因一定是,在一种情况下,您连接到一个正在运行的Excel实例,而在另一种情况下,打开一个新的Excel实例(或连接到其他一些实例)。

要确保连接到现有实例,可以按照Attaching to an already running Office application from your application using GetActiveObject or BindToMoniker – .NET4Office使用mergeMap


我不确定什么时候会发生,但是这些是我注意到的模式,可以解释您看到的内容:

  • 如果您有一个在运行程序之前手动启动的Excel实例,则程序会连接到该实例
  • 如果不是,则托管DCOM进程启动器服务的win32com.client.GetActiveObject(<ProgID>)进程会生成一个excel.exe实例
    • 此实例最初没有打开任何工作簿
  • 但是,如果之后手动启动Excel,则会创建另一个实例。 DCOM实例具有优先权。
  • An instance is not closed even after .Quit as long as there are references to it,因此在引用该进程的同时从该进程进行的任何进一步分派都将获得相同的实例。
  • 您无法连接到以不同用户身份运行的Excel进程(这包括带高程与不带高程)。

因此,如果您从交互式控制台运行代码,或者IDE不会每次都重新启动Python进程(不太可能,但是可能),您可能已有旧的引用。