I want to loop through a directory and group files by the filenames up until the first _ in the filename.
Files are structured by
Manager Name_Employee Name_Assessment.xlsx
I want this to group together strings up until the first underscore. I can't designate a character length because managers have different names.
I'm thinking changing the If Right(filename,4) statement should do what I want, but I can't specify a character limit.
Public Sub Move_Files()
Dim sourceFolder As String, fileName As String
Dim destinationFolder As String, foundDestinationFolder As String
Dim missingFolders As String
sourceFolder = "C:\Assessment\"
If Right(sourceFolder, 1) <> "\" Then sourceFolder = sourceFolder & "\"
'Loop through *.xls files in source folder
missingFolders = ""
fileName = Dir(sourceFolder & "*.xls")
While fileName <> vbNullString
**If Right(fileName, 4) = ".xlsx" Then**
destinationFolder = Left(fileName, InStrRev(fileName, ".") - 1)
foundDestinationFolder = Find_Subfolder(sourceFolder, destinationFolder)
If foundDestinationFolder <> "" Then
Name sourceFolder & fileName As foundDestinationFolder & fileName
Else
missingFolders = missingFolders & vbCrLf & destinationFolder
End If
End If
fileName = Dir
Wend
If missingFolders = "" Then
MsgBox "All subfolders exist. All files moved to their respective destination folder"
Else
MsgBox "The following subfolders don't exist:" & vbCrLf & _
missingFolders
End If
End Sub
After it identifies all that fit within that manager's name, I want to group only those manager's employee files into a folder with their name up until the first _.
If the file extension is .xlsx, then change fileName = Dir(sourceFolder & "*.xls") to fileName = Dir(sourceFolder & "*.xlsx").
Consider the InStr function, which "returns a Variant (Long) specifying the position of the first occurrence of one string within another."
As is, destinationFolder = Left(fileName, InStrRev(fileName, ".") - 1) finds everything to the left of the last period.
So if you want to the destination folder to be Manager Name, then perhaps destinationFolder = Left$(fileName, InStr(fileName, "_") - 1)
Note that this can be made more robust to handle the possibility of no _ in the file name, or the file name beginning with _, with an initial If InStr(fileName, "_") > 1).
Related
I am working on a code which Moves the files after matching the file name into the folders accordingly "moveMatchedFilesInAppropriateFolders"
In order to run this code it is required that the Excel sheet should be saved in the same folder where the files and folders are available e.g. Folders and Files are saved in Drive E:\Archive. Therefore it is also important that the excel sheet should also be saved in the same folder (E:\Archive.
However i do not want to save the excel sheet in the same folder where the files and folders are placed and i wanted to save the excel sheet in some other Drive (e.g. Drive G). Is there any possibility where if i saved this excel sheet in other Drive and just give the path to it the code should run and not give error.
Sub moveMatchedFilesInAppropriateFolders()
Dim sh As Worksheet, lastR As Long, filesPath As String, fileName As String, foldersRoot As String, FolderPath As String
Dim arr, boolNotFound As Boolean, i As Long
Set sh = ActiveSheet
lastR = sh.Range("A" & sh.Rows.Count).End(xlUp).Row
arr = sh.Range("A2:A" & lastR).Value2
foldersRoot = ThisWorkbook.Path & "\" 'use here the root folder for folders
filesPath = "G:\!Archive Management\2023\" 'use here the path where the files can be found
Set FSO = CreateObject("Scripting.FileSystemObject") 'to check if file exists
For i = 1 To UBound(arr)
boolNotFound = False
If Dir(foldersRoot & arr(i, 1), vbDirectory) <> "" Then
FolderPath = foldersRoot & arr(i, 1) & "\"
Else
MsgBox arr(i, 1) & " folder could not be found!" & vbCrLf & _
"Please, note and correct it after copying the matching ones and run the code again!"
boolNotFound = True
End If
If Not boolNotFound Then
fileName = Dir(filesPath & arr(i, 1) & "*.*")
Do While fileName <> ""
If Not FSO.FileExists(FolderPath & fileName) Then 'move/copy only if it does not exist in destination fld
'uncomment the way you need (moving or copying):
Name filesPath & fileName As FolderPath & fileName 'the file is moved
'FileCopy filesPath & fileName, folderPath & fileName 'the file is copied
End If
fileName = Dir
Loop
End If
Next i
End Sub
I want to be able to rename the file to the fifth file number then add on import-TMP-AD-IFI-REV12
The file path only changes for the fifth file for new jobs (the bolded part)
R:\3.0 Projects\2.0 Current Projects\2021 JOBS\ 999111-DO-Customer-Description \2.0 Estimate\2.7 Final Estimates\999111import-TMP-IFI-REV12.CSV
Such as for this example it will become 999111import-TMP-IFI-REV12
The file is to create a copy of the xlsm then saves it as a CSV
Sub OverwriteData_In_CSV()
Dim CSVfile
***CSVfile = ThisWorkbook.Sheets("DataFeed").Cells("N1")***
' ^ needs to be rewritten to properly save with new name.
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Foundation Budget Template")
'
Application.ScreenUpdating = False
ws.Select
ws.Copy
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs Filename:=CSVfile, FileFormat:=xlCSV, local:=True
Application.DisplayAlerts = True
ActiveWorkbook.Close False
Application.ScreenUpdating = True
'
End Sub
Function getName(pf): getName = Split(Mid(pf, InStrRev(pf, "\") + 1), ".")(0): End Function
Sub Test()
MsgBox getName(ActiveWorkbook.FullName)
End Sub
I'm afraid I fail to understand what exactly, you are trying to achieve but I can tell you two things.
You don't need to Select a worksheet in order to copy it to the clipboard. Instead, I would worry about the range from that sheet that is to be copied (though Excel might indeed preempt your omission).
The code below is a demonstration of how to manipulate file names. You will find what you need in it. The procedure is self-contained and ready to run. It is also fully annotated for you to easily understand it.
Sub Snippet()
Const Original As String = "R:\3.0 Projects\2.0 Current Projects\2021 JOBS\999111-DO-Customer-Description\" & _
"2.0 Estimate\2.7 Final Estimates\999111import-TMP-IFI-REV12.CSV"
Dim Ext As String ' file extension
Dim Fn As String ' file name
Dim Path As String ' file path
Dim Ffn As String ' full file name
Dim Sp() As String
' extract the extension
Sp = Split(Original, ".") ' the split is 0-based
Ext = Sp(UBound(Sp))
ReDim Preserve Sp(UBound(Sp) - 1)
Ffn = Join(Sp, ".")
MsgBox "File & Path = " & Ffn & vbCr & _
"Extension = " & Ext
' extrac the file name
Sp = Split(Original, "\")
Fn = Sp(UBound(Sp))
MsgBox "File name with extension = " & Fn
Sp = Split(Fn, ".") ' the split is 0-based
MsgBox "File name without extension = " & Sp(0) & vbCr & _
"Exension = " & Sp(1)
' extract a folder from the full file name
Sp = Split(Original, "\")
MsgBox "5th path element = " & Sp(4) ' 5th element = #4
' replace or modify the 5th element
Sp = Split(Original, "\")
Fn = Sp(UBound(Sp))
Sp(4) = Split(Fn, ".")(0)
Ffn = Join(Sp, "\")
MsgBox "Original Ffn: " & Original & vbCr & vbCr & _
"Changed 5th element: " & Ffn
' extract the path from a full file name
Sp = Split(Original, "\")
ReDim Preserve Sp(UBound(Sp) - 1)
Path = Join(Sp, "\")
MsgBox "Observe: path does NOT end on back-slash:" & vbCr & Path
' append a file name to path
Sp = Split(Path, "\")
Fn = "My File Name" & "." & Ext
ReDim Preserve Sp(UBound(Sp) + 1)
Sp(UBound(Sp)) = Fn
Ffn = Join(Sp, "\")
MsgBox "Full File Name = " & Ffn
End Sub
I'm completely new to VBA and had some trouble googling this problem cause variable has multiple meanings.
I am trying to open a file and assign its name to a variable. The file's name is never the same though I always download it to the same folder (one file in that folder only). The only recognizable thing about the file are 3 letters "ABC".
So far I managed to get opening the file to work but not assigning the non-standardized file name to a variable.
Sub openwb()
Dim wb As Workbook Dim directory As String
directory = "D:\Users\AAA\Desktop\Practice"
Set FSO = CreateObject("Scripting.FileSystemObject")
Set folder = FSO.GetFolder(directory)
For Each file In folder.Files
If Mid(file.Name, InStrRev(file.Name, ".") + 1) = "xlsm" Then
Workbooks.Open directory & Application.PathSeparator & file.Name
End If
Next file
End Sub
Public Sub RecordFileName()
Dim sPath As String, sFile As String
Dim wb As Workbook
sPath = "D:\Users\AAA\Desktop\Practice"
sFile = sPath & "*ABC*"
End Sub
Here is a function you can use. It will return the filename you are looking for, and you can specify a file pattern if you want to, or you can omit that argument and it will assume all files.
Function GetFullFileName(sFolder As String, Optional sPattern As String = "*") As String
Dim sFile As String
' ensure sFolder ends with a backslash
If Right$(sFolder, 1) <> "\" Then sFolder = sFolder & "\"
sFile = Dir(sFolder & sPattern)
If sFile = "" Then
MsgBox "NOT FOUND: " & sFolder & sPattern
End
End If
GetFullFileName = sFolder & sFile
End Function
Usage:
MsgBox GetFullFileName("C:\Users\Fred\Documents")
Or
MsgBox GetFullFileName("C:\Users\Fred\Documents\", "*ABC*.xlsm")
Or
sFullFile = GetFullFileName("C:\Users\Fred\Documents\", "*ABC*.xlsm")
I have the following module to check the number of files contained in a folder and display a messagebox with the with the number of files:
Sub CheckFiles(strDir As String, strType As String)
Dim file As Variant, i As Integer
strDir = ThisWorkbook.Path & "\Source\"
If Right(strDir, 1) <> "\" Then strDir = strDir & "\"
file = Dir(strDir & strType)
While (file <> "")
i = i + 1
file = Dir
Wend
MsgBox i
End Sub
Files to look for (in separate module):
Call CheckFiles("", "File1*.xlsx")
Call CheckFiles("", "File2*.xlsx")
What I want to do is to only display messagebox if the number of files for File1 is not excaly 3 and the number of files for File2 is not excaly 2. This is what I'm having trouble doing? How can this be acheived?
Add the ChckNum as Third Parameter in the Subject and pass it in the Call Statement
Try:
Sub CheckFiles(strDir As String, strType As String, chknum As Integer)
Dim file As Variant, i As Integer
strDir = ThisWorkbook.path & "\Source\"
If Right(strDir, 1) <> "\" Then strDir = strDir & "\"
file = Dir(strDir & strType)
While (file <> "")
i = i + 1
file = Dir
Wend
If i <> chknum Then MsgBox i
End Sub
And
Call CheckFiles("", "File1*.xlsx", 3)
Call CheckFiles("", "File2*.xlsx", 2)
I'm working on a code that will do the following:
1. Create folder based on the filename of the excel file in the same root folder
2. Move the excel file to the newly created folder with the same name
I'm having a problem in setting up the code that will check the excel files in the folder as it contains other excel files that I want to skip. The difference between the filenames is that the one I want to exclude are the filenames with a date at the start of the file name.
Here's what I have so far
Sub Create_Folder()
Dim ParentFolder As String
ParentFolder = ThisWorkbook.Path
myFile = Dir(ParentFolder)
Do While myFile <> "Australia Formatting" 'Or "20*"
Debug.Print myFile
Debug.Print Left(myFile, InStr(1, myFile, "_") - 1)
MkDir (ParentFolder & Left(myFile, InStr(1, myFile, "_") - 1))
Name ParentFolder & myFile As ParentFolder & Left(myFile, InStr(1, myFile, "_") - 1) & "\" & myFile
myFile = Dir
Loop
End Sub
Sub Create_Folder()
Dim ParentFolder As String
dim s as string
ParentFolder = ThisWorkbook.Path & "\"
myFile = Dir(ParentFolder & "*.xl??") 'only want to look at excel files
Do While myFile <> "" 'keep looking until all files have been checked
if myfile ="Australia Formatting" Or isdate(left(myfile,8)) then
'skip
else
s=Left(myFile, InStr(1, myFile, "_") - 1)
MkDir (ParentFolder & s)
Name ParentFolder & myFile As ParentFolder & s & "\" & myFile
end if
myFile = Dir()
Loop
End Sub
'done on my phone so i can't test this - may be typos