Have you ever needed to make a copy of a file? Well, there are a number of ways that you can do it.
Built-in VBA FileCopy
I find that using the built-in FileCopy function to be the simplest and cleaness method. Below is a simple procedure around it that trap certain common errors.
'---------------------------------------------------------------------------------------
' Procedure : CopyFile
' Author : Daniel Pineault, CARDA Consultants Inc.
' Website : http://www.cardaconsultants.com
' Purpose : Copy a file
' Overwrites existing copy without prompting
' Cannot copy locked files (currently in use)
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
' (CC BY-SA 4.0) - https://creativecommons.org/licenses/by-sa/4.0/
' Req'd Refs: None required
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sSource - Path/Name of the file to be copied
' sDest - Path/Name for copying the file to
'
' Revision History:
' Rev Date(yyyy/mm/dd) Description
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
' 1 2007-Apr-01 Initial Release
'---------------------------------------------------------------------------------------
Public Function CopyFile(sSource As String, sDest As String) As Boolean
On Error GoTo CopyFile_Error
FileCopy sSource, sDest
CopyFile = True
Exit Function
CopyFile_Error:
If Err.Number = 0 Then
ElseIf Err.Number = 70 Then
MsgBox "The file is currently in use and therfore is locked and cannot be copied at this" & _
" time. Please ensure that no one is using the file and try again.", vbOKOnly, _
"File Currently in Use"
ElseIf Err.Number = 53 Then
MsgBox "The Source File '" & sSource & "' could not be found. Please validate the" & _
" location and name of the specifed Source File and try again", vbOKOnly, _
"File Currently in Use"
Else
MsgBox "MS Access has generated the following error" & vbCrLf & vbCrLf & "Error Number: " & _
Err.Number & vbCrLf & "Error Source: CopyFile" & vbCrLf & _
"Error Description: " & Err.Description, vbCritical, "An Error has Occurred!"
End If
Exit Function
End Function
All you have to do is copy it into a module and then call it as required. Enjoy!
Copying a File Using FSO
As an alternative, here is an example to copy a file using FSO.
'---------------------------------------------------------------------------------------
' Procedure : FSO_FileCopy
' Author : Daniel Pineault, CARDA Consultants Inc.
' Website : http://www.cardaconsultants.com
' Purpose : Copy a file
' Overwrites existing copy without prompting (you can change the varible
' in the CopyFile method call)
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
' (CC BY-SA 4.0) - https://creativecommons.org/licenses/by-sa/4.0/
' Req'd Refs: Uses Late Binding, so none required
' Ref : FSO - https://msdn.microsoft.com/en-us/library/ms127964(v=vs.110).aspx
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sSource - Path/Name of the file to be copied
' sDest - Path/Name for copying the file to
'
' Usage:
' ~~~~~~
' FSO_FileCopy("C:\TE.MP\Tab.le1.txt", "C:\TE.MP\Tab.le3.txt")
'
' Revision History:
' Rev Date(yyyy/mm/dd) Description
' **************************************************************************************
' 1 2018-06-16 Initial Release - Blog Help
'---------------------------------------------------------------------------------------
Public Function FSO_FileCopy(ByVal sSource As String, _
ByVal sDest As String) As Boolean
On Error GoTo Error_Handler
Dim oFSO As Object
Set oFSO = CreateObject("Scripting.FileSystemObject")
Call oFSO.CopyFile(sSource, sDest, True)
FSO_FileCopy = True
Error_Handler_Exit:
On Error Resume Next
If Not oFSO Is Nothing Then Set oFSO = Nothing
Exit Function
Error_Handler:
MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & _
"Error Source: FSO_FileCopy" & vbCrLf & _
"Error Description: " & Err.Description & _
Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
, vbOKOnly + vbCritical, "An Error has Occurred!"
Resume Error_Handler_Exit
End Function
I found this error:
403 – Forbidden: Access is denied.
You do not have permission to view this directory or page using the credentials that you supplied.
This looks like a website error and not a VBA error?!
It is very hard to help you when you do not supply any information on how you were using the code (supply your code in which you have integrated using this function), give me a context (what type of files are you trying to copy, where are they located, etc…)
One way or another, the message is very clear. Either you made a typo entering your login username/password or you simply do not have the necessary rights to access the folder/files. Try again, and if the problem persists, then contact your Network administrator for assistance.
Really handy, thanks.
Good job bro!
Will this overwrite the destination file if it already exists?
Yes, it will silently overwrite the file if it already exists.
Thank you this is just what I needed.
Glad you can put the code to good use!
I found this today. It worked perfectly and saved me a couple hours of troubleshooting.
Thanks
Glad it helped.
just found this link is there a way to automatically not copy or over right a file is already exist, I just want to add new files with out overwriting the ones that are already there?
Why not use it in conjunction with the FileExist function
Test to see if the file already exists and only perform the copy if it is not found.
thx, it helped
What would you recommend for folders that have a period in them?
We have clients that create folders with periods. When I try to use the FileCopy or your CopyFile it errors out. Are there any workarounds for this situation?
The built-in CopyFile, or my procedure seem to work fine with paths or filenames that include periods?! Can you give me a concrete example of a fully qualified path/filename that I could test with?
I’ve also updated the example to also now include an FSO example, you might want to try with it instead and see if there is any difference in behavior.
You are correct…I see my problem now.
Thank you very much for replying so fast.
Love your blog…it’s great for the Access community!
Is there a way to copy files that have been encrypted in MS Access? I’m using the fso method and it works great unless the .accdb file is encrypted.
FSO doesn’t care about the files you are trying to copy, encrypted or not. FSO doesn’t know if the accdb it is copying is encrypted, it’s a file, that all it knows. So there is something else going on here.
If the destination file allready exists, how can i ad an incrementing number? (even with multiple existing files e.g.(2), (3) etc….
Thanks a lot!!!!!, thanks a lot!!!
Thanks for sharing
Any way to auto rename the destination file
e.g. from desert.jpg to desert1.jpg
You could do something like:
Public Function CopyFile(ByVal sSrcFile As String, ByVal sDestPath As String) As Boolean ' Copies a file and retain original file attributes (created, modified, ...) On Error GoTo CopyFile_Error ' Dim sSrcFilePath As String Dim sSrcFileName As String Dim sSrcFileExt As String Dim sDestFile As String ' Probably a good idea to perform a FielExist check here first before continuing. ' Break the Source file down into its componenets ' sSrcFilePath = left(sSrcFile, InStrRev(sSrcFile, "\")) sSrcFileName = right(sSrcFile, Len(sSrcFile) - InStrRev(sSrcFile, "\")) sSrcFileName = left(sSrcFileName, InStrRev(sSrcFileName, ".") - 1) sSrcFileExt = right(sSrcFile, Len(sSrcFile) - InStrRev(sSrcFile, ".")) ' Define the Destination file If right(sDestPath, 1) <> "\" Then sDestPath = sDestPath & "\" sDestFile = sDestPath & sSrcFileName & "1" & "." & sSrcFileExt ' Perform the actual file copy FileCopy sSrcFile, sDestFile CopyFile = True Exit Function CopyFile_Error: If Err.Number = 0 Then ElseIf Err.Number = 70 Then MsgBox "The file is currently in use and therfore is locked and cannot be copied at this" & _ " time. Please ensure that no one is using the file and try again.", vbOKOnly, _ "File Currently in Use" ElseIf Err.Number = 53 Then MsgBox "The Source File '" & sSrcFile & "' could not be found. Please validate the" & _ " location and name of the specifed Source File and try again", vbOKOnly, _ "File Currently in Use" Else MsgBox "MS Access has generated the following error" & vbCrLf & vbCrLf & "Error Number: " & _ Err.Number & vbCrLf & "Error Source: CopyFile" & vbCrLf & _ "Error Description: " & Err.Description, vbCritical, "An Error has Occurred!" End If Exit Function End Functionand you’d call it by simply doing
Call CopyFile("C:\Images\desert.jpg", "C:\Users\Dev\Desktop\")Couldn’t get this right
but did manage to auto name the destination file using this code;
Private Sub Command3_Click()
Dim f As Object
Dim strfile As String
Dim varItem As Variant
Set f = Application.FileDialog(3)
f.allowMultiSelect = True
If f.show Then
For Each varItem In f.selectedItems
strfile = Dir(varItem)
strfolder = Left(varItem, Len(varItem) – Len(strfile))
MsgBox “Folder” & strfolder & vbCrLf & “File: ” & strfile
Me.Image_Path = strfolder + strfile
Me.Image_Path1 = strfolder + “Cropped_” + strfile
Me.Image_Path1.Requery
DoCmd.Save
Next
End If
Set f = Nothing
CopyFile Me.Image_Path, Me.Image_Path1
End Sub
Then i managed to crop the destination file using your crop image code without over writing the original file.
Anyways Thanks for the continued support