After finding files, find subsequently received file - vba

This code finds files that have a certain date in the file name, then saves them in a specified folder.
When another file that has the same date comes in, I want to add this file to the collection of previously found files. It doesn't find the new file.
If I delete the previously made folders and run it from scratch it will find all the files. It is like the recursivefilesearch isn't refreshing the folder and just using the previously found files.
Option Explicit
Sub Merge_Data()
Application.StatusBar = "Finding today's files"
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Dim FilePath As String
FilePath = "folder\"
' Ask user what date they would like to merge the files for
Dim dateString As String, TheDate As Date
Dim valid As Boolean: valid = True
Dim Input_Box_Msg As String
Input_Box_Msg = "What Date would you like to merge the files for? " & vbNewLine & "Please enter date in format mm/dd/yyyy: "
Do
dateString = InputBox(Input_Box_Msg)
If IsDate(dateString) Then
TheDate = DateValue(dateString)
valid = True
Else
MsgBox "Invalid date. Please enter date in format mm/dd/yyyy:"
valid = False
End If
Loop Until valid = True
'Edit_1: Based on Comment
' Obtain current date in format yyyymmdd
Dim Current_Date, Current_Date_1 As String
Current_Date = Format(TheDate, "yyyymmdd")
Current_Date_1 = Format(TheDate, "yyyy_mm_dd")
' Find all files in folder that contain previously input date by the user
Dim objFSO As Object
Set objFSO = CreateObject("Scripting.FileSystemObject")
Dim objRegExp As Object
Set objRegExp = CreateObject("VBScript.RegExp")
' Regex object with previously input date by the user
objRegExp.Pattern = Current_Date
objRegExp.IgnoreCase = True
Dim colFiles As Collection
Set colFiles = New Collection
Dim f As Variant
' Recursively search through folders for files that match today's date
RecursiveFileSearch FilePath, objRegExp, colFiles, objFSO
Dim Combined_Path As String
Combined_Path = "new_folder\"
Combined_Path = Combined_Path & Current_Date & "\"
Dim Path As String
Dim Folder As String
Dim FileFormatNum As Long
Dim FileName As String
' .xlsx extension number
FileFormatNum = 51
Path = Combined_Path
Folder = Dir(Path, vbDirectory)
' Create New folder to store today's files
If Folder = vbNullString Then
VBA.FileSystem.MkDir (Path)
End If
Dim Full_File_Path As String
Dim FSO As Object
Set FSO = CreateObject("Scripting.FileSystemObject")
Dim File_Type_1 As String
Application.StatusBar = "Saving today's files in new folder"
' Save Files that match criteria in new folder in .xlsx format
For Each f In colFiles
Workbooks.Open f
FileName = ActiveWorkbook.Name
MsgBox FileName
File_Type_1 = FSO.GetExtensionName(FileName)
If File_Type_1 = "xls" Then
FileName = FileName & "x"
Full_File_Path = Path & FileName
ActiveWorkbook.SaveAs FileName:=Full_File_Path, FileFormat:=FileFormatNum, CreateBackup:=False
ActiveWorkbook.Close
File_Type_1 = ""
FileName = ""
Full_File_Path = ""
ElseIf File_Type_1 = "xlsx" Then
If Left(FileName, 11) = "Merged_File" Then Exit For
Else
Full_File_Path = Path & FileName
ActiveWorkbook.Close
Kill Full_File_Path
ActiveWorkbook.SaveAs FileName:=Full_File_Path, FileFormat:=FileFormatNum, CreateBackup:=False
ActiveWorkbook.Close
FileName = ""
Full_File_Path = ""
File_Type_1 = ""
End If
Next
FilePath = ""
Current_Date = ""
Current_Date_1 = ""
Set f = Nothing
Set colFiles = New Collection
Set FSO = Nothing
Set objFSO = Nothing
Set objRegExp = Nothing
RecursiveFileSearch FilePath, objRegExp, colFiles, objFSO
End Sub
Sub RecursiveFileSearch(ByVal targetFolder As String, ByRef objRegExp As Object, _
ByRef matchedFiles As Collection, ByRef objFSO As Object)
Dim objFolder As Object
Dim objFile As Object
Dim objSubfolder As Object
Dim objSubFolders As Object
'Get the folder object associated with the target directory
Set objFolder = objFSO.GetFolder(targetFolder)
'Loop through the files current folder
For Each objFile In objFolder.Files
If objRegExp.test(objFile) Then
matchedFiles.Add (objFile)
End If
Next
'Loop through the each of the sub folders recursively
Set objSubFolders = objFolder.Subfolders
For Each objSubfolder In objSubFolders
RecursiveFileSearch objSubfolder, objRegExp, matchedFiles, objFSO
Next
'Garbage Collection
Set objFolder = Nothing
Set objFile = Nothing
Set objSubFolders = Nothing
Set objSubfolder = Nothing
End Sub
Function FileExists(ByVal FileToTest As String) As Boolean
FileExists = (Dir(FileToTest) <> "")
End Function
Function StripNumber(stdText As String)
Dim str As String, i As Integer
'strips the number from a longer text string
stdText = Trim(stdText)
For i = 1 To Len(stdText)
If Not IsNumeric(Mid(stdText, i, 1)) Then
str = str & Mid(stdText, i, 1)
End If
Next i
StripNumber = str ' * 1
End Function

Related

Powerpoint VBA function return not working

This is driving me mad: I have a sub and a function in a powerpoint vba.
The sub starts by allowing me to select a dir. The function, called from the sub, finds a file in the dir. I want it as a function outside of the sub, as I will need to use it multiple times.
The sub is still under development, so doesn't do much, but works. The function works too if I give it something to do - like open the found file (ie uncomment that line in my code below) - but I can't for the life of me get it to return the filePath to the sub. Please help!
The sub:
Sub ManagementSummaryMerge()
Dim folderPath As String
'select dir
Dim FldrPicker As FileDialog
Set pptApp = CreateObject("PowerPoint.Application")
pptApp.Visible = True
'Retrieve Target Folder Path From User
Set FldrPicker = Application.FileDialog(msoFileDialogFolderPicker)
With FldrPicker
.Title = "Select A Target Folder"
.AllowMultiSelect = False
If .Show <> -1 Then GoTo NextCode
folderPath = .SelectedItems(1) & "\"
End With
'In Case of Cancel
NextCode:
folderPath = folderPath
If folderPath = "" Then GoTo EndOfSub
'set _Main <= string I want to look for
Dim v As String
v = "_Main"
Dim fullFilePathIWantToSet As String
'set value of fullFilePathIWantToSet from findFile function
fullFilePathIWantToSet = findFile(folderPath, v)
'when I test, this MsgBox appears, but blank
MsgBox fullFilePathIWantToSet
'If I can get this working properly, I want to be able to do something like this:
'objFSO.CopyFile fullFilePathIWantToSet, duplicateFilePath
'Presentations.Open (duplicateFilePath)
'numSlides = ActivePresentation.Slides.Count
'etc
EndOfSub:
'let the sub end
End Sub
The function:
Function findFile(ByRef folderPath As String, ByVal v As String) As String
Dim fileName As String
Dim fullFilePath As String
Dim duplicateFilePath As String
Dim numFolders As Long
Dim numSlides As Integer
Dim folders() As String
Dim i As Long
If Right(folderPath, 1) <> "\" Then folderPath = folderPath & "\"
ileName = Dir(folderPath & "*.*", vbDirectory)
While Len(fileName) <> 0
If Left(fileName, 1) <> "." Then
fullFilePath = folderPath & fileName
duplicateFilePath = folderPath & "duplicate " & fileName
If (GetAttr(fullFilePath) And vbDirectory) = vbDirectory Then
ReDim Preserve folders(0 To numFolders) As String
folders(numFolders) = fullFilePath
numFolders = numFolders + 1
Else
'if true, the it matches the string we are looking for
If InStr(10, fullFilePath, v) > 0 Then
'if true, then it isn't in a dir called P/previous, which I want to avoid
If InStr(1, fullFilePath, "evious") < 1 Then
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set f = objFSO.GetFile(fullFilePath)
'If true, then it isn't one of those funny duplicate files that microsoft makes, that has the ~ at the beginning of the file name
If f.Size > 5000 Then GoTo ReturnSettings
' if we're here then we have found the one single file that we want! Go ahead and do our thing
findFile = fullFilePath
Exit Function
End If
End If
End If
End If
End If
fileName = Dir()
Wend
For i = 0 To numFolders - 1
findFile folders(i), v
Next i
End Function
I'm a total VBA noob, so have just pva glued this together from what I can find online. Is it not working because of the findFile loop returning an array of one instead of a string? I thought the 'Exit Function' call would do away with that issue.
Please excuse the recursive if statements - the people that I am doing this for don't have a totally standard way of storing their ppts, but this hones down on the ppt I want. When the sub is complete, it will itself loop through 130 sub dirs of the selected dir, and within each of those sub dirs it will grab various slides from six different ppts and merge them into one, ie consolidate data from 780 ppts into 130 - something I definitely want to automate!
This is my first question posted on stack Overflow, so I hope I have posed it clearly and correctly. I have searched extensively for a solution to this. I hope the solution pops out to you! Many thanks in advance.
This is a classic case of needing to use Option Explicit.
You have a missing f from filename and this goes unchecked as a variable ilename not filename.
You should put Option Explicit at the top of every module and declare all your variables. There is also a missing label for a GoTo statement which I have added.
Note: You are doing a full string case sensitive match on the file name within the selected folder.
Option Explicit
Sub ManagementSummaryMerge()
Dim folderPath As String, FldrPicker As FileDialog, pptApp As Object
Set pptApp = CreateObject("PowerPoint.Application")
pptApp.Visible = True
Set FldrPicker = Application.FileDialog(msoFileDialogFolderPicker)
With FldrPicker
.Title = "Select A Target Folder"
.AllowMultiSelect = False
If .Show <> -1 Then GoTo NextCode
folderPath = .SelectedItems(1) & "\"
End With
'In Case of Cancel
NextCode:
folderPath = folderPath
If folderPath = "" Then GoTo EndOfSub
'set _Main <= string I want to look for
Dim v As String
v = "_Main"
Dim fullFilePathIWantToSet As String
'set value of fullFilePathIWantToSet from findFile function
fullFilePathIWantToSet = findFile(folderPath, v)
'when I test, this MsgBox appears, but blank
MsgBox fullFilePathIWantToSet
'If I can get this working properly, I want to be able to do something like this:
'objFSO.CopyFile fullFilePathIWantToSet, duplicateFilePath
'Presentations.Open (duplicateFilePath)
'numSlides = ActivePresentation.Slides.Count
'etc
EndOfSub:
'let the sub end
End Sub
Function findFile(ByRef folderPath As String, ByVal v As String) As String
Dim fileName As String
Dim fullFilePath As String
Dim duplicateFilePath As String
Dim numFolders As Long
Dim numSlides As Integer
Dim folders() As String, i As Long
If Right(folderPath, 1) <> "\" Then folderPath = folderPath & "\"
fileName = Dir(folderPath & "*.*", vbDirectory)
While Len(fileName) <> 0
If Left(fileName, 1) <> "." Then
fullFilePath = folderPath & fileName
duplicateFilePath = folderPath & "duplicate " & fileName
If (GetAttr(fullFilePath) And vbDirectory) = vbDirectory Then
ReDim Preserve folders(0 To numFolders) As String
folders(numFolders) = fullFilePath
numFolders = numFolders + 1
Else
'if true, the it matches the string we are looking for
If InStr(10, fullFilePath, v) > 0 Then
'if true, then it isn't in a dir called P/previous, which I want to avoid
If InStr(1, fullFilePath, "evious") < 1 Then
Dim objFSO As Object, f As Object
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set f = objFSO.GetFile(fullFilePath)
'If true, then it isn't one of those funny duplicate files that microsoft makes, that has the ~ at the beginning of the file name
If f.Size > 5000 Then GoTo ReturnSettings
' if we're here then we have found the one single file that we want! Go ahead and do our thing
findFile = fullFilePath
Exit Function
End If
End If
End If
End If
fileName = Dir()
Wend
For i = 0 To numFolders - 1
findFile folders(i), v
Next i
Exit Function
ReturnSettings:
End Function
OK, I have a solution to this. It's not totally elegant, because it relies on globally set variables, but it works and is good enough for me:
' show if a mistake is made
Option Explicit
' globally set the var we want to return to the sub from the function
Public foundFilePath As String
Sub FindIt()
Dim colFiles As New Collection, vFile As Variant, mypath As String
FldrPicker As FileDialog, fileToFind As String, pptApp As Object
Set pptApp = CreateObject("PowerPoint.Application")
pptApp.Visible = True
Set FldrPicker = Application.FileDialog(msoFileDialogFolderPicker)
With FldrPicker
.Title = "Select A Target Folder"
.AllowMultiSelect = False
If .Show <> -1 Then GoTo NextCode
mypath = .SelectedItems(1) & "\"
End With
NextCode:
mypath = mypath
If mypath = "" Then GoTo EndOf
'
' find file
'
fileToFind = "*your_string_here*"
'calls to function RecursiveDir, which sets first matching file as foundFilePath
Call RecursiveDir(colFiles, mypath, fileToFind, True)
' do what you want with foundFilePath
MsgBox "Path of file found: " & foundFilePath
'
'find second file
'
fileToFind = "*your_second_string_here*"
Call RecursiveDir(colFiles, mypath, fileToFind, True)
MsgBox "Second file path: " & foundFilePath
EndOf:
End Sub
Public Function RecursiveDir(colFiles As Collection, _
strFolder As String, _
strFileSpec As String, _
bIncludeSubfolders As Boolean)
Dim strTemp As String, fullFilePath As String
Dim colFolders As New Collection
Dim vFolderName As Variant
'Add files in strFolder matching strFileSpec to colFiles
strFolder = TrailingSlash(strFolder)
strTemp = Dir(strFolder & strFileSpec)
Do While strTemp <> vbNullString
strFileSpec = Replace(strFileSpec, "*", "")
If InStr(strTemp, strFileSpec) > 0 Then
foundFilePath = strFolder & strTemp
Exit Function
End If
colFiles.Add strFolder & strTemp
strTemp = Dir
Loop
If bIncludeSubfolders Then
'Fill colFolders with list of subdirectories of strFolder
strTemp = Dir(strFolder, vbDirectory)
Do While strTemp <> vbNullString
If (strTemp <> ".") And (strTemp <> "..") Then
If (GetAttr(strFolder & strTemp) And vbDirectory) <> 0 Then
colFolders.Add strTemp
End If
End If
strTemp = Dir
Loop
'Call RecursiveDir for each subfolder in colFolders
For Each vFolderName In colFolders
Call RecursiveDir(colFiles, strFolder & vFolderName, strFileSpec, True)
Next vFolderName
End If
End Function
Public Function TrailingSlash(strFolder As String) As String
If Len(strFolder) > 0 Then
If Right(strFolder, 1) = "\" Then
TrailingSlash = strFolder
Else
TrailingSlash = strFolder & "\"
End If
End If
End Function
That works. What was a better solution for me is the below. It uses separate subs / functions to do the following: pick a folder ; loop through first-child folders ; recursively search for a file, using a partial file name, in all folders and subfolders ; do something with the found file/s (plural if the search function is called on multiple strings).
It's not necessary to separate out like this, but I find it easier for separation of concerns and keeping things simple.
Sub 1: Root folder picker. Passes selected folder onto sub 2
Option Explicit
Public foundFilePath As String
Sub StartSub()
' selects the parent folder and passes it to LoopSuppliers
Dim masterPath As String, FldrPicker As FileDialog, pptApp As Object
Set pptApp = CreateObject("PowerPoint.Application")
Set FldrPicker = Application.FileDialog(msoFileDialogFolderPicker)
pptApp.Visible = True
With FldrPicker
.Title = "Select A Target Folder"
.AllowMultiSelect = False
If .Show <> -1 Then GoTo NextCode
masterPath = .SelectedItems(1) & "\"
End With
NextCode:
masterPath = masterPath
If masterPath = "" Then GoTo EndOf
Call LoopSuppliers(masterPath) ' goes to masterFolder in LoopSuppliers sub
EndOf:
End Sub
Sub two: simply loops through the parent folder and passes the path of each first-child sub folder to function three to do something with it. Adapted from here.
Private Sub LoopSuppliers(masterFolder As String)
Dim objFSO As Object, objFolder As Object, objSupplierFolder As Object
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(masterFolder)
For Each objSupplierFolder In objFolder.SubFolders
'objSupplierFolder.path objSubFolder.Name <- object keys I can grab
Call ManipulateFiles(objSupplierFolder.path)
Next objSupplierFolder
End Sub
Function 1: Grabs file paths for doing something with
Private Function ManipulateFiles(ByRef FolderPath As String)
Dim file1 As String, file2 As String, file3 As String
' each of these calls find a file anywhere in a suppliers subfolders, using the second param as a search string, and then holds it as a new var
Call FindSupplierFile(FolderPath, "search_string1")
file1 = foundFilePath
Call FindSupplierFile(FolderPath, "search_string2")
file2 = foundFilePath
Call FindSupplierFile(FolderPath, "search_string3")
file3 = foundFilePath
'
' do something with the files!
'
End Function
Function 2: This is the function that takes a dir, a search string, and then loops through all the dirs folders and sub folders until it gets a match. I've included extra filtering, to show how I further narrowed down the files that could be returned to function 1.
Private Function FindSupplierFile(ByRef FolderPath As String, ByVal v As String) As String
Dim FileName As String, fullFilePath As String, numFolders As Long, Folders() As String, i As Long
Dim objFSO As Object, f As Object
If Right(FolderPath, 1) <> "\" Then FolderPath = FolderPath & "\"
FileName = Dir(FolderPath & "*.*", vbDirectory)
While Len(FileName) <> 0
If Left(FileName, 1) <> "." Then
fullFilePath = FolderPath & FileName
If (GetAttr(fullFilePath) And vbDirectory) = vbDirectory Then
ReDim Preserve Folders(0 To numFolders) As String
Folders(numFolders) = fullFilePath
numFolders = numFolders + 1
Else
'
' my filters
'
If InStr(1, fullFilePath, "evious") < 1 Then ' filter out files in folders called "_p/Previous"
If InStr(10, fullFilePath, v) > 0 Then ' match for our search string 'v'
Set objFSO = CreateObject("Scripting.FileSystemObject") ''
Set f = objFSO.GetFile(fullFilePath) '' use these three code lines to check that the file is more that 5kb - ie not a tiny ~ file
''
If f.Size > 5000 Then ''
foundFilePath = fullFilePath ' if we get in here we have the file that we want
Exit Function ' as we have found the file we want we can exit the function (which means we carry on with ManipulateFiles)
End If ' end f.size
End If ' end InStr v if
End If ' end InStr evious if
'
' end of my filters
'
End If ' end get attr if else
End If ' end left if
FileName = Dir()
Wend ' while len <> 0
For i = 0 To numFolders - 1
FindSupplierFile Folders(i), v
Next i
End Function

Query user to choose path

I have a code that reads a folder contents (only other folders) and lists them into excel in a certain range.
The problem is that the path where the code reads contents (/CtrExtrase) is given in the code.
I need the path to be choosen by the user. Tried and failed totally.
My code:
Sub distribuire_foldere()
Dim objFSO As Object
Dim objFolder As Object
Dim objSubFolder As Object
Dim i As Integer
'CLEARS ALL PREVIOUS CONTENT
Sheets("DISTRIBUIRE foldere").Range("A2:A2000").ClearContents
'INSERTS IN CELL THE PATH WHERE THE SCRIPT IS READING
Sheets("DISTRIBUIRE foldere").Range("$E$1").Value = ThisWorkbook.path & "\CtrExtrase"
' LISTS THE CONTENT OF THE CHOOSEN FOLDER
Application.StatusBar = ""
'Create an instance of the FileSystemObject
Set objFSO = CreateObject("Scripting.FileSystemObject")
'Get the folder object
On Error GoTo nuexistafolderul
'THIS IS THE PROBLEM, AS I NEED THE USER TO CHOOSE THE PATH:
Set objFolder = objFSO.GetFolder(Application.ThisWorkbook.path & "\CtrExtrase")
i = 1
'loops through each folder in the directory and prints their names
On Error GoTo handleCancel
Application.EnableCancelKey = xlErrorHandler
For Each objSubFolder In objFolder.subfolders
Application.StatusBar = objSubFolder.path & " " & objSubFolder.Name
'OUTPUTS THE FOLDERS NAME
Cells(i + 1, 1) = objSubFolder.Name
i = i + 1
Next objSubFolder
handleCancel:
If Err = 18 Then
MsgBox "Ai anulat procesul inainte de finalizare! Reia procedura!"
nuexistafolderul:
MsgBox "Nu exista folderul pentru extractia contractelor! Extrage intai contractele!"
End If
'CALLS A MODULE THAT INSERTS CERTAIN TEXT INTO A BATCH FILE
Call Module1.batchfile2
End Sub
Use FileDialog with FolderPicker, here it's wrap in a function :
Function GetFolder(Optional strPath As String = "C:\") As String
Dim fldr As FileDialog
Dim sItem As String
GetFolder = vbNullString
Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
With fldr
.Title = "Select a Folder"
.AllowMultiSelect = False
.InitialFileName = strPath
If .Show <> -1 Then GoTo NextCode
sItem = .SelectedItems(1)
End With
NextCode:
GetFolder = sItem
Set fldr = Nothing
End Function
And your code, you can set the default path in GetFolder(ThisWorkbook.Path & "\") :
Sub distribuire_foldere()
Dim objFSO As Object
Dim objFolder As Object
Dim objSubFolder As Object
Dim i As Integer
'CLEARS ALL PREVIOUS CONTENT
Sheets("DISTRIBUIRE foldere").Range("A2:A2000").ClearContents
'INSERTS IN CELL THE PATH WHERE THE SCRIPT IS READING
Sheets("DISTRIBUIRE foldere").Range("$E$1").Value = ThisWorkbook.Path & "\CtrExtrase"
' LISTS THE CONTENT OF THE CHOOSEN FOLDER
Application.StatusBar = ""
'Create an instance of the FileSystemObject
Set objFSO = CreateObject("Scripting.FileSystemObject")
'Get the folder object
On Error GoTo nuexistafolderul
'THIS IS THE PROBLEM, AS I NEED THE USER TO CHOOSE THE PATH:
Set objFolder = objFSO.GetFolder(GetFolder(ThisWorkbook.Path & "\"))
i = 1
'loops through each folder in the directory and prints their names
On Error GoTo handleCancel
Application.EnableCancelKey = xlErrorHandler
For Each objSubFolder In objFolder.SubFolders
Application.StatusBar = objSubFolder.Path & " " & objSubFolder.Name
'OUTPUTS THE FOLDERS NAME
Cells(i + 1, 1) = objSubFolder.Name
i = i + 1
Next objSubFolder
handleCancel:
If Err = 18 Then
MsgBox "Ai anulat procesul inainte de finalizare! Reia procedura!"
nuexistafolderul:
MsgBox "Nu exista folderul pentru extractia contractelor! Extrage intai contractele!"
End If
'CALLS A MODULE THAT INSERTS CERTAIN TEXT INTO A BATCH FILE
Call Module1.batchfile2
End Sub

Rename all workbooks in folder

I am trying to rename all workbooks in a folder, based on the value of a cell in each file (basically reports dates). The xls files are saved from the internet in a folder. I wrote the code below but it's not working... workbooks.open fail and wb.name seems to not work either.
Sub openrenamebook()
Dim FileExtension As String, FilesInFolder As String
Dim FolderPath As String
Dim wb As Workbook
FileExtension = "*xls"
FolderPath = "N:\MyFolder\"
FilesInFolder = Dir(FolderPath & FileExtension)
Do While FilesInFolder <> ""
Set wb = Workbooks.Open(Filename:=FolderPath & FilesInFolder, ReadOnly:=False)
wb.Name = Mid(wb.Sheets(1).Cells(1, 2).Value, 38, 2)
wb.Close True
FilesInFolder = Dir
Set wb = Nothing
Loop
End Sub
You cannot rename a file by changing the Workbook Name property. But you can use the FileSystemObject.
A reference to Microsoft Scripting Runtime is required for this code to work.
I cannot fully test because I do not know what file paths are specified in your worksheet. It assumes they're valid
Sub Test()
Dim FSO As New FileSystemObject
Dim FileItem As File
Dim wb As Workbook
Dim strRenameValue As String
FolderPath = "N:\MyFolder\"
'Loop Files
For Each FileItem In FSO.GetFolder(FolderPath).Files
Set wb = Workbooks.Open(FileItem.Path)
'Get The Value With Which To Rename The Workbook
strRenameValue = Mid(wb.Sheets(1).Cells(1, 2).Value, 38, 2)
'You shouldn't need to save?
wb.Close False
'Now That The File Is Closed, Rename It
FileItem.Name = strRenameValue
Set wb = Nothing
Next FileItem
End Sub
Since you plan to rename the files, I would suggest that you start by loading all the names into an array before renaming the files, in order to get coherent values from Dir.
I do that using the following function:
Function GetFileList(FileSpec As String) As Variant
' Returns an array of filenames that match FileSpec
' If no matching files are found, it returns False
Dim FileArray() As Variant
Dim FileCount As Integer
Dim FileName As String
On Error GoTo NoFilesFound
FileCount = 0
FileName = Dir(FileSpec)
If FileName = "" Then GoTo NoFilesFound
'Loop until no more matching files are found
Do While FileName <> ""
FileCount = FileCount + 1
ReDim Preserve FileArray(1 To FileCount)
FileArray(FileCount) = FileName
FileName = Dir()
Loop
GetFileList = FileArray
Exit Function
' Error handler
NoFilesFound:
GetFileList = False
End Function
This version uses a separate instance for speed (I did consider using ADO instead).
Also ensures only Excel files are opened and that the new filename is valid (I do assume that you have a valid suffix file type, ie .xlsx in your cell names)
Sub openrenamebook()
Dim xlApp As Excel.Application
Dim FileExtension As String
Dim FilesInFolder As String
Dim FolderPath As String
Dim strRenameValue As String
Dim wb As Workbook
Set xlApp = New Excel.Application
With xlApp
.Visible = False
.ScreenUpdating = False
.DisplayAlerts = False
End With
FileExtension = "*.xls*"
FolderPath = "c:\temp\"
FilesInFolder = Dir(FolderPath & FileExtension)
Do While Len(FilesInFolder) > 0
Set wb = xlApp.Workbooks.Open(FolderPath & FilesInFolder)
On Error Resume Next
strRenameValue = Mid$(wb.Sheets(1).Cells(1, 2).Value, 38, 2)
On Error GoTo 0
wb.Close False
If Len(strRenameValue) > 0 Then Name FolderPath & FilesInFolder As FolderPath & strRenameValue
Set wb = Nothing
FilesInFolder = Dir
Loop
xlApp.Quit
Set xlApp = Nothing
End Sub

VBA code to open all excel files in a folder

I was working with a vba and I'm trying to open all excel files in a folder (about 8-10) based on cell values. I was wondering if this is the right approach to opening it, it keeps giving me syntax error where I wrote the directory. and when I rewrote that section, the vba only shot out the msgbox which meant it had to have looped and did something right? but didn't open any files. Any information will help. Thank you guys so much for taking the time to help me in any way.
Sub OpenFiles()
Dim search As Worksheet
Dim customer As Range
Dim customerfolder As Range
Dim QualityHUB As Workbook
'setting variable references
Set QualityHUB = ThisWorkbook
Set search = Worksheets("Search")
Set customer = Worksheets("Search").Range("$D$1")
Set customerfolder = Worksheets("Search").Range("$D$3")
With QualityHUB
If IsEmpty((customer)) And IsEmpty((customerfolder)) Then
MsgBox "Please Fill out Customer Information and search again"
Exit Sub
End If
End With
With QualityHUB
Dim MyFolder As String
Dim MyFile As String
Dim Directory As String
Directory = "O:\LAYOUT DATA\" & customer & "\" & customerfolder"
MyFile = Dir(Directory & "*.xlsx")
Do While MyFile <> ""
Workbooks.Open Filename:=MyFile
MyFile = Dir()
Loop
MsgBox "Files Open for " + customerfolder + " complete"
End With
End Sub
This worked for me perfectly
Sub OpenFiles()
Dim search As Worksheet
Dim customer As Range
Dim customerfolder As Range
Dim QualityHUB As Workbook
'setting variable references
Set QualityHUB = ThisWorkbook
Set search = Worksheets("Search")
Set customer = Worksheets("Search").Range("$D$1")
Set customerfolder = Worksheets("Search").Range("$D$3")
With QualityHUB
If IsEmpty((customer)) And IsEmpty((customerfolder)) Then
MsgBox "Please Fill out Customer Information and search again"
Exit Sub
End If
End With
With QualityHUB
Dim MyFolder As String
Dim MyFile As String
Dim Directory As String
Directory = "O:\LAYOUT DATA\" & customer & "\" & customerfolder & "\"
MyFile = Dir(Directory & "*.xlsx")
Do While MyFile <> ""
Workbooks.Open Filename:=Directory & MyFile
MyFile = Dir()
Loop
MsgBox "Files Open for " + customerfolder + " complete"
End With
End Sub
one of the issue was, you had to write
Workbooks.Open Filename:=Directory & MyFile
instead of
Workbooks.Open Filename:=MyFile
Corrected some issues with your code and cleaned it up, give this a try. I think the big issue was you had an extra double-quote, and you missing the ending \ in the Directory line:
Sub OpenFiles()
Dim QualityHUB As Workbook
Dim search As Worksheet
Dim customer As String
Dim customerfolder As String
Dim Directory As String
Dim MyFile As String
'setting variable references
Set QualityHUB = ThisWorkbook
Set search = QualityHUB.Worksheets("Search")
customer = search.Range("$D$1").Value
customerfolder = search.Range("$D$3").Value
If Len(Trim(customer)) = 0 Or Len(Trim(customerfolder)) = 0 Then
MsgBox "Please Fill out Customer Information and search again"
Exit Sub
End If
Directory = "O:\LAYOUT DATA\" & customer & "\" & customerfolder & "\" '<--- This requires the ending \
MyFile = Dir(Directory & "*.xlsx")
Do While Len(MyFile) > 0
Workbooks.Open Filename:=Directory & MyFile
MyFile = Dir()
Loop
MsgBox "Files Open for " + customerfolder + " complete"
End Sub
I found this code online and it will open all the excel files in a folder, you can adapt the code to apply a function to the workbook, once it is open.
Option Explicit
Type FoundFileInfo
sPath As String
sName As String
End Type
Sub find()
Dim iFilesNum As Integer
Dim iCount As Integer
Dim recMyFiles() As FoundFileInfo
Dim blFilesFound As Boolean
blFilesFound = FindFiles("G:\LOCATION OF FOLDER HERE\", _
recMyFiles, iFilesNum, "*.xlsx", True)
End Sub
Function FindFiles(ByVal sPath As String, _
ByRef recFoundFiles() As FoundFileInfo, _
ByRef iFilesFound As Integer, _
Optional ByVal sFileSpec As String = "*.*", _
Optional ByVal blIncludeSubFolders As Boolean = False) As Boolean
Dim iCount As Integer '* Multipurpose counter
Dim sFileName As String '* Found file name
Dim wbResults, file, WS_Count, i, gcell, col, finRow, wbCodeBook As Workbook, lCount, name, looper
Dim WorksheetExists
Set wbCodeBook = ThisWorkbook
'*
'* FileSystem objects
Dim oFileSystem As Object, _
oParentFolder As Object, _
oFolder As Object, _
oFile As Object
Set oFileSystem = CreateObject("Scripting.FileSystemObject")
On Error Resume Next
Set oParentFolder = oFileSystem.GetFolder(sPath)
If oParentFolder Is Nothing Then
FindFiles = False
On Error GoTo 0
Set oParentFolder = Nothing
Set oFileSystem = Nothing
Exit Function
End If
sPath = IIf(Right(sPath, 1) = "\", sPath, sPath & "\")
'*
'* Find files
sFileName = Dir(sPath & sFileSpec, vbNormal)
If sFileName <> "" Then
For Each oFile In oParentFolder.Files
If LCase(oFile.name) Like LCase(sFileSpec) Then
iCount = UBound(recFoundFiles)
iCount = iCount + 1
ReDim Preserve recFoundFiles(1 To iCount)
file = sPath & oFile.name
name = oFile.name
End If
On Error GoTo nextfile:
Set wbResults = Workbooks.Open(Filename:=file, UpdateLinks:=0)
''insert your code here
wbResults.Close SaveChanges:=False
nextfile:
Next oFile
Set oFile = Nothing '* Although it is nothing
End If
If blIncludeSubFolders Then
'*
'* Select next sub-forbers
For Each oFolder In oParentFolder.SubFolders
FindFiles oFolder.path, recFoundFiles, iFilesFound, sFileSpec, blIncludeSubFolders
Next
End If
FindFiles = UBound(recFoundFiles) > 0
iFilesFound = UBound(recFoundFiles)
On Error GoTo 0
'*
'* Clean-up
Set oFolder = Nothing '* Although it is nothing
Set oParentFolder = Nothing
Set oFileSystem = Nothing
End Function
Function SSCGetColumnCodeFromIndex(colIndex As Variant) As String
Dim tstr As String
Dim prefixInt As Integer
Dim suffixInt As Integer
prefixInt = Int(colIndex / 26)
suffixInt = colIndex Mod 26
If prefixInt = 0 Then
tstr = ""
Else
prefixInt = prefixInt - 1
tstr = Chr(65 + prefixInt)
End If
tstr = tstr + Chr(65 + suffixInt)
SSCGetColumnCodeFromIndex = tstr
End Function
Function GetColNum(oSheet As Worksheet, name As String)
Dim Endrow_Col, i
'For loop to get the column number of name
Endrow_Col = oSheet.Range("A1").End(xlToRight).Column
oSheet.Select
oSheet.Range("A1").Select
For i = 0 To Endrow_Col - 1 Step 1
If ActiveCell.Value <> name Then
ActiveCell.Offset(0, 1).Select
ElseIf ActiveCell.Value = name Then
GetColNum = ActiveCell.Column
Exit For
End If
Next i
End Function
Function ShDel(name As String)
End If
End Function

Find file and insert path into cell

I have a file name of a pdf that I want to search for in a folder on a shared network drive \\Share\Projects. The pdf will be in one of the subfolders under projects. I then want to return the entire file path of the pdf into a cell (eg \\Share\Projects\Subfolder\Another subfolder\thisone.pdf).
I have started the code but can't figure out how to search a file system:
Sub InsertPath()
Dim PONumber As String
PONumber = InputBox("PO Number:", "PO Number")
'search for order
Dim myFolder As Folder
Dim myFile As File
'This bit doesn't work
Set myFolder = "\\Share\Projects"
For Each myFile In myFolder.Files
If myFile.Name = "PO" & PONumber & ".pdf" Then
'I have absolutely no idea how to do this bit
End If
Next
End Sub
Am I on the right track or is my code completely wrong?
get list of subdirs in vba
slighly modified the above post.
Public Arr() As String
Public Counter As Long
Sub LoopThroughFilePaths()
Dim myArr
Dim i As Long
Dim j As Long
Dim MyFile As String
Const strPath As String = "C:\Personal\" ' change it as per your needs
myArr = GetSubFolders(strPath)
Application.ScreenUpdating = False
Range("A1:B1") = Array("text file", "path")
For j = LBound(Arr) To UBound(Arr)
MyFile = Dir(myArr(j) & "\*.pdf")
Do While Len(MyFile) <> 0
i = i + 1
Cells(i, 1) = MyFile
Cells(i, 2) = myArr(j)
MyFile = Dir
Loop
Next j
Application.ScreenUpdating = True
End Sub
Function GetSubFolders(RootPath As String)
Dim fso As Object
Dim fld As Object
Dim sf As Object
Dim myArr
Set fso = CreateObject("Scripting.FileSystemObject")
Set fld = fso.GetFolder(RootPath)
For Each sf In fld.SUBFOLDERS
Counter = Counter + 1
ReDim Preserve Arr(Counter)
Arr(Counter) = sf.Path
myArr = GetSubFolders(sf.Path)
Next
GetSubFolders = Arr
Set sf = Nothing
Set fld = Nothing
Set fso = Nothing
End Function
Well, your folder declaration isn't set against a filesystemobject so it can't find the folder. And because it's a network location, you may need to map a network drive first so that it's a secure link.
So here's an updated version of your code.
EDIT - to OP's conditions.
Dim PONumber As String
Sub InsertPath()
PONumber = InputBox("PO Number:", "PO Number")
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Dim Servershare As String
ServerShare = "S:\"
Dim Directory As Object
Set Directory = fso.GetFolder(ServerShare)
Subfolderstructure Directory
End Sub
Function Subfolderstructure(Directory As Object)
For Each oFldr in Directory.SubFolders
For Each FileName In oFldr.Files
If FileName.Name = "PO" & PONumber & ".pdf" Then
sheets("Sheet1").range("A1").value = ServerShare & "\PO" & PONumber & ".pdf"
Exit For
End If
Next
Dim sbfldrs : Set sbfldrs = ofldr.SubFolders
If isarray(sbfldrs) then
Subfolderstructure ofldr
End if
Next
'Cleanup
Set FileName = Nothing
Set Directory = Nothing
Set fso = Nothing
End Function
I have not tested this code. Try it out and let me know how it works.