Versions Compared

Key

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

...

Code Block
languagevb
Sub ConceptSauce_ImageMatchHelper_Debug()
    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
    Dim moveFiles As Boolean
    Dim lastSearchFolder As String
    Dim lastCopyFolder As String
    Dim debugOutput As String

    ' Set default folder paths from named ranges, if available
    On Error Resume Next
    lastSearchFolder = ThisWorkbook.Names("LastSearchFolder").RefersToRange.Value
    lastCopyFolder = ThisWorkbook.Names("LastCopyFolder").RefersToRange.Value
    On Error GoTo 0

    ' Prompt user for the folder
    With Application.FileDialog(msoFileDialogFolderPicker)
        .Title = "Select a Folder to Search"
        .InitialFileName = lastSearchFolder
        .AllowMultiSelect = False
        If .Show = -1 Then
            folderPath = .SelectedItems(1)
            ' Save the selected folder path
            SetNamedRange "LastSearchFolder", folderPath
        Else
            Exit Sub
        End If
    End With

    ' Create filesystem object
    Set fso = New Scripting.FileSystemObject

    ' Create a dictionary to store file paths by base filename
    Set filenamesDict = CreateObject("Scripting.Dictionary")
    AddFilesRecursively fso.GetFolder(folderPath), filenamesDict

    ' Get the active worksheet
    Set ws = ThisWorkbook.ActiveSheet

    ' Ask user to select the 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
    If rng Is Nothing Or rng.Cells.Count = 0 Then Exit Sub

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

    ' Ask the user if they want to copy or move the found files
    response = MsgBox("Do you want to copy or move the found files to a new folder?" & vbCrLf & _
                      "Yes = Copy, No = Move, Cancel = Exit", vbYesNovbYesNoCancel + vbQuestion, "CopyFile FilesOperation")
    If response = vbYesvbCancel Then Exit Sub
    moveFiles = (response = vbNo)

    ' Prompt for destination folder and set initial path
        With Application.FileDialog(msoFileDialogFolderPicker)
  
         .Title = "Select a Destination Folder"
   
        .InitialFileName = lastCopyFolder
            .AllowMultiSelect = False
            If .Show = -1 Then
   
            destFolderPath = .SelectedItems(1)

               ' Save the destination folder path
                SetNamedRange "LastCopyFolder", destFolderPath
   
        Else
 
              Exit Sub
        End If
  End If End With

    ' EndInitialize Withdebugging output
    debugOutput = "Debug Output:" '& CopyvbCrLf
matched
files, ensuring only unique paths' areMove addedor copy matched files
     Dim copiedFilesDictprocessedFilesDict As Object
        Set copiedFilesDictprocessedFilesDict = CreateObject("Scripting.Dictionary")
        Dim filePath As Variant
        For Each cell In rng.Cells
  
         baseFilename = Trim(CStr(Trim(cell.Value)) ' Trim spaces
         If filenamesDict.exists(baseFilename) Then
                For Each filePath In filenamesDict(baseFilename)
                If Not processedFilesDict.exists(filePath) Then
                    debugOutput = debugOutput & "Matched File: " & filePath & vbCrLf
                  If Not copiedFilesDict.exists(filePath) Then  If fso.FileExists(filePath) Then ' Ensure the file exists
                        If moveFiles Then
                            debugOutput = debugOutput & "Moving to: " & destFolderPath & "\" & fso.GetFileName(filePath) & vbCrLf
                            fso.MoveFile filePath, destFolderPath & "\" & fso.GetFileName(filePath)
                        Else
                            debugOutput = debugOutput & "Copying to: " & destFolderPath & "\" & fso.GetFileName(filePath) & vbCrLf
                            fso.CopyFile filePath, destFolderPath & "\" & fso.GetFileName(filePath), True
                         copiedFilesDictEnd If
                        processedFilesDict.Add filePath, True
                    Else
                        debugOutput = debugOutput & "File not found: " & filePath & vbCrLf
                    End If
                End If
            Next filePath
        Else
            debugOutput = debugOutput & "No match for: " & baseFilename & vbCrLf
        End If
    Next cell

    ' Output debugging information
    ' Debug.Print debugOutput
  Next cell ' MsgBox debugOutput, vbInformation, End"Debugging IfInformation"

    MsgBox "Process complete!", vbInformation, "Done"
End Sub

' Optimized recursive subroutine to add files from folder and subfolders
Sub AddFilesRecursively(folder As Scripting.folder, filenamesDict As Object)
    Dim fileObj As Scripting.File
    Dim subfolder As Scripting.folder
    Dim baseFilename As String

    For Each fileObj In folder.Files
        If InStr(fileObj.Name, ".jpg") > 0 Or InStr(fileObj.Name, ".png") > 0 Then
            baseFilename = Trim(Split(fileObj.Name, "_.")(0)) ' Trim spaces from base filename
            If Not filenamesDict.exists(baseFilename) Then
                Set filenamesDict(baseFilename) = New Collection
            End If
            filenamesDict(baseFilename).Add fileObj.Path
        End If
    Next fileObj

    For Each subfolder In folder.Subfolders
        AddFilesRecursively subfolder, filenamesDict
    Next subfolder
End Sub

' Helper function for partial matches
Function PartialMatchExists(baseFilename As String, filenamesDict As Object) As Boolean
    Dim key As Variant
    PartialMatchExists = False
    For Each key In filenamesDict.Keys
        If Left(key, Len(baseFilename)) = baseFilename Then
            PartialMatchExists = True
            Exit Function
        End If
    Next key
End Function

' Function to set or update a named range with folder path
Sub SetNamedRange(rangeName As String, folderPath As String)
    On Error Resume Next
    ' Ensure the range is valid by wrapping the folderPath as a valid Excel string literal
    ThisWorkbook.Names.Add Name:=rangeName, RefersTo:="='""" & folderPath & ""'""
    On Error GoTo 0
End Sub

...