【问题标题】:Word VBA and Multiple Word InstancesWord VBA 和多个单词实例
【发布时间】:2019-01-29 03:13:41
【问题描述】:

早上好。

我无法让我的代码找到单词的其他实例,并且在经过大量谷歌搜索后遇到了问题。

下面的“我的代码”将找到所有打开的 Word 文档并将它们填充到组合框中。

我的问题是我们的应用程序(我无法控制这些)会在新实例中打开 word 文档,因此我的代码将无法找到/控制这些文档。

有什么想法吗?

Dim objWordDocument As Word.Document
Dim objWordApplication As Word.Application


'//find all open word documents
Set objWordApplication = GetObject(, "Word.Application")

'//clear combobox
    OpenDocs.Clear

'//add all open documents to combo box

        For Each objWordDocument In objWordApplication.Documents

            OpenDocs.AddItem objWordDocument.Name

        Next objWordDocument

【问题讨论】:

  • 我在下面的回答让您可以遍历所有 Word 实例,包括僵尸,而不必杀死任何实例;从此时起,您将使用 Get AccessibleObjectFromWindow 获得任何实例

标签: vba ms-office ms-word


【解决方案1】:

据我所见并了解,唯一可靠的方法是遍历 word 的运行实例,然后依次杀死每个实例,以确保获得下一个实例。

由于单词在运行对象表中的每个实例都以完全相同的方式注册,因此如果不先关闭您正在查看的对象,就无法通过它们。

此方法的一个选项可能是不可取的,即在您终止应用程序实例时获取所有文件名,然后将它们全部加载回您创建的一个实例中。

或者,如果您知道打开文件的名称,您可以通过打开文件名“getObject”,因为 Word 会将其文档名称推送到正在运行的对象表中,遗憾的是这听起来不像您的情况。

如果不编写活动的 x MFC 服务,您将无法做您想做的事情。

我希望这会有所帮助。

编辑:

关于子类化和 Windows API 以获得句柄以改变焦点进行了广泛的讨论。 http://www.xtremevbtalk.com/showthread.php?t=314637

如果您首先深入到那个头并且能够通过 hwnd 枚举单词实例,那么您可能会依次关注每个实例,然后列出文件名。不过我确实警告过你;那是一些令人讨厌的子类化,这是只有一些真正想不小心破坏东西的人才会玩的黑魔法。

无论如何,如果您想查看一个实例,杀死,重复,重新打开试试这个:

改编自这个帖子:http://www.xtremevbtalk.com/showthread.php?t=316776

Set objWordApplication = GetObject(, "Word.Application")

'//clear combobox
    OpenDocs.Clear

'//add all open documents to combo box

   Do While Not objWordDocument is nothing 

        For Each objWordDocument In objWordApplication.Documents

            OpenDocs.AddItem objWordDocument.Name

        Next objWordDocument
        objWordApplication.Quit False
        Set objWordApplication = Nothing
        Set objWordApplication = GetObject(, "Word.Application")
   loop

   ** use create object to open a new instance of word here and then go though
   ** your list of files until you have opened them all as documents in the new
   ** instance.

【讨论】:

  • 感谢您的回复@Pow-Ian。你是对的,我不会知道第二次打开文件的名称。我将考虑杀死我的代码/应用程序并让它在 seocnd 实例中重新打开,看看它是否有效。有什么建议吗?
  • 好吧,你可以很容易地杀死它并获得文件名,但是让同一个实例恢复活力,以便创建它的应用程序/进程能够识别它超出了实际范围在 vba 中是可能的,除非有办法对其进行子类化。我会详细说明抓杀。
  • 非常感谢您迄今为止的帮助!一旦我有 15 个代表,我会将您的帖子标记为有用 :)
  • 没问题。如果你决定调用 Windows API 并开始子类化,我保证当出现严重错误时我不会告诉你我告诉过你的。
  • 今天下午我会玩一下它,看看我的表现如何。感谢您的帮助和建议:)
【解决方案2】:

这是一个旧线程,但我也需要遍历 Word 实例并在这里碰到。

按照@Pow-Ian 的建议,我尝试这样做

如果你先进入那个脑袋并且能够列举出这个词 hwnd 的实例,那么您可能会依次关注每个实例 然后列出文件名。

虽然我已经掌握了所有的句柄,但我通过AccessibleObjectFromWindow找到了一个更简单的关于办公应用程序的策略,我们的问题现在已经解决了。

另外,我相信显示@Pow-lan's 的代码有误

Do While Not objWordDocument is nothing

应该是:

Do While Not objWordApplication is nothing

【讨论】:

  • @Martijn Pieters,我稍微修改了我的答案以更好地符合格式。否则,我不知道您为什么删除了我以前已经获得赞成票的答案……您能为我澄清一下吗?据我了解,这里的答案,重定向到另一个不适合评论,这不是非法的;在我什至在另一个答案中输入错误之后 - 好的,这可能是一个评论。
  • 至于删除答案的原因:1)对问题或其他答案的评论,2)提出另一个不同的问题,3)其他答案的完全重复,3)甚至没有部分答案实际的问题,我知道 1) 可能适用于后半部分,但前半部分是我提出了一种不同的策略,以避免他杀死并重新打开所有 Word 实例。我可以从那里复制并粘贴一些代码,但我认为作为百科全书链接答案更有用......但如果你或任何版主这么认为,我可以删除它并发布一个实际完整的答案......跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-18
  • 1970-01-01
  • 1970-01-01
  • 2014-08-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多