Excel VBA Course
Excel VBA Course - From Beginner to Expert

200+ Video Lessons
50+ Hours of Video
200+ Excel Guides

Become a master of VBA and Macros in Excel and learn how to automate all of your tasks in Excel with this online course. (No VBA experience required.)

View Course

expanding code to populate files names within subfolders

0

Hi,

I have this code 

Sub MorshedDhaka()
   Dim Fldr As String, Fname As String
   Dim ObjFldr As Object
   Dim i As Long
   i = 1
   Set ObjFldr = Application.FileDialog(4)
   With ObjFldr
      .Title = "Choose a folder"
      .AllowMultiSelect = False
      If .Show = -1 Then Fldr = .SelectedItems(1)
   End With
   If Fldr = "" Then Exit Sub
   Fname = Dir(Fldr & "\*")
   Do While Fname <> ""
      i = i + 1
      Cells(i, 2) = Split(Fname, ".")(0)
      Fname = Dir()
   Loop
End Sub

I would expand code deals with files in subfolders by exatraction all of files when select folder .

the files in subfolders could be like this

C:\Users\KLL\Desktop\KM\asss.xlsm

C:\Users\KLL\Desktop\KM\rrp\fl.xls

C:\Users\KLL\Desktop\KM\rrp\data\123.xlsx

thanks

Answer
Discuss

Answers

0
Selected Answer

Hi again Kalil

In the attached revised file, you'll see:

  1. column B is headed "File name (without extension)"
  2. column C is headed "Full path and full filename" - this it to show where the file in column B is located within the directory structure
  3. a blue button in column A, ;labelled "List files in all subfolders".

Clicking that button will run the revised code below, where:

  1. changes and comments are in bold
  2. some of your code is moved to a Function (see below)
  3. to search subfolders, I use the FileSystemObject object (in the variable objFSO)
  4. your variable i is declared before this routine (so it's value isn't lost when the Function is called). 
Dim i As Long
Sub MorshedDhaka()
    Dim Fldr As String, Fname As String
    Dim objFldr As Object
    Dim objSubFldr As Object

    i = 1
    Set objFldr = Application.FileDialog(4)
    With objFldr
       .Title = "Choose a folder"
       .AllowMultiSelect = False
       If .Show = -1 Then Fldr = .SelectedItems(1)
    End With
    If Fldr = "" Then Exit Sub

    ' enable use of FSO
     Set objFSO = CreateObject("Scripting.FileSystemObject")

    ' clear any previous results (shrinking file size)
    ActiveSheet.UsedRange.Offset(1, 0).EntireRow.Delete

    Set objFldr = objFSO.GetFolder(Fldr)

    ' call function
    LoopEachFolder objFldr

    ' quit FSO
    Set objFSO = Nothing

    ' fit results and tell user
    Columns("B:C").AutoFit
    MsgBox "Done! Listed " & i - 1 & " files"
End Sub

After the user picks a folder, the code clears any existing results then this line:

    LoopEachFolder objFldr

calls the new Function below (in the same Module) and passes the folder to it:

Function LoopEachFolder(fldFolder As Object)

    Dim objFldLoop As Object

    Fname = Dir(fldFolder & "\")

    ' List files in this folder
    Do While Fname <> ""
        i = i + 1
        'write full path in column C
        Cells(i, 3) = fldFolder.Path & "\" & Fname
        'write filename (without extension) in column B
        Cells(i, 2) = Split(Fname, ".")(0)
        ' get next file (if any)
        Fname = Dir()
    Loop

    ' With the subfolders in this folder....
    For Each objFldLoop In fldFolder.subFolders
        '  run this function on each subfolder found
        LoopEachFolder objFldLoop

    Next objFldLoop

End Function

The crucial bit is the loop near the end- this finds any sub-folders and calls on the function itself again (and iteratively until all levels of folders have been searched).

The last lines of your revised code tidy up the results and tell the user how many files it found.

Now you'll get the file names in column B (asd before) and C will tell you exactly where those files are.

Hope this works well for you (and you remember to mark this Answer as Selected if it does!)

Discuss

Discussion

@John

Nice work John. I had the code for the first level of subfolders worked out but the recursive code for sub\sub\sub\ etc folders was tripping me up. I'm sure this is what Kalil is looking for.

Cheers   :-)
WillieD24 (rep: 687) May 5, '25 at 11:19 am
@Willie - thanks. Actually I kept as much of Kalil's code as i could ( it could have been a little simpler otherwise).
John_Ru (rep: 6722) May 5, '25 at 12:35 pm
well done John!
thank you so much.
Kalil (rep: 44) May 6, '25 at 3:28 am
Thanks for selecting my Answer, Kalil. 
John_Ru (rep: 6722) May 6, '25 at 5:49 am
Hi john,
I note the code doesn't show whole number format like this 1,000.00
the cod shows 1,000
I try adding this line
Columns("B").NumberFormat = "#,##0.00"

but doesn't work!
any ideas ,please?
Kalil (rep: 44) May 7, '25 at 6:33 am
Hi Kalil 

I'm confused - this code is about file names and locations (which are text strings). Where do the numbers come from?
John_Ru (rep: 6722) May 7, '25 at 2:36 pm
I have file names within folders and subfolders like this 
INVOICE 1,000.00
12,000.00
should populate whole files names , but the code delete the last two zero .00 for files names contains amounts with numberformat !
Kalil (rep: 44) May 8, '25 at 3:35 am
Kalil 

In Windows, it's generally recommended NOT to include the period mark (.) in filenames. That's because it is used separate the filename from the file extension, which indicates the file type.

In fact I used your original code:
Cells(i, 2) = Split(Fname, ".")(0)

which removes everything after the first period mark.

For example that line would change FName of "INVOICE 1,000.00.xls" into a value "INVOICE 1,000" (so it's not my coding changes which caused that problem!).

You could try this line instead:
Cells(i, 2) = Left(Fname, InstrRev(Fname, ".")-1)

where the last bit in bold determines the position of the last period mark in the filename Fname.

For FName of "INVOICE 1,000.00.xls", this will give "INVOICE 1,000.00".

John_Ru (rep: 6722) May 8, '25 at 6:49 am
BTW if you used my Answer code, column C would still show the full filename (after the path)
John_Ru (rep: 6722) May 8, '25 at 7:02 am
You could try this line instead:
Select All
Cells(i, 2) = Left(Fname, InstrRev(Fname, ".")-1)
it works well. thanks gain for your help
Kalil (rep: 44) May 8, '25 at 1:49 pm
Add to Discussion


Answer the Question

You must create an account to use the forum. Create an Account or Login