Excel VBA для открытия нескольких файлов Word в цикле - PullRequest
0 голосов
/ 06 мая 2009

Я заранее прошу прощения за вопрос новичка - большая часть моего опыта 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

Я заметил, что код работает нормально, если я закрываю приложение и устанавливаю объект = ничего в цикле. Но так оно и есть, он взрывает второй файл в папке в строке «objWordApp.documents.Open strFilePath & strCurFileName».

Можно ли открывать и закрывать документы Word в цикле, не создавая объект снова и снова? Это очень медленно, когда я так делаю.


Спасибо за помощь - мне нравится ваш путь намного лучше. К сожалению, я получаю тот же результат. Программа умирает во второй раз через цикл в строке, которая гласит:

Set objWordDoc = objWordApp.Documents.Open(objFile.Path)

Я получаю ошибку:

Ошибка времени выполнения -2147417851 (80010105) Ошибка автоматизации Сервер выдал исключение.

Я попробовал ваш код на обычных документах (не на тех, которые я обрабатываю), и он работал нормально. Документы, которые я использую, имеют поля формы и макросы - не уверен, что это имеет значение. Я установил макрос безопасности в 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

Я не уверен, почему это работает и почему это не сработает. Если мне придется пойти по этому пути, я смогу - это кажется очень медленным и неэффективным. Это плохая идея?

1 Ответ

1 голос
/ 07 мая 2009

Я изменил 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 <> 0, то ...).

Опять же, что-то должно быть особенным в ваших документах (макросы, защита и т. Д.), Потому что этот код работает на тестовых примерах, которые я пробовал. Пробовали ли вы вручную открывать документы в Word в том же порядке, что и скрипт, обновляя информацию, аналогичную сценарию процесса, а затем закрывая документы, чтобы проверить, что Word делает что-то странное?

Закрытие Word. Приложение ничего не повредит, но, очевидно, будет значительно медленнее.

...