VBA for searching photos in a folder and concatenating filenames without duplicating

Asked

Viewed 177 times

4

In February I asked for help in a code to group photo names I have in a folder (product photos) belonging to the same product, such as can be seen in this other question. My problem has been solved, but I need an adjustment to the code that I will explain.

Everything works perfectly if the names don’t match but if for example I have the photos:

Product

Production_4200a.jpg

Product

Product

Production_42001a.jpg

Production_42001b.jpg

when I run the code it joins all these references in the same cell as if it were just a reference...

Product_4200 (6 photos)

Production_4200.jpg, Product_4200a.jpg, Product_42000.jpg, Product_42001.jpg, Product_42001a.jpg, Product_42001b.jpg

... and not 3 different products:

Product_4200 (2 photos)

Production_4200.jpg, Product_4200a.jpg

Product_42000 (1 photo)

Product

Product_42001 (3 photos)

Production_42001.jpg, Product_42001a.jpg, Product_42001b.jpg

Can you help me? I hope I haven’t been too confused in my explanation. The code I have is this::

------------------ Codigo (Paulo Balbino)-----------------------------

        Sub GetJPGandPNGandJPEG()

Dim Path As String
Dim FileName As String
Dim LastDot As Long
Dim FileNameAux As String
Dim FileNameConc As String
Dim LastRow As Long

Path = "C:\Temp\Imagens\"
FileName = Dir(Path & "*.*p*g")

Do While Len(FileName)
  LastDot = InStrRev(FileName, ".")
  If LCase(Mid(FileName, LastDot)) = ".jpg" Or LCase(Mid(FileName, LastDot)) = ".png"  Or LCase(Mid(FileName, LastDot)) = ".jpeg" Then
    If (FileNameAux = vbNullString) Then
      FileNameAux = Replace(FileName, LCase(Mid(FileName, LastDot)), "")
    End If

    If (InStr(1, FileName, FileNameAux, vbTextCompare)) Then
      If (FileNameConc = vbNullString) Then
      FileNameConc = FileName
    Else
      FileNameConc = FileNameConc & ", " & FileName
    End If
  Else
    If (FileNameConc = vbNullString) Then
      FileNameConc = FileName
    End If
    LastRow = Plan1.Cells(Plan1.Rows.Count, 1).End(xlUp).Row + 1
    Plan1.Cells(LastRow, 1) = FileNameConc
    FileNameAux = Replace(FileName, LCase(Mid(FileName, LastDot)), "")
    FileNameConc = FileName
  End If
End If
FileName = Dir
Loop
LastRow = Plan1.Cells(Plan1.Rows.Count, 1).End(xlUp).Row + 1
Plan1.Cells(LastRow, 1) = FileNameConc
End Sub

---------------------------------------------------------------------

Thanks in advance for all the help possible.

  • Hello Francisco! Very cool your question! I think a good option would be to check the last digit to see if it is letter or number. From what I understand the code of the photo is repeated (for the same product) in letters (a, b, c, d, etc.) correct? If you have a number (0, 1, 2 etc.) it would be a new product, yes? I can help with the code, but it is not difficult to test the last character. In case I can’t solve tomorrow put the code for you! Ok? Abs

  • Hello Evert, thank you for your interest. If it is a number it will be a new product. If you can help me with this last character test, I’d appreciate it, but would it be using the "If Isnumeric... Then" function? My problem is to fit this all together without ruining the code that they kindly passed me. : ) Thanks again, Abs - Francisco

  • Francisco, I was able to do the test if it is number, but it didn’t work perfectly, because when Excel (Windows) searches the files in the folder, it comes in alphabetical order, being the numbers before the letters, which does not meet the code above, which was very well written by the way. I explain: are the files 'P_4200', 'P_4200a' and 'P_42000', this would be the ideal order, but Excel brings me 'P_4200', 'P_42000' and 'P_4200a'... =( anyway... I tried to make some adjustments and extra functions, but I think it will be easier to make a new code... I will try and put here as soon as I can. Okay? Sorry for the delay! =)

  • Okay Evert... thank you very much... :)

  • Hello. I edited the question to replace the reproduction of the content with the link of the previous question. It is more readable for everyone. I also took the thanks. It is that this site is not a forum, so they are not really necessary. By the way, if you haven’t done it yet, please do the [tour]. Good luck! :)

  • Hi again. rs So I’m very glad that your problem has been solved. However, know that the best way for you to thank @Evert for his help is by accepting his response (by clicking on the "v" next to the votes) and even by voting positively for it. :)

Show 1 more comment

1 answer

1

In addition to the function presented (very well written by the way), I changed some codes and created other functions to facilitate reading and improve performance, performing the necessary tests as requested. Goes below:

Option Explicit

Sub GetJPGandPNGandJPEG()

Dim Path As String
Dim FileName As String
Dim LastDot As Long
Dim LastRow As Long
Dim Count As Integer
Dim FileAddress As String
Dim FileNameAux As String


    ' Busca os dados
    Path = "C:\temp\imagens\"
    FileName = Dir(Path & "*.*p*g")
    Count = 1

    ' Verifica variável com os dados na pasta especificada
    Do While Len(FileName)

        LastDot = InStrRev(FileName, ".")

        ' Verifica se são fotos com as seguintes extensões: jpg, png, jpeg
        If LCase(Mid(FileName, LastDot)) = ".jpg" Or LCase(Mid(FileName, LastDot)) = ".png" Or LCase(Mid(FileName, LastDot)) = ".jpeg" Then

            FileNameAux = LCase(FileName)

            If (IsNumeric(Right(Replace(FileNameAux, LCase(Mid(FileNameAux, LastDot)), ""), 1))) And Count > 1 Then

                writeToCell FileName

            Else
                FileNameAux = Mid(FileName, 1, LastDot - 2)
                FileAddress = CheckIfExist(FileNameAux)

                If FileAddress <> "" Then
                    writeToCell FileName, FileAddress
                Else
                    writeToCell FileName
                End If
            End If

        End If
        FileName = Dir
        Count = Count + 1
    Loop
End Sub

Sub writeToCell(FileName As String, Optional ENDERECO As String)
'
' Verifica se foi passado um endereço e escreve os dados na célula
'
Dim LastRow As Long

    If ENDERECO <> "" Then
        Range(ENDERECO).Select
        ActiveCell.FormulaR1C1 = ActiveCell.Text & ", " & FileName
    Else
        ' Forma antiga de escrever os dados na planilha
        LastRow = Plan1.Cells(Plan1.Rows.Count, 1).End(xlUp).Row + 1
        Plan1.Cells(LastRow, 1) = FileName
    End If
End Sub

Function CheckIfExist(NOMEARQUIVO As String) As String
'
' Função para checar se já existe o nome do arquivo na coluna "A"
'
Dim Rng As Range        ' Range com os dados existentes na coluna "A"
Dim Dn As Range         ' Dados do Range
Dim Ln As Long          ' Tamanho do texto
Dim FileAux As String   ' Variável Auxiliar

    FileAux = NOMEARQUIVO
    Ln = Len(FileAux)

    Set Rng = Range(Range("A1"), Range("A" & Rows.Count).End(xlUp))

    For Each Dn In Rng
        If LCase(Mid(Dn.Value, 1, Ln)) = LCase(FileAux) Then
            CheckIfExist = Dn.Address
            Exit Function
        End If
    Next Dn

    ' Caso não encontre retorna zero
    CheckIfExist = ""

End Function

Please test the code and check if it is working as desired.

I hope I’ve been helpful!

Anything we can spare.

Abs

  • Great, by the way, HUGE Evert... all working perfectly. Thank you very much. Thank you for your interest in my problem, thank you for your time in restructuring the code and thank you very much for being helpful to those who do not know... Thank you again. Have...always. Abs Francisco Santos

  • @Thanks! Please! if served mark as answered (green arrow) and give an 'up' (marking as useful answer) ai!! Abs

  • Hi again. rs So I’m very glad that your problem has been solved. However, know that the best way for you to thank @Evert for his help is by accepting his response (by clicking on the "v" next to the votes) and even by voting positively for it. :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.