Issue with MoveFile method to overwrite file in Destination in vbscript?
Asked Answered
R

3

18

I have a vbscript that I have written to move files from a source directory to a destination directory. The way the script works at the moment is that I have a mapping file which is read in (maps id's to folder type). Each file being moved begins with the id and the destination will be based on what the id is mapped to. I read in the mapping file and build up the destination path for each file being moved. This all works as expected, the problem is when I try to move a file that already exists in the destination directory, the files are not moved from the source directory. Essentially I would like it to overwrite a file in the destination directory if it already exists. At the moment, my main command is this:

fso.MoveFile ObjFile.Path, archiveTo & "\" & yearValue & "\" & monthValue & "\" & ObjFile.Name

Is there a way to default this to always overwrite a file in the destionation directory if it already exists?

Recollected answered 12/6, 2013 at 12:11 Comment(0)
H
36

Unfortunately, the VBScript MoveFile method works only when the target file does not exist. It can't overwrite such file when exists, just throw error.

So the only option is to use CopyFile (which does have option to overwrite) then DeleteFile:

fso.CopyFile ObjFile.Path, archiveTo & "\" & yearValue & "\" & monthValue & "\" & ObjFile.Name, True
fso.DeleteFile ObjFile.Path
Homorganic answered 12/6, 2013 at 12:39 Comment(4)
That's great - thanks for the info. I knew I could do this - I just didn't know if there was a more efficient way I could do it with the Move command.Recollected
@Recollected nope, that specific method was never intended for such use. :)Homorganic
It does seem odd that the copy method will has the option to overwrite but the move does not.. Anyway, at least I know nowRecollected
@Recollected my guess is that the MoveFile was created for purpose of renaming files; rename target must not exist. And they never bothered to change that logic. :/Homorganic
H
5

Like mentioned before, MoveFile cannot overwrite existing File. But you can create your own Function:

Function MoveFile(source, target)
  Dim fso
  Set fso = CreateObject("Scripting.FileSystemObject")

  fso.CopyFile source, target, True
  fso.DeleteFile source
End Function

And then call it like:

MoveFile ObjFile.Path, archiveTo & "\" & yearValue & "\" & monthValue & "\" & ObjFile.Name
Hertzog answered 1/10, 2018 at 13:26 Comment(0)
D
2

Examples above look good, but there is a risk that the source and destination paths may be the same. Then the file overrides itself, and nothing seems to be actually copied. So if you delete the source file after that, then the file can be lost! So what I use is the function below (which I believe is more safe):

Public Function GrMoveFile(ByVal sMoveFrom As String, ByVal sMoveTo As String, Optional ByVal fOverride As Boolean = False) As Variant

' This function allows moving file between different drives or servers with possible overriding
' author: Tomasz Kubiak
' [email protected]
'
' RETURNS:
'   - true (if moving successfull)
'   - error description (otherwise)
' ARGUMENTS:
'   - sMoveFrom - source file path
'   - sMoveTo - destination file path
'   - fOverride - allow for overriding (false by default)

    Dim FSO As New Scripting.FileSystemObject   ' File system object - requires reference to Microsoft Scripting Library (Tools -> References)
    Dim OrigFileAttr As VbFileAttribute         ' Holds attribute of the destination file

On Error GoTo EH

    ' if overriding is allowed:
    If fOverride Then

        ' It's necessary to prevent the destination file from deleting,
        ' in case of the source path and destination path points to the same file
        ' (it's possible e.g. when the network location is mapped as a drive).
        ' So the solution is to lock the file by setting fileattribute to ReadOnly

        ' Before locking file let's remember the original state of the destination file
        OrigFileAttr = GetAttr(sMoveFrom)

        ' Unlock file before copy
        SetAttr sMoveFrom, vbNormal

        ' Original FSO MoveFile method does not allow overriding, so we copy the file at first
        FSO.CopyFile source:=sMoveFrom, destination:=sMoveTo, overwritefiles:=True

        ' Set destination file attribute to read-only to prevent deletion
        SetAttr sMoveTo, vbReadOnly

On Error Resume Next
        ' Theoretically the condition below should not be required, because FSO.delete method with
        ' attribut "force" set to false shouldn't allow for deleting "Read-only files".
        ' But in practice, when you have a file located on the server location, it appeared to not
        ' work properly and delete also RO-files, so i've introduced that condition
        If GetAttr(sMoveFrom) <> vbReadOnly Then
            ' Try to delete source file
            FSO.DeleteFile sMoveFrom, False
        End If

        'restore previous file attribute
        SetAttr sMoveTo, OrigFileAttr
On Error GoTo EH

    ' if overriding is NOT allowed:
    Else
        'move using regular move method (does not allow override)
        FSO.MoveFile source:=sMoveFrom, destination:=sMoveTo
    End If

    'pReleaseFolder

    ' Moving succesfull, let function return true
    GrMoveFile = True
    Exit Function

'Error handler
EH:
    'pReleaseFolder

    ' An error occured, return error description
    GrMoveFile = Err.Description
End Function

Dilorenzo answered 25/10, 2019 at 12:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.