Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
languagevb
Sub ConceptSauce_ImageMatchHelper()
    Dim folderPath As String
    Dim destFolderPath As String
    Dim ws As Worksheet
    Dim rng As Range
    Dim cell As Range
    Dim fso As Scripting.FileSystemObject
    Dim filenamesDict As Object
    Dim baseFilename As String
    Dim response As VbMsgBoxResult

    ' Create aDictionary dictionary to store collections of file paths, indexed by base filenamesfilename
    Set filenamesDict = CreateObject("Scripting.Dictionary")

    ' Prompt user for the folder
    With Application.FileDialog(msoFileDialogFolderPicker)
        .Title = "Select a Folder"
        .AllowMultiSelect = False
        If .Show = -1 Then
            folderPath = .SelectedItems(1)
        Else
            Exit Sub
        End If
    End With

    ' Create filesystem object (early binding for performance)
    Set fso = New Scripting.FileSystemObject

    ' Recursively add filenames from thecollect files by base filename in main folder and subfolders
to the dictionary  AddFilesToDictionary   AddFilesRecursively fso.GetFolder(folderPath), filenamesDict

    ' Get the active worksheet
    Set ws = ThisWorkbook.ActiveSheet

    ' AskPrompt user to select therange
column to match     On Error Resume Next
    Set rng = Application.InputBox("Select a range", "Select cells with filenames to match", Type:=8)
    On Error GoTo 0

    ' Exit if the range is not valid or has no cellsno valid range
    If rng Is Nothing Or rng.Cells.Count = 0 Then Exit Sub

    ' Color-code cells based on partial filename matches
    For Each cell In rng.Cells
        baseFilename = CStr(Trim(cell.Value))
        If PartialMatchExists(baseFilename, filenamesDict) Then
            cell.Interior.Color = RGB(0, 255, 0) ' Green for matched
        Else
            cell.Interior.Color = RGB(255, 0, 0) ' Red for unmatched
        End If
    Next cell

    ' AskPrompt the user if they want to copy the found files
    response = MsgBox("Do you want to copy the found files to a new folder?", vbYesNo + vbQuestion, "Copy Files")
    If response = vbYes Then
        With Application.FileDialog(msoFileDialogFolderPicker)
            .Title = "Select a Destination Folder"
            .AllowMultiSelect = False
            If .Show = -1 Then
                destFolderPath = .SelectedItems(1)
            Else
                Exit Sub
            End If
        End With

        ' Copy matched files thatto partiallydestination match thefolder
cell value without duplicating         Dim copiedFilesDict As Object
        Set copiedFilesDict = CreateObject("Scripting.Dictionary")

        For Each cell In rng.Cells
            baseFilename = CStr(Trim(cell.Value))
            If PartialMatchExists(baseFilename, filenamesDict) Then
                Dim matchedFiles As Collection
                Set matchedFiles = filenamesDict(baseFilename)
                Dim filePath As Variant
                For Each filePath In matchedFiles
                
   ' Check if the file has already been copied                     If Not copiedFilesDict.exists(filePath) Then
                        fso.CopyFile filePath, destFolderPath & "\" & fso.GetFileName(filePath), True
                        copiedFilesDict.Add filePath, True
                    End If
                Next filePath
            End If
        Next cell
    End If

    ' Inform the user that the process is complete
    MsgBox "Process complete!", vbInformation, "Done"
End Sub

' OptimizedCollect files recursivein subroutinethe tofolder addand filessubfolders, fromindexed folderby andbase subfoldersfilenames
Sub AddFilesRecursivelyAddFilesToDictionary(folder As Scripting.folder, filenamesDict As Object)
    Dim fileObj As Scripting.File
    Dim subfolder As Scripting.folder
    Dim baseFilename As String

    ' Add files from the
current
folder to the dictionary     For Each fileObj In folder.Files
        ' Optional: Add file extension filter here (e.g., only add .jpg files)
        If InStr(fileObj.Name, ".jpg") > 0 Or InStr(fileObj.Name, ".png") > 0 Then
            baseFilename = Split(fileObj.Name, "_")(0) ' AdjustedBase tofilename matchwithout filenamessuffix
with suffixes             If Not filenamesDict.exists(baseFilename) Then
 
              Set filenamesDict(baseFilename) = New Collection
            End If
   
        filenamesDict(baseFilename).Add fileObj.Path
        End
If     Next fileObj

 

 ' Process each subfolder recursively
    For Each subfolder In folder.Subfolders
        AddFilesRecursivelyAddFilesToDictionary subfolder, filenamesDict
    Next subfolder
End Sub

' HelperCheck functionif toany checkfile for partialpartially matches and populate the dictionarybase withfilename
matches
Function PartialMatchExists(baseFilename As String, filenamesDict As Object) As Boolean
    Dim key As Variant
    Dim matchedFiles As Collection
    Set matchedFiles = New Collection
    PartialMatchExists = False
    For Each key In filenamesDict.Keys
        ' Check if key starts with baseFilename
        If Left(key, Len(baseFilename)) = baseFilename Then
            ' Collect matching file paths
            Dim filePath As Variant
      If filenamesDict.exists(baseFilename) Then
     For Each filePath In filenamesDict(key)
                matchedFiles.Add filePath
            Next filePath
            ' Return true if any match is found
            PartialMatchExists = True
    Else
       ' Store matched file paths in the dictionary under the baseFilename
            Set filenamesDict(baseFilename) = matchedFiles
   PartialMatchExists = False
     End If
    Next key
End Function
  1. Close the VBA editor and return to your Excel workbook.

  2. To run the macro, press Alt + F8 to open the "Macro" dialog, select "CheckFileNames," and click "Run."

...