Excel VBA For-Loop skipping some files, but not others - excel

I'm running an Excel VBA macro. It includes the following code:
Private Sub ListTheFiles(inFldr as Scripting.Folder)
Dim fl as Scripting.File, subfldr as Scripting.Folder
If inFldr.Files.Count > 0 then
For Each fl in inFldr.Files
'List the file and its size and LastModifiedDate on a worksheet, making no changes to the file
Next fl
End If
For Each subfldr in inFldr.Subfolders
ListTheFiles subfldr
Next subfldr
End Sub
The module runs this subroutine hundreds of times, usually successfully. But for just a couple of folders, it reaches the first "For Each" (which indicates there ARE files in inFldr), but then it skips right to the "End If" without processing any files. The two folders that don't get processed each contains 12 PDF files and no other files and no subfolders. Many of the other folders also contain PDF files only, and they work fine.
Why would this happen? Thanks.

List Files in a Folder and in Its Subfolders
I am using this without a reference to the Scripting FileSystemObject object. As you can see, the 'recursion' code is 'basically' the same (except for the .Count). You could test it, to see if the issue repeats itself.
The Code
Option Explicit
Sub FilesRecurseTEST()
Const FolderPath As String = "F:\Test\2021"
Dim fso As Object: Set fso = CreateObject("Scripting.FileSystemObject")
FilesRecurse fso.GetFolder(FolderPath)
End Sub
Sub FilesRecurse( _
fsoFolder As Object)
Dim fsoSubFolder As Object, fsoFile As Object
For Each fsoFile In fsoFolder.Files
With fsoFile
Debug.Print .Name, .Size, .DateLastModified
End With
Next fsoFile
For Each fsoSubFolder In fsoFolder.Subfolders
FilesRecurse fsoSubFolder
Next
End Sub

Related

Traverse zip file using VBA

I need to traverse a zip files using VBA. In particular I need to, without unzipping the file, locate the xl folder in order to find the media subfolder. I then need to copy the images out of the media subfolder and save them to another folder.
Public Sub Extract_Images()
Dim fso As FileSystemObject
Dim objFile As File
Dim myFolder
Const zipDir As String = "\\...\ZIP FILES"
Const xlFolder As String = "xl"
Const mediaFolder As String = "media"
Dim picname As String
Dim zipname As String
Set fso = New FileSystemObject
Set myFolder = fso.GetFolder(zipDir)
For Each objFile In myFolder.Files
zipname = objFile.Name
Next objFile
End Sub
^That code successfully loops through the folder and gathers the names of the zip files. But I need to get into the files and traverse the structures to get to the Media folder.
Building off: https://www.rondebruin.nl/win/s7/win002.htm
Edit: - this shows how you can incorporate the extraction into your code. Just pass the full zip path and the location to where you want to extract the files. You can do this from within your existing loop.
You may need to account for media files sharing the same name if you're planning on extracting them all to the same location...
Sub Tester()
ExtractMediaFiles "C:\Users\twilliams\Desktop\tempo.zip", _
"C:\Users\twilliams\Desktop\extracted\"
End Sub
Sub ExtractMediaFiles(zipFile As Variant, outFolder As Variant)
Dim oApp As Object
Dim fileNameInZip As Variant, oNS As Object
Set oApp = CreateObject("Shell.Application")
On Error Resume Next
Set oNS = oApp.Namespace(zipFile & "\xl\media")
On Error GoTo 0
If Not oNS Is Nothing Then
For Each fileNameInZip In oNS.items
Debug.Print fileNameInZip
oApp.Namespace(outFolder).copyhere oNS.items.Item(CStr(fileNameInZip))
Next
Else
Debug.Print "No xl\media path for " & zipFile
End If
End Sub

Excel file directory grabber

Currently I have a workbook designed to index a folder, where you enter in a folder path e.g. 'Z:\Example' and it exports all the file names and file paths for everything in that particular folder, into another sheet within the workbook. I was wondering if it would be possible to grab all the files within that folder ('Z:\Example') and if there was any other folders inside that directory, also grab all the files within that folder too.
E.g. I enter 'Z:\Example' into cell A19 (as per the code below),
'Z:\Example' has another folder in it, Z:\Example\Another'. All files
within both 'Z:\Example' and Z:\Example\Another' get brought into
excel sheet 2.
Private Sub CommandButton1_Click()
Dim objFSO As Object
Dim objFolder As Object
Dim objFile As Object
Dim i As Integer
Dim Source_Workbook As Workbook
Dim Target_Path As String
'Create an instance of the FileSystemObject
Set objFSO = CreateObject("Scripting.FileSystemObject")
'Path of the Target Folder
Target_Path = Range("A19").Value
Set Target_Workbook = Workbooks.Open(Target_Path)
Set Source_Workbook = ThisWorkbook
'Get the folder object
Set objFolder = objFSO.GetFolder(Target_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
Source_Workbook.Sheets(2).Cells(i + 1, 1) = objFile.Name
'print file path
Source_Workbook.Sheets(2).Cells(i + 1, 2) = objFile.Path
i = i + 1
Next objFile
'Process Completed
msgBox "Task Completed"
End Sub
I would prefer to not have to insert all paths that I want indexed at the beginning but if that is unavoidable it is okay. Any help appreciated.
Thanks
As In the comments, there are many resources to list a folder and its subfolders. This snippet is customized to your application. It uses recursion and needs to be fed the root folder and the target cell where to paste the results.
Private Sub CommandButton1_Click()
'Call the recursive function
ListAllFiles ThisWorkbook.Sheets(1).Range("A19").Value, ThisWorkbook.Sheets(2).Cells(2, 1)
msgBox "Task Completed"
End Sub
Private Sub ListAllFiles(root As String, targetCell As Range)
Dim objFSO As Object, objFolder As Object, objSubfolder As Object, objFile As Object
Dim i As Integer, Target_Path As String
'Create an instance of the FileSystemObject
Set objFSO = CreateObject("Scripting.FileSystemObject")
'Get the folder object
Set objFolder = objFSO.GetFolder(root)
'loops through each file in the directory and prints their names and path
For Each objFile In objFolder.Files
'print file name
targetCell.Value = objFile.Name
'print file path
targetCell.Offset(, 1).Value = objFile.Path
Set targetCell = targetCell.Offset(1)
Next objFile
' Recursively call the function for subfolders
For Each objSubfolder In objFolder.SubFolders
ListAllFiles objSubfolder.Path, targetCell
Next objSubfolder
End Sub

Looping through different kinds of files in folder (VBA)

I have a question regarding looping through a folder of two different kinds of files: xlsm and mdb (Access).
I have currently written a macro that would open 1 single xlsm file and 1 single mdb file before copying some data from the xlsm to mdb file and then saving the mdb file.
Now, I would like this process to repeat through a folder that has 50 xlsm files and 50 mdb files. They have the same names, so for example the loop should do this:
Open both xlsm and mdb files called "2001".
Perform copying and pasting etc from xlsm to mdb (I have written this part).
Save the mdb file.
Close both xlsm and mdb files called "2001".
Repeat steps 1-4 for "2002", "2003", etc in the folder.
I am really new to VBA so much help is appreciated! Looking forward to any guidance at all. Merry Christmas!
I just did today sample code for listing JPG files in folder, you can adopt and modify to do exactly what you like it to do, but would be very hard to give you exact code without being able to see your solution.
Public Sub listImages(folderPath As String)
'define variables
Dim fso As Object
Dim objFolder As Object
Dim objFolders As Object
Dim objF As Object
Dim objFile As Object
Dim objFiles As Object
Dim strFileName As String
Dim strFilePath As String
Dim myList As String
'set file system object
Set fso = CreateObject("Scripting.FileSystemObject")
'set folder object
Set objFolder = fso.GetFolder(folderPath)
'set files
Set objFiles = objFolder.files
Set objFolders = objFolder.subfolders
'list all images in folder
For Each objFile In objFiles
If Right(objFile.Name, 4) = ".jpg" Then
strFileName = objFile.Name
strFilePath = objFile.Path
myList = myList & strFileName & " - " & strFilePath & vbNewLine
End If
Next
'go through all subflders
For Each objF In objFolders
Call listImages(objF.Path)
Next
Debug.Print myList
Set objFolder = Nothing
Set objFile = Nothing
Set fso = Nothing
End Sub

VBA search subfolders of a folder

I am trying to find a way using Access 2003 (Yes I know this is ancient), to search all the sub directories of a folder to determine if a file exists. If it is found it needs to be entered into a sub that turns a button on or off. I would also like to be able to save the path as I would need this button to link to a file. So as a brief explanation, using Access I would like to search a folder a drive which has sub folders which each has their own sub folders. I found many websites, including the following one, but none of the answers seems to work.
Loop Through All Subfolders Using VBA
Any help will be appreciated.
`Dim FileSystem As Object
Dim HostFolder As String
HostFolder = "C:\"
Set FileSystem = CreateObject("Scripting.FileSystemObject")
DoFolder FileSystem.GetFolder(HostFolder)
Sub DoFolder(Folder)
Dim SubFolder
For Each SubFolder In Folder.SubFolders
DoFolder SubFolder
Next
Dim File
For Each File In Folder.Files
' Operate on each file
Next
End Sub`
Gives me an invalid procedure and says the error is in the host folder I used. However, it is the same one I have used for my other codes samples with no problems.
Public Sub NonRecursiveMethod()
Dim fso, oFolder, oSubfolder, oFile, queue As Collection
Set fso = CreateObject("Scripting.FileSystemObject")
Set queue = New Collection
queue.Add fso.GetFolder("your folder path variable") 'obviously replace
Do While queue.Count > 0
Set oFolder = queue(1)
queue.Remove 1 'dequeue
'...insert any folder processing code here...
For Each oSubfolder In oFolder.SubFolders
queue.Add oSubfolder 'enqueue
Next oSubfolder
For Each oFile In oFolder.Files
'...insert any file processing code here...
Next oFile
Loop
End Sub
Gives me an error because the last next isn't in a for loop according to Access VBA.
I found another code that I was able to get working. It is from the website
http://www.ammara.com/access_image_faq/recursive_folder_search.html
However, this is extremely slow. Takes 30 seconds to run yet, when everything was in a single folder, a simple dir check would be instantaneous. Thanks to those who offered some help.

code to loop through all workbooks in a folder VB

I have a number of excel (.xls) stored in a folder in a local drive. I need to do some process to every file in this folder. What is the code that will
loop through every file
open the file
Do some processing and then Save & close the file
move the file to another folder after processing
To be more clear, I want go over every file and do processing to it. After finishing a file, go to another file and so till the end of all the files in the folder. I do have the code for the processing; I just need to know the code that will loop through the files and move then to another folder.
Thanks for your help in advance,
What you need is a recursive function that iterates over the tree that represents a file system. It means to iterate over all the childs of some 'parent folder'. I send you a function that does something similar, to the one you need (this is currently in usage). This function deletes all the empty folders given a parent folder.
Public Function gf_DeleteEmptyFolder(path As String) As Boolean
On Error GoTo Error_Handler
Dim fso_folder As Scripting.Folder, sub_folder As Scripting.Folder
If g_FSO.FolderExists(path) Then
Set fso_folder = g_FSO.GetFolder(path)
'-- eliminates de folder only if is empty
If 0 = fso_folder.Files.Count And 0 = fso_folder.SubFolders.Count Then
Call g_FSO.DeleteFolder(path, False)
'-- recursively calls the function
Else
For Each sub_folder In fso_folder.SubFolders
Call gf_DeleteEmptyFolder(sub_folder.path)
Next
End If
End If
gf_DeleteEmptyFolder = True
Exit Function
'~~~ on error
Error_Handler:
gf_DeleteEmptyFolder = False
End Function
If your files are stored in a simple folder, then you can use the following code to iterate each file.
Public Sub fsoProcessFilesInFolder(sFolder As String)
Dim fso As Scripting.FileSystemObject, fld As Scripting.Folder, fil As Scripting.File
Set fso = New FileSystemObject
Set fld = fso.GetFolder(sFolder)
For Each fil In fld.Files
'--- add code to process your files
Next fil
End Sub
Here's the easy VBA object way to do it:
Dim fs As FileSearch
Dim i As Integer
Dim wbk As Workbook
Set fs = Application.FileSearch
With fs
.LookIn = ThisWorkbook.Path
.FileName = "*.xls"
For i = 1 to .Execute()
Set wbk = Workbooks.Open(.FoundFiles(i))
''//DO STUFF HERE
wbk.Close(SaveChanges:=True)
Next i
End With
In VB6 you have three options, as shown in the following KB articles:
How to Search Directories to Find or List Files
HOW TO: Recursively Search Directories by Using FileSystemObject
The following code will read xlsx/xls files from given folder neglecting other files and iterate through each item.
You can use it for any set of extensions and filters.
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(folderPath)
Set objFiles = objFolder.Files
'Iterate through the files in the folder
For Each Item In objFiles
If LCase(Right(Item.Name, 5)) = ".xls" Or LCase(Right(Item.Name, 4)) = ".xlsx" Then
''''''Do Stuffs Here''''''
End If
Next

Resources