简体   繁体   中英

VBA FileCopy inside a loop fails after one successful copy; Problem: How to Close files before next use?

.................................................................................................................................................................. Late-breaking news... PPS I just read that FileSystem.FileCopy is better than just FileCopy . That's what I'm going to try. But I really would like to know how to use FileCopy inside a loop , meaning, "How do I close files used in FileCopy ?" For the big picture made clear, read on. ..................................................................................................................................................................

(Using Windows 10 Pro, Word 365 Pro)

The online Help for FileCopy Src, Dest says that it ... Copies a file from Src to Dest [but] does not work on a currently open file. Both ... files must be closed [by] the Close statement.

But the online help for Close , from link supplied on that page connects to help for Close for the Open statement , which says that it "Closes the file(s) previously opened with the" Open statement, not the FileCopy statement.

So it is that I'm stumped on what to do with this code, which will copy the first code module in the Document to a backup location, but not the second .

Pic#1: Info about what's supposedly going to be copied

在此处输入图片说明

Pic#2: Original error message without On Error

在此处输入图片说明

(I have no clue why all these blank lines. They're NOT in my Body.)

Please ignore all the OnError stuff for now .

When the second code module should have been copied, execution halted with error "File not found".

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

Then I began experimenting (a LOT as you can see) with On Error Goto x being placed at various places (one at a time and then all, as shown) and the nasty-looking but syntactically and logically correct line that starts x: If Err... placed inside the Else block.

Pic#3: Error msg after using On Error

在此处输入图片说明

(FWIW, I just spotted Normal in the Err.Source part of the error message above. Online help says, "When an unexpected error occurs in your code, the Source property is automatically filled in. For errors in a standard module, Source contains the project name . For errors in a class module, Source contains a name with the project.class form." Indeed, the code is in a Module within the Normal Project.)

Pic#4: Line causing error that On Error did NOT trap 在此处输入图片说明

So what's wrong ? I've tried everything I can think of. The only help I could find for Close did NOT mention its use with FileCopy . My Close usages caused no error but did Close close both the source and the destination file? Surely not. First use of FileCopy worked, files (probably) not closed, thus second use of FileCopy failed. Docs say using FileCopy on an open file will cause error.

On Error Goto x or to 0 is neither here nor there. That's why I said to ignore them at first.

The question is apparently " How do I close both files mentioned in FileCopy ?"

PS Per opening blurb, I'm NOT gonna do this. I suppose I could use Open ... For Input As File#1 and specify the Module's name, if it's readily available to code, and also Open ... For Output As File#2 for the destination, use a For loop to copy the number of lines, if available, and then Close both. But I hope I get a solution to my problem before I try that since SURELY FileCopy should work within a loop (and doesn't because of improper close).

Thanks to @TimWilliams, who tipped me off to Export , my final "Backup all modules" routine is quite simple.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM