在 VBA 宏中打开/激活 Word 文档
我希望VB/VBA专家能帮助我。 考虑以下: 用户在 Word 2003 中打开一个文档,在 Normal.dot AutoOpen 宏中,我们查看当前文档,是否已通过单击网页上的链接打开该文档,并且满足某些其他条件应用程序特定标准,关闭流式“副本”并打开源文档(在共享驱动器上找到,我们可以假设用户有权访问):
Documents.Open origDoc
Documents(ActiveDocument.FullName).Close SaveChanges:=wdDoNotSaveChanges
Documents(origDoc).Activate
With ActiveDocument
''# Do work
End With
我的想法是我需要调用 Activate
以确保原始文档是 ActiveDocument
,但我在 .Activate
调用中收到 4160“错误文件名”错误。 如果我注释掉对 .Activate
的调用,则似乎 ActiveDocument
设置为 origDoc 文档,即使已经打开了其他文档(我不太确定如何管理文档集合,以及如果您以编程方式关闭当前 ActiveDocument,Word 如何确定下一个 ActiveDocument
是什么)
因此,在文档上调用 .Open
是否会显式设置文档是ActiveDocument
吗? 另外,在已经处于活动状态的文档上调用 .Activate
是否会导致错误?
我还没有找到太多关于此的文档,所以提前感谢您的任何建议和见解!
I'm hoping a VB/VBA expert can help me out. Consider the following:
The user opens a document in Word 2003, and within the Normal.dot AutoOpen
macro, we look at current document, and if it has been opened by clicking on a link on a webpage, and meets certain other application specific criteria, close the streamed 'copy' and open the source document (found on a shared drive we can assume the user has access to):
Documents.Open origDoc
Documents(ActiveDocument.FullName).Close SaveChanges:=wdDoNotSaveChanges
Documents(origDoc).Activate
With ActiveDocument
''# Do work
End With
My thought was that I needed to call Activate
to ensure that the original document was the ActiveDocument
, but I'm getting a 4160 'Bad file name' error on the .Activate
call. If I comment out the call to .Activate
, it appears that ActiveDocument
is set to the origDoc document, even if there were other documents already opened (I'm not really sure how the Documents Collection is managed, and how Word determines what next ActiveDocument
would be if you programatically close the current ActiveDocument)
So, does calling .Open
on a document explicitly set the Document to be the ActiveDocument
? Also, does calling .Activate
on the already active document cause an error?
I haven't really been able to find much documentation about this, so thanks in advance for any suggestions and insight!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
简单的答案是肯定的。 通过使用代码打开文档,使其成为活动文档,然后在下一行中关闭该文档并尝试在下一行中激活该文档,但此操作会失败,因为该文档不再打开。 一般来说,VBA 似乎是这样工作的。
小心使用 ActiveDocument 很重要,因为在代码或其他地方,哪些操作会使文档变得“活跃”并不总是不言自明的(我没有证据,但即使是自动保存也可能做到这一点)。 如果有任何疑问,您最好通过 Documents 集合引用文档,尽管如果文档不再打开,这也可能会导致错误,并且您可能必须通过迭代集合来确保文档是,事实上,开放。 我在使用 Excel VBA 时经常遇到这种情况,而 Word VBA 在这方面的功能似乎相同。
此外,VBA 在释放应用程序对象方面也不稳定。 如果你不小心,你最终会得到多个 WINWORD 进程,可以在任务管理器中查看,无论你是否在代码中关闭或退出它们。 我发现解决这个问题的代码相当于模拟在任务管理器中选择 END PROCESS 的过程。 它有效,但应该有更好的解决方案。
The simple answer is yes. By opening the document with your code you make it the active document, which you then close in the next line and try to activate in the next, and this fails because the document is no longer open. VBA in general seems to work this way.
It is important to be careful with ActiveDocument, because it's not always self-evident what actions, in code or elsewhere, will make a document 'active' (i have no proof but even an autosave might do it). IF there's any doubt you're better off referring to a document through the Documents collection, though this can also cause errors if the document is no longer open, and you might have to resort to iterating through the collection to be sure the document is, in fact, open. I run into this a lot with excel VBA, and Word VBA seems to function identically in that regard.
Also, VBA is flaky about releasing application objects. If you're not careful you'll end up with multiple WINWORD processes,viewable in task manager, regardless of whether you Close or Quit them in your code. The code I've found to work around this amounts to simulating the process of selecting END PROCESS in task manager. It works, but there should be a better solution.
请注意,可能会遇到多种问题:
如果您想在关闭文档后重新打开文档
一次...Word/Windows 不
“释放”文件名,您会收到“文件忙”消息,或有关“正在创建”的消息
临时副本'。
为了解决这个问题,我不得不开发一个复杂的系统来创建/保存和
整理我在 Word 应用程序中打开/操作的任何其他文档的多个版本
由于 Office
Open
/Close
/Save
方法中存在此设计缺陷。使用设置为
False
的ReadOnlyRecommended
属性.Open
方法引用文档对象(上面名为 doc)可能会导致
如果您不保证会出现严重错误
在您尝试操作 doc 对象之前,该对象仍然存在。 永远记住,那
Word 是一个“开放”的应用程序平台......并且用户可以做一些你没有预料到的事情
上...在最后一毫秒左右。 此建议适用于您可能的任何其他物体或财产
希望在 Word 中进行操作。
如果您操作文档集合(或任何其他集合)而无需
确保文件或其他物体仍然存在并且
在您可以删除或移动集合之前有效
出现“堆栈溢出”错误。 特别是如果你尝试并且
关闭/删除从
.item(1)
开始的集合中的对象。 你必须从最后一个集合中删除项目,并记住
每当你改变集合的idicis和指针
.add/.remove/.close 项目。
Beware that there are a variety of problems that can be encountered:
if you want to re-open the document after closing it
once....Word/Windows DOES NOT
'release' the filename and you get a 'file busy' message, or message about 'creating
a temporary copy'.
to deal with this problem, I've had to develop an elaborate system of creating/saving and
tidying up multiple versions of any other documents I open/manipulate in my Word applications
because of this design flaw in Office
Open
/Close
/Save
methods.Use the
ReadOnlyRecommended
property set toFalse
with the.Open
methodreferring to the document object (named doc, above) can cause
serious errors if you do not assure
that the
doc
object still exists before you try and manipulate it. Remember always, thatWord is an 'open' application platform....and the user can be doing things you didn't count
on...in the last millisecond or so. This advice holds for any other object or property you may
wish to manipulate in Word.
if you manipulate the Documents collection (or any other) without
assuring that the document or other object is still there and
valid before deleting or moving it within the collection you may
get 'stack overflow' errors. Particularly if you try and
close/delete objects in a collection starting at
.item(1)
. Youmust delete items in a collection from the last one, and remember
that the collection idicies and pointers change whenever you
.add/.remove/.close items from them.
这里有一个错误:
应该是文档s。
是的,您可以激活活动文档。 然后什么也没有发生。
是的,打开的文档变为活动状态。
如果您不确定,请使用
Documents.Open(origDoc).Activate
。You have an error here:
Should be Documents.
Yes, you can activate the active document. Nothing happens then.
Yes, opened document becomes active.
If you are not sure, use
Documents.Open(origDoc).Activate
.除非绝对必要,否则您不应该首先使用
ActiveDocument
对象,因为它非常不可靠。 首选方法是这样的:You shouldn't be using the
ActiveDocument
object in the first place unless absolutely necessary because it's very unreliable. The preferred approach would be this: