【问题标题】:Control 2 separate Excel instances by COM independently... can it be done?通过COM独立控制2个单独的Excel实例......可以做到吗?
【发布时间】:2010-10-05 17:47:12
【问题描述】:

我有一个旧版应用程序,它在许多 Excel 工作簿中实现。这不是我有权重新实现的东西,但是我维护的另一个应用程序确实需要能够调用 Excel 工作簿中的函数。

它被赋予了一个使用 Win32Com 库的 python 接口。其他进程可以调用我的 python 包中的函数,然后通过 Win32Com 调用我需要的函数。

不幸的是,COM 不允许我指定特定的 COM 进程,所以目前无论我的服务器多么强大,我都只能在计算机上一次控制一个 Excel 实例。如果我要尝试运行多个 excel 实例,则无法确保 python 层绑定到特定的 Excel 实例。

我希望能够在我的 Windows 服务器上同时运行 1 个以上的 Excel 应用程序。有没有办法做到这一点?例如,我是否可以划分我的环境,以便我可以运行我的应用程序支持的尽可能多的 Excel _ Python 组合?

【问题讨论】:

    标签: python windows excel com


    【解决方案1】:

    参见"Starting a new instance of a COM application" by Tim Golden,也参考here,提供使用提示

    xl_app = DispatchEx("Excel.Application")
    

    而不是

    xl_app = Dispatch("Excel.Application")
    

    启动一个单独的进程。所以你应该能够做到:

    xl_app_1 = DispatchEx("Excel.Application")
    xl_app_2 = DispatchEx("Excel.Application")
    xl_app_3 = DispatchEx("Excel.Application")
    

    请注意,完成后,要关闭应用程序,我发现有必要这样做:

    xl_app.Quit()
    xl_app = None
    

    我发现进程直到xl_app = None 才会关闭,也就是说,Python COM 对象的引用计数变为零。

    注意我还有一个问题:当我的 Python 程序运行时,如果我在资源管理器中双击一个 Excel 文件(至少在 Win2k 上),它最终会打开该文件在 Python 启动的现有 Excel 进程中(隐藏运行),这会破坏 Python 程序。我还没有找到解决办法。

    【讨论】:

    • 非常感谢。你的解决方案让我很开心!
    • 你也成就了我的一天!我希望我可以投票给你 100 次,或者只是给你我所有的分数!这让我很生气!非常感谢
    • 谢谢 :) 不幸的是,Excel 无法打开新 Windows 的问题非常有名且令人讨厌。但也许blogs.office.com/2013/06/03/… 可以帮助你...
    • 在我发表上述评论 7 年多之后,我才回到这个问题,却发现我在不同的脚本上遇到了类似的问题......希望这能帮助我再次找到解决方案!
    【解决方案2】:

    不幸的是,我对 Python 一无所知,但如果它通过 COM 工作,Excel 就不是单实例应用程序,因此您应该能够在内存允许的情况下创建尽可能多的 Excel 实例。

    使用 C#,您可以通过以下方式创建多个 Excel 应用程序实例:

    Excel.Application xlApp1 = new Excel.Application();
    Excel.Application xlApp2 = new Excel.Application();
    Excel.Application xlApp3 = new Excel.Application();
    

    在 C# 中使用后期绑定,您可以使用:

    object objXL1 = Activator.CreateInstance(Type.GetTypeFromProgID("Excel.Application"));
    object objXL2 = Activator.CreateInstance(Type.GetTypeFromProgID("Excel.Application"));
    object objXL3 = Activator.CreateInstance(Type.GetTypeFromProgID("Excel.Application"));
    

    如果使用 VB.NET、VB6 或 VBA,您可以使用 CreateObject,如下所示:

    Dim objXL1 As Object = CreateObject("Excel.Application")
    Dim objXL2 As Object = CreateObject("Excel.Application")
    Dim objXL3 As Object = CreateObject("Excel.Application")
    

    不幸的是,在 Python 中,我一无所知。但除非 Python 有一些限制(我无法想象?),否则我会认为它非常可行。

    也就是说,让多个 Excel 实例充当某种服务器以进行其他操作的想法听起来很危险……我会小心测试你在做什么,尤其是关于你可以使用多少个实例立即打开而不会耗尽内存,如果 Excel 因某种原因崩溃,调用程序会发生什么情况。

    【讨论】:

    • 是的,启动两个不同的 Excel 实例没问题;只是你不能打开多个 Excel 应用程序并使用 GetObject 获取它们的 COM 进程...
    • 好吧,没错……但是任何使用 Excel 作为任何服务后端的人都不应通过 GetObject() 劫持其他 Excel 进程。它应该只创建和使用自己的 Excel 实例。否则,您的应用程序可能会与使用 Excel 实例的用户或其他进程发生冲突。 :-(
    【解决方案3】:

    如果您的应用程序使用包含您调用的宏的单个 excel 文件,我担心答案可能是否定的,因为除了 COM Excel 不允许以相同的名称打开相同的文件(即使在不同的目录中) .您可以通过在打开之前将文件动态复制到另一个名称来解决此问题。

    我的 Python 知识并不丰富,但在大多数语言中,有一种方法可以指定创建 COM 对象时是希望它是新对象还是默认连接到预先存在的实例。检查 python 文档以了解这些方面的内容。

    您能否列出您遇到的具体问题以及您希望做什么?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-20
      • 1970-01-01
      • 1970-01-01
      • 2011-07-07
      • 1970-01-01
      • 1970-01-01
      • 2021-02-15
      • 1970-01-01
      相关资源
      最近更新 更多