VBA FileCopy внутри al oop завершается неудачно после одной успешной копии; Проблема: Как закрыть файлы перед следующим использованием? - PullRequest
0 голосов
/ 01 февраля 2020

............................................ .................................................. .................................................. .................. Последние новости ... PPS Я только что прочитал, что FileSystem.FileCopy лучше , чем просто FileCopy. Вот что я собираюсь попробовать. Но я действительно хотел бы знать, как использовать FileCopy внутри al oop, что означает «Как закрыть файлы, используемые в FileCopy Для общей картины ясно, читайте дальше. ............................................... .................................................. .................................................. ...............

(с использованием Windows 10 Pro, Word 365 Pro)

Онлайн Справка для FileCopy Src, Dest говорит, что она ... Копирует файл из Src в Dest [но] не работает с открытым в данный момент файлом. Оба ... файла должны быть закрыты с помощью оператора Close.

Но онлайн-справка для Close по ссылке, предоставленной на , эта страница подключается к help для Close для оператора Open , который говорит, что он "закрывает файл (ы), ранее открытый с помощью оператора" Open, а не оператора FileCopy.

Так что я ' Я озадачен тем, что делать с этим кодом, который скопирует модуль кода первый в документе в резервное хранилище, но не второй .

Рис. 1: Информация о том, что предположительно будет скопировано

enter image description here

Рис. 2: Исходное сообщение об ошибке без On Error

enter image description here

(Понятия не имею, почему все эти пустые строки. Они НЕ в моем теле.)

Пожалуйста, пока игнорируйте все OnError .

Когда второй кодовый модуль должен был быть скопирован, выполнение остановлено с ошибкой "Файл не найден ».

Sub BackupModules()
    Dim prj As VBProject
    Dim comp As VBComponent
    Dim code As CodeModule
    Set prj = ThisDocument.VBProject
    Dim k As Integer, n As Integer
    Dim Destination As String, Prefix As String
    Prefix = "junk"
    k = 0: n = 0
On Error GoTo x
    For Each comp In prj.VBComponents
On Error GoTo x
        k = k + 1
        If comp.Type = vbext_ct_StdModule Then
          n = n + 1
          Destination = Prefix & n
          MsgBox "Copying Standard module " & n & " of " & k & " components encountered: <" & comp.Name & "> to " _
                 & Destination & "; # lines: " & comp.CodeModule.CountOfLines
On Error GoTo x
          FileCopy comp.Name, Destination
          MsgBox "Success"
          Close
        Else

x: If Err.Number <> 0 Then: _
msg = "Error # " & Str(Err.Number) & " was generated by " _
& Err.Source & Chr(13) & Err.Description: _
MsgBox msg, , "Error", Err.HelpFile, Err.HelpContext: On Error GoTo 0: Close:

       End If
    Next

End Sub

Затем я начал экспериментировать (ЛОТ, как вы можете видеть) с On Error Goto x, размещенным в разных местах (по одному, а затем все, как показано) и противно выглядящим, но синтаксически и логически правильная строка, которая начинается x: If Err..., помещенная в блок Else.

Рис. 3: Сообщение об ошибке после использования On Error

enter image description here

(FWIW, я только что заметил Normal в Err.Source часть сообщения об ошибке выше. Интерактивная справка гласит: «Когда в вашем коде возникает непредвиденная ошибка, свойство Source автоматически заполняется. Для ошибок в стандартном модуле Source содержит имя проекта . Для ошибок в модуле класса Source содержит имя с формой project.class. «Действительно, код находится в модуле в обычном проекте.)

Рис. 4: Строка, вызывающая ошибку, On Error НЕ перехватил enter image description here

Итак что не так ? Я перепробовал все, что мог придумать. Единственная помощь, которую я смог найти для Close, НЕ упоминала о ее использовании с FileCopy. Мои Close использования не вызвали ошибок, но Close закрыл как исходный, так и целевой файл? Конечно, нет. Первое использование FileCopy сработало, файлы (вероятно) не закрылись, поэтому второе использование FileCopy не удалось. Документы говорят, что использование FileCopy в открытом файле вызовет ошибку.

On Error Goto x или 0 ни здесь, ни там. Вот почему я сказал, чтобы сначала игнорировать их.

Вопрос, по-видимому, " Как мне закрыть оба файла , упомянутые в FileCopy?"

PS За одно сообщение об открытии я НЕ собираюсь этого делать. Полагаю, я мог бы использовать Open ... For Input As File#1 и указать имя модуля, если он легко доступен для кода, а также Open ... For Output As File#2 для пункта назначения, использовать For l oop скопировать количество строк, если доступно, а затем Close обе. Но я надеюсь, что смогу найти решение своей проблемы, прежде чем попробую это, поскольку SURELY FileCopy должен работать в пределах al oop (а не из-за неправильного закрытия).

1 Ответ

0 голосов
/ 02 февраля 2020

Благодаря @TimWilliams, который сообщил мне Export, моя последняя процедура "Резервное копирование всех модулей" довольно проста.

Sub BackupModules()
    Dim comp As VBComponent
    Dim prj As VBProject:     Set prj = ThisDocument.VBProject
    Dim fso As Object:        Set fso = CreateObject("Scripting.FileSystemObject")
    Dim destPrefix As String: destPrefix = "C:\Users\Dov\Google Drive\Word\Modules\"
    Dim destFilePath As String

    For Each comp In prj.VBComponents
        If comp.Type = vbext_ct_StdModule Then
            destFilePath = destPrefix & comp.Name & " " & Year(Now) & " " & Month(Now) & " " & Day(Now)
            Debug.Print "Copying Standard module <" & comp.Name & "> to <" & destFilePath & ">"
            comp.Export (destFilePath)
        Else
            Debug.Print "Skipping component # " & k & ", <" & comp.Name & ">, type " & comp.Type
       End If
    Next
End Sub
...