VBS MoveFile Issue - file-io

I did write the 1st if statement and it worked well in start while my file sizes were just in kbs.
as my file sizes got to mbs it started giving me problems like it was not renaming the file to .CSV again from .CSV.tmp hence I decided to add File Size before and after(2nd IF statement) , But it started to show me 2 debug msgBox "Entry in B Request with File : " and then "fname". after that it fails and don't give and error but don't do the job too.
do you find any issues with it?
Option Explicit
Dim FSO, FLD, FIL, GetFileSize1, GetFileSize2, f, fname
Dim strFolder,strFileName
strFolder = "\Sieb\Request"
Set FSO = CreateObject("Scripting.FileSystemObject")
set FLD = FSO.GetFolder(strFolder)
For Each Fil In FLD.Files
strFileName=Lcase(Fil.Name)
If instr (1,strFileName,"_a_request_")>0 then
if (FSO.FileExists(".\Sieb_Process_Files\a\Request\"+Fil.Name)) then
else
FSO.MoveFile ".\Request\"+Fil.Name,".\Sieb_Process_Files\a\Request\" + Fil.Name +".tmp"
FSO.MoveFile ".\Sieb_Process_Files\a\Request\" + Fil.Name +".tmp", ".\Sieb_Process_Files\a\Request\" + Fil.Name
end if
End if
If instr (1,strFileName,"_b_request_")>0 then
if (FSO.FileExists(".\Sieb_Process_Files\b\Request\"+Fil.Name)) then
else
MsgBox "Entry in B Request with File : " + Fil.Name
set fname = ".\Sieb_Process_Files\b\Request\" + Fil.Name
MsgBox fname
set f = FSO.GetFile(fname)
GetFileSize1 = f.size
MsgBox "Orignal File Size" + GetFileSize1
FSO.MoveFile ".\Request\"+Fil.Name,".\Sieb_Process_Files\b\Request\" + Fil.Name +".tmp"
set f = FSO.GetFile(".\Sieb_Process_Files\b\Request\" + Fil.Name +".tmp")
GetFileSize2 = f.size
MsgBox "Copied File Size" + GetFileSize2
MsgBox "File Moved with tmp name"
Do Until GetFileSize1=GetFileSize2
FSO.MoveFile ".\Sieb_Process_Files\b\Request\" + Fil.Name +".tmp" ,".\Sieb_Process_Files\b\Request\" + Fil.Name
MsgBox "File renamed to orignal name exiting now"
Exit Do
Loop
end if
End if
Next
Set Fil = nothing
set FSO = nothing

It's clearly not possible that your first If conditional ever successfully moved a file that didn't exist in the destination (and file size doesn't have anything to do with it).
if (FSO.FileExists(".\Sieb_Process_Files\a\Request\"+Fil.Name)) then
else
FSO.MoveFile ".\Request\"+Fil.Name,".\Sieb_Process_Files\a\Request\" + Fil.Name +".tmp"
FSO.MoveFile ".\Sieb_Process_Files\a\Request\" + Fil.Name +".tmp", ".\Sieb_Process_Files\a\Request\" + Fil.Name
end if
Once you move the file to a different location/name the file your variable Fil refers to doesn't exist anymore, so the second MoveFile (or rather, the attempt to access the property Fil.Name) would raise a "File not Found" error. If you didn't get an error you have an On Error Resume Next in your code that you didn't show.
Also, why are you moving the file to a temp name and then back to the original name in the same directory? That would only make sense when moving the file to a hot folder on a different volume, which doesn't seem to be the case here.
Something like this should be all you need:
Option Explicit
Dim fso, sourceFolder, targetFolder, f, target
sourceFolder = "\Sieb\Request"
targetFolder = ".\Sieb_Process_Files\a\Request"
Set fso = CreateObject("Scripting.FileSystemObject")
For Each f In fso.GetFolder(sourceFolder).Files
target = fso.BuildPath(targetFolder, f.Name)
If InStr(1, f.Name, "_a_request_", vbTextCompare) > 0 Then
If Not fso.FileExists(target) Then
f.Move target
End If
End If
Next
vbTextCompare makes InStr() comparisons case-insensitive, so you don't need to lowercase the filename.

Related

VBA attempting to open file which name contains characters above high-ascii (256)

What I'd like to achieve is opening a file from the previously-stored variable. The problem is the filename sometimes contains characters like ŰŐ. VBA environment changes them to the closest one UO. So I'm unable to open a workbook included with "special" characters. What I have tried so far:
Sub open_last_modified()
Dim fso As New FileSystemObject
Dim files, folder, lmfile As String
Dim lmdate As Date
' a file previously created on desktop ( like őőőűűű.xlsx)
' with a proper filename, both method works very well
folder = ("C:\Users\szidzse\Desktop\")
files = Dir(folder & "*.*", vbNormal)
Do While files <> ""
On Error Resume Next 'if it contains non
If FileDateTime(folder & files) > lmdate Then
lmdate = FileDateTime(folder & files)
lmfile = files 'the last modified file what i'd like to open even if it has non-ascii characters.
End If
files = Dir
Loop
Set a = Workbooks.Open(folder & lmfile, ReadOnly:=True) 'does nothing when filename is not proper.
fso.CopyFile Source:=folder & lmfile, Destination:=folder & "temp.xlsx" 'file not found (I've tried to copy and rename it to a proper name.)
End Sub
I've also tried StrConv(string, vbFromUnicode or vbUnicode) without success.
Any help will be appreciated.
Please, test the next function. It should replace the non ASCII characters with similar ones:
Function replaceNonASCIICh(x As String) As String
Dim i As Long
For i = 1 To Len(x)
If AscW(Mid(x, i, 1)) <> Asc(Mid(x, i, 1)) Then
x = Replace(x, Mid(x, i, 1), Chr(Asc(Mid(x, i, 1))))
End If
Next i
replaceNonASCIICh = x
End Function
I tested it on the two not ASCII characters we could see/copy, in the next way:
Sub testReplaceNonASCII()
Dim x As String, result As String
x = ChrW(368) & ChrW(79) 'the string containing the characters you show us
result = replaceNonASCIICh(x)
ActiveCell.Offset(1).Value = result 'in Immediate Window non ASCII characters cannot be seen as they are...
End Sub
I do not know what other characters should be involved. Please, test it on your cases and send some feedback.
Now, supposing that Dir returns all files from the folder, even if their name contain non ASCII characters, you should firstly iterate between all of them and change their names, using the above function (and Name function). If it looks complicated, but if Dir returns them, I will show you how to proceed...
If you share such a file (supposing it is not confidential) I can try testing the code I posted, only supposing that it should work...
Edited:
I copied the workbook you sent in a folder named "InvalidCharacters", like subfolder of the one running the code. Then, I (manually) changed its name adding a suffix and copy it again (keeping the non ASCII characters). Please, do the same and test the following code:
Sub changeNonASCIIFileName()
Dim FSOLibrary As Object, fldObj As Object, fsoFile As Object
Dim foldPath As String, fileName As String, newName As String
Set FSOLibrary = CreateObject("Scripting.FileSystemObject")
foldPath = ThisWorkbook.path & "\InvalidCharacters\"
Set fldObj = FSOLibrary.GetFolder(foldPath)
For Each fsoFile In fldObj.files
On Error Resume Next 'if no characters to be replaced you cannot rename the file...
fsoFile.Name = replaceNonASCIICh(fsoFile.Name)
On Error GoTo 0
Next
End Sub
It uses the above function. Please, take care to be there!
I would like to receive some feedback after testing it...
#FaneDuru sorry for my late response.
Your code works, for me, it returns uo instead of űő. But gives File not found. when attempting to open. In my special case for opening a file, putting a question mark where the invalid character is doing the trick.
Workbooks.Open("C:\Users\User\invalid??.xlsx") opens successfully the file named: invalidűő.xlsx
Getting that file's last modified date is a bit trickier,if I tried to store as string it runs into error, file not found, so it must be done via FSO and a lot of mess with the strings, and telling the editor that "Hey this is from Middle European code table!!" so in my case:
Chr(254) is ő in the mid-euro table. If your string contains this char in the editor it handles as the following.
Chr(254) is õ in the western table.
Setting the string with the specified Unicode hex code here ChrW$(&H151) is the key. (Accented o letter). While Chr(254) is (o letter with tilde, or without).
Sub lmfile_check2()
Dim files As String
Dim folder As String
Dim lmdate As Date
Dim lmfile As String
files = Empty
For i = 1 To 11
folder = ThisWorkbook.Sheets(1).Cells(i, 2).Value
files = Dir(folder & "*.*", vbNormal)
Do While files <> ""
On Error Resume Next
If FileDateTime(folder & files) = Empty Then GoTo 2
On Error GoTo 2
lmdate_2:
If FileDateTime(folder & files) > lmdate Or lmdate2 > lmdate Then
If IsEmpty(FileDateTime(folder & files)) Then
GoTo ende
End If
lmfile = files '
If lmdate2 > lmdate And lmdate <> Empty Then
lmdate = lmdate2
Else
lmdate = FileDateTime(folder & files)
End If
End If
GoTo ende
2:
If InStr(1, files, "hétfo") > 0 Then 'this section is for known invalid character
Set fs = CreateObject("Scripting.FileSystemObject")
files2 = Replace(files, "hetfo", "hetf" & ChrW$(&H151), 1, -1, vbTextCompare)
l = Len(files2)
files2 = Left(files2, l - 5)
Set f = fs.GetFile(folder & files2 & ChrW$(&H151) & ".xls")
lmdate2 = f.DateLastModified
If lmdate2 > lmdate Then
lmdate = lmdate2
lmfile = Replace(files, "hetfo", "hetf" & "?", 1, -1, vbTextCompare)
GoTo vege
End If
End If
GoTo lmdate_2
ende:
files = Dir
Loop
ThisWorkbook.Sheets(1).Cells(i, 1) = folder & lmfile
ThisWorkbook.Sheets(1).Cells(i, 4) = lmdate
Set f = Nothing
lmdate = Empty
lmfile = Empty
Next i
For i = 1 To 11
ThisWorkbook.Sheets(1).Cells(i, 1) = Replace(ThisWorkbook.Sheets(1).Cells(i, 1), "hétfo", "hétf" & "?", 1, -1, vbTextCompare)
Next i
MsgBox "Vertig"
End Sub

In Excel-Word Interop, how do I use the File Object after using the Name function to rename it?

Overall objective: create an Excel-based file converter that interops with Word, changing several built-in document properties, header/footer text & pics, watermark, and file name. The new attributes/text/file paths are found in cells. After changing all these attributes, et al, the file is to be copied as a regular .docx to a new Output folder and also exported as a PDF to a separate PDF Output folder. Optionally the files in the input folder will be deleted after the other steps are completed.
Specific problem: After I rename any of the files using the Name function, the File Object (I'm using File Scripting Object) loses its reference to the old file (since it's renamed), but does not pick up on the new, renamed file. After renaming the file, I would like to make a copy of it into the word document output folder; then, with the original, I would export it to the PDF output folder. Finally, I would either delete it or leave it alone, depending on an optional boolean.
I have attempted to re-assign the File Object with the new file, but this doesn't seem to be possible, and nothing else in its properties or methods makes sense to use.
Sub ChangeProperties()
Dim wordApp As Word.Application
Dim wordDoc() As Word.Document
Dim fso As New FileSystemObject
Dim fo(3) As Folder
Dim f As file
Dim cvSht As Worksheet
Dim fileSht As Worksheet
Dim progShp As Shape
Dim fileRng(0 To 13) As Range
Dim optRng As Range
Dim i As Long
Dim n As Long
Dim count As Long
Set wordApp = Word.Application
' Dashboard sheet
Set cvSht = Sheets("Convert")
' Sheet where user types new attributes or views old attributes
Set fileSht = Sheets("FileAttributes")
' Folder objects
Set fo(1) = fso.GetFolder(cvSht.Range("F3").Value)
Set fo(2) = fso.GetFolder(cvSht.Range("F5").Value)
Set fo(3) = fso.GetFolder(cvSht.Range("F7").Value)
ChDir (fo(1) & Application.PathSeparator)
Set optRng = cvSht.Range("H13")
' Just some user-defined true/false input cells
optERR = optRng
optMSG = optRng.Offset(1, 0)
optPDF = optRng.Offset(2, 0)
optDOC = optRng.Offset(3, 0)
optRMV = optRng.Offset(4, 0)
' Run some pre-execution checks to prevent catastrophic failure
If fo(1).Files.count > 20 Then
MsgBox "Too many files in folder. Please only 20 files at a time.", vbOKOnly, "Error!"
Exit Sub
End If
For i = 0 To 13
Set fileRng(i) = fileSht.Range("D27").Offset(0, i)
Next
n = 1
If InStr(1, fileRng(0).Offset(n - 1, 0), "doc") = 0 Then
MsgBox "New file names must end with a proper extension, i.e. - .docx", vbCritical, "Terminating Process!"
Exit Sub
End If
For Each f In fo(1).Files
For i = 0 To fo(1).Files.count
If fileRng(0).Value = f.Name Then
MsgBox "New file names must be different from the existing file names! Aborting...", vbCritical, "Terminating Process!"
Exit Sub
End If
Next
Next
For Each f In fo(1).Files
If optERR = False Then On Error Resume Next
If Left(f.Name, 1) = "~" Then GoTo Nxt
Set wordDoc(n) = wordApp.Documents.Open(f.Path)
' -------- Clipped out middle parts for clarity ---------
If fileRng(0).Offset(n - 1, 0) <> "" Then
End If
On Error GoTo 0
wordDoc(n).Save
Application.Wait Now + 0.00003
Application.StatusBar = "Processing..." & n & "/" & fo(1).Files.count
If optPDF Then
If Right(f, 1) = "x" Then
wordDoc(n).ExportAsFixedFormat fo(2) & Application.PathSeparator & _
VBA.Replace(f.Name, ".docx", ".pdf"), wdExportFormatPDF
ElseIf Right(f, 1) = "c" Then
wordDoc(n).ExportAsFixedFormat fo(2) & Application.PathSeparator & _
VBA.Replace(f.Name, ".doc", ".pdf"), wdExportFormatPDF
ElseIf Right(f, 1) = "m" Then
wordDoc(n).ExportAsFixedFormat fo(2) & Application.PathSeparator & _
VBA.Replace(f.Name, ".docm", ".pdf"), wdExportFormatPDF
End If
End If
wordDoc(n).Close
**Name f.Name As fileRng(0).Offset(n - 1, 0).Value** ' Causes the next lines to fail
**Set f = fileRng(0).Offset(n - 1, 0).Value** ' Attempt to reassign fails
**If optDOC Then f.Copy (fo(3) & "/")** ' This would fail too
If optRMV Then f.Delete
Nxt:
On Error GoTo 0
n = n + 1
Next
End Sub

Reference name-changing workbook in VBA

I was wondering whether there is a (built in/simple) option to reference/connect/link to a workbook that has a variable name?
My xy-problem is, I have workbook b v45.xlsm and wish to export data to workbook a v34.xlsm where the version numbers vary. So I was wondering if there is a sub-ID for each workbook, to which excel can refence independent of the name, automatically picking the most recent version in that folder.
Of course the simple solution is to pick the most recently modified excel file in the folderpath containing the string "a v", assuming an identical folderpath, but I was curious if there was a more convential/integrated option for this.
Kind regards.
(For future people looking at this issue, here is my manual solution:)
Sub find_planner_name()
Dim objFSO As Object
Dim objFolder As Object
Dim objFile As Object
Dim i As Integer
Dim string_object(0 To 2) As String 'saving the filenames as strings
Dim count As Integer 'counting nr of files encountered
Dim save_version_number(0 To 1) As Long
'Create an instance of the FileSystemObject
Set objFSO = CreateObject("Scripting.FileSystemObject")
'Get the folder object
Set objFolder = objFSO.GetFolder(ThisWorkbook.Path)
i = 1
'loops through each file in the directory and prints their names and path
For Each objFile In objFolder.Files
'print file name
'Cells(i + 1, 1) = objFile.name
count = count + 1
ReDim version_number(0 To count) As Long
string_object(0) = ""
string_object(1) = ""
string_object(2) = ""
string_object(0) = objFile.name
If Right(string_object(0), 5) = ".xlsm" Or Right(string_object(0), 5) = ".xlsb" Then
If Left(string_object(0), 10) = " planner v" Or Left(string_object(0), 10) = " planner v" Then
string_object(1) = Right(string_object(0), Len(string_object(0)) - 10)
MsgBox (string_object(1))
Do While IsNumeric(Left(string_object(1), 1)) = True
If IsNumeric(Left(string_object(1), 1)) = True Then
string_object(2) = string_object(2) & Left(string_object(1), 1)
string_object(1) = Right(string_object(1), Len(string_object(1)) - 1)
End If
Loop
If version_number(count) < string_object(2) And string_object(2) > 0 Then
version_number(count) = string_object(2)
MsgBox (version_number(count))
save_version_number(0) = version_number(count)
save_version_number(1) = count
End If
End If
End If
i = i + 1
Next objFile
count = save_version_number(1) 'rewrite maxima back
version_number(count) = save_version_number(0) 'rewrite maxima back
'MsgBox ("done " & version_number(count))
Dim myMax As Long
Dim count_results As Long
For count_results = LBound(version_number, 1) To UBound(version_number, 1)
If version_number(count_results) > myMax Then
myMax = version_number(count_results)
Findmax = count_results
'MsgBox (version_number(count_results))
End If
'MsgBox (version_number(count_results) & " and count_results = " & count_results)
Next count_results
'the name of the planner =
name_planner = " planner v" & version_number(Findmax) & ".xlsm"
' check if xlsm or xlsb
'MsgBox (name_planner)
If Dir(ThisWorkbook.Path & "\" & name_planner) <> "" Then
MsgBox ("File exists. and name is " & name_planner)
Else
name_planner = " planner v" & version_number(Findmax) & ".xlsb"
End If
End Sub
It should be more reliable to parse filenames looking at the version numbers rather than looking at the most recently modified file. Loop through all of them checking the filename with something like:
strFile = Dir(DirectoryPath)
Do while strFile <> ""
'Code here to parse strFile for intNewVersionNumber
if intNewVersionNumber > intVersionNumber then intVersionNumber = intNewVersionNumber
strFile = Dir
Loop
strFile = 'Code here to reconstruct filename from intVersionNumber
From your question, I think this might actually be necessary, even though there may be a couple of ways of adding/checking metadata on Excel files.
When you say the workbook name changes, it is literally the exact same file being renamed through Windows Explorer, or do you have multiple versions in the same folder created when you use Save As...? The issue of "automatically picking the most recent version" suggests that there are new versions being created in the same folder. If so, it means that you're actually changing which workbook you're linking to, so any kind of link to a file isn't going to work anyway. Also, even if you put in a sub-ID, each version will still have that same sub-ID. While this can still identify the files that are different versions of the same file, you still have to loop through all of those files looking for the latest version. A sub-ID would help if the filename is changing entirely, but doesn't remove the need to search through the different versions. So, if you can keep a consistent filename with only the version number changing, you'll be able to implement the simplest solution possible.

Filesystemobject permission denied - ways to check / skip?

I have a tool that copies all files from one folder into 10 seperate folders (all stored on different servers).
Sometimes when running this tool, I will get a permission denied error - which I presume comes down to a user being in one of the files that the program tries to overwrite.
Is there a way to confirm where the error occurs, and on top of that.. is there any way to create a report which shows which files were unsuccessful, but continue running after hitting the error?
Hope this makes sense, it is a generic FSO loop (think it was ron de bruin example)
Can you help? Error handling is definitely not my VBA forte!
I have the variables set before this with the filepaths and a seperate macro for each folder that gets copied - here is the code below
Handling the error is more important for me right now as it would let me pinpoint the issue
If Right(FromPath, 1) = "\" Then
FromPath = Left(FromPath, Len(FromPath) - 1)
End If
If Right(ToPath, 1) = "\" Then
ToPath = Left(ToPath, Len(ToPath) - 1)
End If
If Right(ToPath2, 1) = "\" Then
ToPath = Left(ToPath2, Len(ToPath) - 1)
End If
If Right(ToPath3, 1) = "\" Then
ToPath = Left(ToPath3, Len(ToPath) - 1)
End If
If Right(ToPath4, 1) = "\" Then
ToPath = Left(ToPath4, Len(ToPath) - 1)
End If
If Right(ToPath5, 1) = "\" Then
ToPath = Left(ToPath5, Len(ToPath) - 1)
End If
If Right(ToPath6, 1) = "\" Then
ToPath = Left(ToPath6, Len(ToPath) - 1)
End If
If Right(ToPath7, 1) = "\" Then
ToPath = Left(ToPath7, Len(ToPath) - 1)
End If
If Right(ToPath8, 1) = "\" Then
ToPath = Left(ToPath8, Len(ToPath) - 1)
End If
If Right(ToPath9, 1) = "\" Then
ToPath = Left(ToPath9, Len(ToPath) - 1)
End If
If Right(ToPath10, 1) = "\" Then
ToPath = Left(ToPath10, Len(ToPath) - 1)
End If
Set FSO = CreateObject("scripting.filesystemobject")
If FSO.FolderExists(FromPath) = False Then
MsgBox FromPath & " doesn't exist"
Exit Sub
End If
FSO.CopyFolder Source:=FromPath, Destination:=ToPath
FSO.CopyFolder Source:=FromPath, Destination:=ToPath2
FSO.CopyFolder Source:=FromPath, Destination:=ToPath3
FSO.CopyFolder Source:=FromPath, Destination:=ToPath4
FSO.CopyFolder Source:=FromPath, Destination:=ToPath5
FSO.CopyFolder Source:=FromPath, Destination:=ToPath6
FSO.CopyFolder Source:=FromPath, Destination:=ToPath7
FSO.CopyFolder Source:=FromPath, Destination:=ToPath8
FSO.CopyFolder Source:=FromPath, Destination:=ToPath9
FSO.CopyFolder Source:=FromPath, Destination:=ToPath10
Let's see if this helps out at all. The idea is to use your FSO to open the destination folder, and attempt to delete each file & subdirectory in the folder. This relies on the helper functions DeleteFile and DeleteFolder.
Module declarations: Important!
Option Explicit
Dim errors As Collection
Dim file As Object 'Scripting.File
Dim fldr As Object 'Scripting.Folder
This is the main procedure, note that you MUST declare all of your variables because of the Option Explicit at the module level.
Sub CopyFolderWithErrorHandling()
Dim FSO As Object 'Scripting.FileSystemObject
Dim paths As Variant
Dim path As Variant
Dim FromPath As String
Dim i As Long
Dim ToPath1$, ToPath2$, ToPath3$, ToPath4$, ToPath5$, ToPath6$, ToPath7$, ToPath8$, ToPath9$, ToPath10$
'!!!### IMPORTANT ###!!!
' Assign all of your "ToPath" variables here:
ToPath1 = "c:\some\path"
'Etc.
Set FSO = CreateObject("scripting.filesystemobject")
Set errors = New Collection
FromPath = "C:\Debug\" '## Modify as needed
If FSO.FolderExists(FromPath) = False Then
MsgBox FromPath & " doesn't exist"
Exit Sub
End If
'## Create an array of destination paths for concise coding
paths = Array(ToPath1, ToPath2, ToPath3, ToPath4, ToPath5, ToPath6, ToPath7, ToPath8, ToPath9, ToPath10)
'## Ensure each path is well-formed:
For i = 0 To UBound(paths)
path = paths(i)
If Right(path, 1) = "\" Then
path = Left(path, Len(path) - 1)
End If
paths(i) = path
Next
'## Attempt to delete the destination paths and identify any file locks
For Each path In paths
'# This funcitno will attempt to delete each file & subdirectory in the folder path
Call DeleteFolder(FSO, path)
Next
'## If there are no errors, then do the copy:
If errors.Count = 0 Then
For Each path In paths
FSO.CopyFolder FromPath, path
Next
Else:
'# inform you of errors, you should modify to print a text file...
Dim str$
For Each e In errors
str = str & e & vbNewLine
Next
'## Create an error log on your desktop
FSO.CreateTextFile(CreateObject("WScript.Shell").SpecialFolders("Desktop") & "\errors.txt").Write str
End If
Set errors = Nothing
End Sub
Helper functions:
The DeleteFolder procedure calls on DeleteFile for each file at its top level, and then calls itself recursively for each subdirectory in the specified folder path, if any.
The DeleteFile procedure logs each error to the errors collection, which we then use to write to a text file on your Desktop.
Sub DeleteFolder(FSO As Object, path As Variant)
'Check each file in the folder
For Each file In FSO.GetFolder(path).Files
Call DeleteFile(FSO, file)
Next
'Check each subdirectory
For Each fldr In FSO.GetFolder(path).SubFolders
Call DeleteFolder(FSO, fldr.path)
Next
End Sub
Sub DeleteFile(FSO As Object, file)
On Error Resume Next
Kill file.path
If Err.Number <> 0 Then
errors.Add file.path
End If
End Sub
Observations
The error log may contain some duplicates, or near-duplicates, as a lock file may be created, e.g. below. These are usually denoted with a tilde character, but since that is legal in a file name, I do not make any attempt to isolate or ignore "duplicates":
c:\my files\excel_file1.xlsx
c:\my files\~excel_file1.xlsx
Certain file types may not raise an error that can be trapped in the above code (.txt for example I think will not error if open in Notepad, etc.). In these cases, the above procedures I think will successfully delete the file, but now you have the risk that the user may save the old version over your newly copied version. I don't know how to prevent this from happening; your problem really is an architecture and replication one, and that is not well-suited to be handled by VBA from Excel...

Find a file in folder using different keywords VBA

I am a new to VBA. My issue is that I have a file that will be updated it into a specific folder by different users. Now everytime a user updates the file, the name of the file might not be the samefolder. However, I can narrow it down using specific keywords. I have been able to search for a file using a keyword but not multiple keywords. Please can you point me in the right direction on how I can use multiple keywords to find a file in a folder? Is it possible to write code that will work like the below?
Sub Start_countries()
Dim keyword, pathname, filename As String
pathname = "C:\XYZ\"
keyword = "lol" Or "rofl" Or "lmfao" Or "rotfl"
filename = Dir(pathname & "*.xls*")
Do While filename <> "*.xls*"
If LCase(filename) Like "*" & keyword & "*" Then
Set wb = Workbooks.Open(pathname & filename)
Find_count_sum_in_file filename
wb.Close SaveChanges:=True
Else
msgbox = "No file Found"
End If
Loop
End Sub
Try the following (adapted following your comment):
Private Const MAX_KWD = 5 ' use a constant to make sure everyone uses the same value
Sub Start_countries()
Dim keyword(1 To MAX_KWD), pathname As String
'Keywords for first file search
keyword(1) = "lol"
keyword(2) = "rofl"
keyword(3) = "lmfao"
keyword(4) = "rotfl"
pathname = "C:\XYZ1\"
search_for_files keyword(), pathname
'Keywords for second file search
keyword(1) = "omg"
keyword(2) = "fyi"
keyword(3) = "ok"
keyword(4) = "brb"
pathname = "C:\XYZ2\"
search_for_files keyword(), pathname
End Sub
Sub search_for_files(keyword(), pathname)
Dim filename As String, s As String
Dim i As Integer
filename = Dir(pathname & "*.xls*")
Do While InStr(filename, ".xls") <> 0
s = LCase(filename)
For i = 1 To MAX_KWD
If (InStr(s, keyword(i)) > 0) Then Exit For ' found!
Next i
If (i <= MAX_KWD) Then
Set WB = Workbooks.Open(pathname & filename)
Find_count_sum_in_file filename
WB.Close SaveChanges:=True
Else
MsgBox "No file Found"
End If
filename = Dir()
Loop
End Sub
Note that in Dim pathname, filename, s As String only s is declared as String; all others are declared as Variant (the As String does not apply to all variables declared on the line).
Note also that in your While filename <> "*.xls*" the test will be exact, i.e. it will look also for asterisks (*) in filename.