我提前为新手问题道歉 - 我的大多数VBA体验都是在Excel或Word到Excel中。在这种情况下,我将从Excel转到Word。我试图从一些Word表单中捕获一些数据并将其存储在Excel文件中。
现在,我的代码适用于该文件夹中的第一个文档,但在此之后,它出现了自动化错误“服务器引发了异常”(goo!)
这是我的代码:
Dim objWordApp As Object
strCurFileName = Dir(strFilePath)
Set objWordApp = CreateObject("word.application")
objWordApp.Visible = True
Do While strCurFileName <> ""
objWordApp.documents.Open strFilePath & strCurFileName
objWordApp.activedocument.Unprotect password:="testcode"
{EXCEL PROCESSING HERE}
strCurFileName = Dir
objWordApp.activedocument.Close 0
Loop
objWordApp.Quit
Set objWordApp = Nothing
我注意到如果我退出应用程序并在循环中设置object = nothing,代码就可以正常工作。但就现在的方式而言,它在“objWordApp.documents.Open strFilePath&amp; strCurFileName”行的文件夹中的第二个文件上进行了轰炸。
我可以在循环中打开和关闭Word文档而无需反复创建对象吗?当我这样做时,它真的很慢。
感谢您的帮助 - 我更喜欢您的方式。不幸的是,我得到了相同的结果。程序第二次通过循环读取:
Set objWordDoc = objWordApp.Documents.Open(objFile.Path)
我得到的错误是:
运行时错误-2147417851(80010105) 自动化错误 服务器抛出异常。
我在常规word文档(不是我正在处理的文档)上尝试了你的代码,它运行正常。我正在运行的文档有表单字段和宏 - 不确定这是否有所不同。我已将Word中的宏安全性设置为“低”和“非常高”,以确保其他宏不会干扰。
我无法弄明白为什么它适用于第一个文档然后不适用于下一个文档。我甚至克隆了第一份文件,但没有任何区别。
Set objFolder = FSO.GetFolder(strFilePath)
For Each objFile In objFolder.Files
Set objWordApp = CreateObject("word.application")
objWordApp.Visible = True
If Right(objFile.Name, 4) = ".doc" Then
Set objWordDoc = objWordApp.documents.Open(Filename:=objFile.Path, ConfirmConversions:=False, _
ReadOnly:=True, AddToRecentFiles:=False, PasswordDocument:="", _
PasswordTemplate:="", Revert:=False, WritePasswordDocument:="", _
WritePasswordTemplate:="", Format:=wdOpenFormatAuto)
[Process DOC]
objWordDoc.Close 0, 1
End If
Set objWordDoc = Nothing
objWordApp.Quit
Set objWordApp = Nothing
Next
我不确定为什么会起作用以及为什么它不起作用。如果我必须走这条路,我可以 - 它看起来真的很慢而且效率低下。这是个坏主意吗?
答案 0 :(得分:1)
我将Dir更改为FileSystemObject(转到Tools \ References并添加Microsoft Scripting Runtime),我能够成功打开多个文件。如果遇到问题,请描述您在调试器中看到的错误。此外,如果你需要递归到子目录,你需要重构它。
Private mobjWordApp As Word.Application
Sub Test()
ProcessDirectory "PathName"
End Sub
Property Get WordApp() As Word.Application
If mobjWordApp Is Nothing Then
Set mobjWordApp = CreateObject("Word.Application")
mobjWordApp.Visible = True
End If
Set WordApp = mobjWordApp
End Property
Sub CloseWordApp()
If Not (mobjWordApp Is Nothing) Then
On Error Resume Next
mobjWordApp.Quit
Set mobjWordApp = Nothing
End If
End Sub
Function GetWordDocument(FileName As String) As Word.Document
On Error Resume Next
Set GetWordDocument = WordApp.Documents.Open(FileName)
If Err.Number = &H80010105 Then
CloseWordApp
On Error GoTo 0
Set GetWordDocument = WordApp.Documents.Open(FileName)
End If
End Function
Sub ProcessDirectory(PathName As String)
Dim fso As New FileSystemObject
Dim objFile As File
Dim objFolder As Folder
Dim objWordDoc As Object
On Error Goto Err_Handler
Set objFolder = fso.GetFolder(PathName)
For Each objFile In objFolder.Files
If StrComp(Right(objFile.Name, 4), ".doc", vbTextCompare) = 0 Then
Set objWordDoc = GetWordDocument(objFile.Path)
' objWordDoc.Unprotect Password:="testcode" ' Need to check if it has Password?
ProcessDocument objWordDoc
objWordDoc.Close 0, 1
Set objWordDoc = Nothing
End If
Next
Exit_Handler:
CloseWordApp
Exit Sub
Err_Handler:
MsgBox "Error " & Err.Number & ": " & Err.Description
Resume Exit_Handler
'Resume Next ' or as above
End Sub
Sub ProcessDocument(objWordDoc As Document)
'{EXCEL PROCESSING HERE}'
End Sub
编辑:我添加了一些错误处理和一些重构,尽管可以完成更多的重构。
您正在打开的文件必须有一些特别之处。您可以尝试使用不同的参数来打开文档,例如:
Set objWordDoc = objWordApp.Documents.Open( _
FileName:=objFile.Path, ReadOnly:=True)
您可能需要添加Microsoft Word作为参考,如果您这样做,则开始使用Word常量(wdDoNotSaveChanges等)。查看Documents.Open上的帮助并测试不同的参数。
此外,在调试期间使用上下文菜单中的“设置下一个语句”,也可以跳过第一个文档并直接打开第二个文档,看看是否存在问题。
编辑:如果您收到所描述的自动化错误,我已将代码更改为关闭并重新打开Word。您可能需要调整错误编号,或者只是在任何错误上关闭Word(如果Err.Number&lt;&gt; 0那么......)。
同样,对于您的文档(宏,保护等)必须有一些特殊之处,因为此代码适用于我尝试过的测试用例。您是否尝试按照与脚本相同的顺序手动打开Word中的文档,更新类似于您的流程脚本的信息,然后关闭文档以查看Word是否有什么奇怪之处?
关闭Word.Application不会伤害任何东西,但显然会明显变慢。