Filtro de textbox en referencia a un listbox que se carga con el contenido en imágenes de una carpeta

Tengo el siguiente caso bastante complejo a mi parecer y espero que algún experto me pueda ayudar

A la hora de registrar un producto en una base de datos mediate un formulario, en uno de los apartados guardo en una celda la ubicación de la imagen. Para realizarlo, dentro del formulario de registro tengo un segundo formulario específico de imagenes donde hay un listbox (carga todo el contenido de la carpeta) y una imagen; al seleccionar un item se guarda más un botón de guardar.

Dicho formulario de imagen funciona a través del siguiente módulo

Public PathImagenes As String
Public RutaImagen As String
'PathImagenes = ActiveWorkbook.Path & "\Productos\" as String
'
'Ruta ListFiles donde especificamos la ruta de la carpeta a buscar en el código de la hoja bajo UserForm_Initialize()
Sub ListFiles()
iRow = 2
Call ListMyFiles(PathImagenes, False)
End Sub
'
'Rutina que llena el ListBox de las imágenes
Sub ListMyFiles(mySourcePath, IncludeSubfolders)
Dim cuenta As Integer
On Error GoTo Errores
Set MyObject = New Scripting.FileSystemObject
Set MySource = MyObject.GetFolder(mySourcePath)
'
On Error Resume Next
ruta = ListBox1.txtRuta
Ext1 = "png"
Ext = "jpg"
cuenta = 0
For Each myfile In MySource.Files
    With Application.WorksheetFunction
        Extension = .Trim(Right(.Substitute(myfile.Name, ".", .Rept(" ", 500)), 500))
    End With
    If Ext1 = Extension Or Ext = Extension Then
        With frmImagenes
            .ListBox1.AddItem myfile.Path
            .ListBox1.List(.ListBox1.ListCount - 1, 1) = myfile.Name
        End With
    Else
    End If
Next
If IncludeSubfolders Then
    For Each MySubFolder In MySource.SubFolders
        Call ListMyFiles(MySubFolder.Path, True)
    Next
End If
Exit Sub
Errores:
'
MsgBox "Ha ocurrido un error: " & Err.Description & ".", vbExclamation, "Atención"
End Sub

Hay otra parte del módulo que carga la imagen del item seleccionado en el listbox.

En sí, lo que me gustaría es filtrar mediante lo escrito en un textbox (se añadiria al form) dicho listbox ya que tengo demasiadas imagenes en la carpeta y la lista de datos es enorme, con fin de agilizar la búsqueda del item/imagen

1 Respuesta

Respuesta
1

H o la: Te anexo el código actualizado.

Voy a suponer lo siguiente:

- En el userform frmImagenes, vas a poner un TextBox1.

- La ruta PathImagenes, en alguna parte la pones.

- Esta línea la quité, porque no la ocupas en el código:

Ruta = ListBox1.txtRuta

- Después de llenar el Textox1, vas a presionar un botón. Esto lo pones en ese botón:

Private Sub CommandButton1_Click()
    frmImagenes.ListBox1.Clear
    Call ListFiles
End Sub

Lo que hice fue agregar un parámetro al procedimiento:

Call ListMyFiles(PathImagenes, False, archivo)

El parámetro lo llame "archivo", pero antes archivo lo llené con el contenido de textbox1:

archivo = TextBox1.Value

Si el textbox1 es vacío y presionas el botón entonces te pone todos los nombres en el listbox. Si escribes un nombre o unas letras, el listbox es filtrado con esas letras.


La macro completa:

Public PathImagenes As String
Public RutaImagen As String
'PathImagenes = ActiveWorkbook.Path & "\Productos\" as String
'
'Ruta ListFiles donde especificamos la ruta de la carpeta a buscar en el código de la hoja bajo UserForm_Initialize()
Sub ListFiles()
    iRow = 2
    archivo = TextBox1.Value
    Call ListMyFiles(PathImagenes, False, archivo)
End Sub
'
'Rutina que llena el ListBox de las imágenes
Sub ListMyFiles(mySourcePath, IncludeSubfolders, archivo)
    Dim cuenta As Integer
    On Error GoTo Errores
    Set MyObject = New Scripting.FileSystemObject
    Set MySource = MyObject.GetFolder(mySourcePath)
    '
    On Error Resume Next
    'ruta = ListBox1.txtRuta
    Ext1 = "png"
    Ext = "jpg"
    cuenta = 0
    For Each myfile In MySource.Files
        With Application.WorksheetFunction
            Extension = .Trim(Right(.Substitute(myfile.Name, ".", .Rept(" ", 500)), 500))
        End With
        If Ext1 = LCase(Extension) Or Ext = LCase(Extension) Then
            If InStr(1, LCase(myfile.Name), LCase(archivo)) > 0 Then
                With frmImagenes
                    .ListBox1.AddItem myfile.Path
                    .ListBox1.List(.ListBox1.ListCount - 1, 1) = myfile.Name
                End With
            End If
        Else
        End If
    Next
    If IncludeSubfolders Then
        For Each MySubFolder In MySource.SubFolders
            Call ListMyFiles(MySubFolder.Path, True, archivo)
        Next
    End If
    Exit Sub
Errores:
    '
    MsgBox "Ha ocurrido un error: " & Err.Description & ".", vbExclamation, "Atención"
End Sub
'
Private Sub CommandButton1_Click()
    PathImagenes = "C:\trabajo\"
    frmImagenes.ListBox1.Clear
    Call ListFiles
End Sub

Recuerda llenar la variable: PathImagenes , yo le puse "C:\trabajo\", cambia esa ruta por la que deseas.


'S aludos. Dante Amor. Recuerda valorar la respuesta. G racias

Hola Dante

Una vez más, mil gracias por tu ayuda, sin vosotros no sería posible desarrollar nuestros pequeños programas.

Sobre lo que supones de mi planteamiento estas en lo cierto. La ruta PathImagenes va dentro del evento Initialize del formulario de registro. Tengo 2 registros, para diferentes cosas, y comparten el mismo formulario de imagen pero según el registro en el que estoy me carga una lista u otra evidentemente.

Copie la macro como has puesto y me genera un error 424 en tiempo de ejecución con el mensaje "se requiere un objeto" señalandome que no es capaz de abrir el formulario de imagen (en el de registro entra perfectamente)

Te voy a pasar la segunda parte del código que va dentro del módulo porque igual es necesario modificar algo ahi para que funcione 

'Cada que demos click en un elemento del ListBox llamará a esta macro
Sub MostrarImagen()
On Error GoTo Error 'en caso de tener varias carpetas para buscar imágenes debemos hacer que la encuentre, por ello si falla la primera que acceda a la segunda
With frmImagenes
    cuenta = .ListBox1.ListCount
    For i = 0 To cuenta - 1
        If .ListBox1.Selected(i) Then
            .imgPicture.Picture = LoadPicture(PathImagenes & .ListBox1.List(i, 1)) 'identifica la imagen en la ruta
            RegRecetas.txtNombreImagen.Caption = .ListBox1.List(i, 1) 'Está activada y dice el nombre del archivo
            RutaImagen = .ListBox1.List(i, 0)
        End If
    Next i
End With
Exit Sub
Error:
With frmImagenes
    cuenta = .ListBox1.ListCount
    For i = 0 To cuenta - 1
        If .ListBox1.Selected(i) Then
            .imgPicture.Picture = LoadPicture(ActiveWorkbook.Path & "\Ejercicios\" & .ListBox1.List(i, 1)) 'en este caso identificamos la ruta
            RegEjercicios.txtNombreImagen.Caption = .ListBox1.List(i, 1) '(activada)
            RutaImagen = .ListBox1.List(i, 0)
        End If
    Next i
End With
End Sub

Espero que te pueda servir para darme la solución definitiva. Un saludo y gracias nuevamente.

Hola Dante

En el código del frmImagenes he borrado del evento Initialize la línea que llama a la macro Call ListFiles y ya me ha abierto el formulario pero lamentablemente cuando pulso el botón en el cual puse el código que me dijiste salta ahi el error y me dirige al módulo señalándome en amarillo archivo = TextBox1.value

Si coloco la ruta dentro del botón del formulario de imágenes como me has indicado en tu respuesta al pulsar el botón si me ofrece la lista de los elementos de la carpeta, sin embargo no me filtra.

El problema es que no puedo poner la ruta en ese apartado, dentro de ese formulario porque ese es compartido sino la ruta debe estar en el evento Initialize del registre en el que trabajo ya que así al acceder al propio de las imágenes ya entra con la ruta identificada

Hola de nuevo Dante, hice nuevas pruebas y al quitar el .value de textbox1 en la macro del módulo sí me aparece la lista de datos sin embargo no filtra la lista al escribir texto, y además da igual donde coloque el PathImagenes, lo he vuelto a poner en el evento Initialize del registro y aparece la lista, pero como te digo no me filtra.

Ya no entendí dónde tienes cada control.

Envíame tu archivo con los formularios y me explicas paso a paso cómo ejecutas los formularios.

Mi correo [email protected]

En el asunto del correo escribe tu nombre de usuario “Esteban Tierra Arias” y el título de esta pregunta.

Hola Dante

La verdad lamento no poder enviarte el archivo porque es  un programa complejo y pesado (actualmente esta en 30 mb), además tengo varias bases de datos dentro del mismo incluyendo datos personales que no me gustaría enviar, sin pretender ofender. He intentado hacer una copia y dejar únicamente aquellas hojas fundamentales para los registros pero en cuanto quise ejecutar uno me ha saltado un error y me ha cerrado el excel.

Entiendo la dificultad de ayudar sin ver el programa, la macro, los módulos... no te preocupes, muchisiimas gracias igualmente por la ayuda

No te preocupes.

No entiendo en dónde tienes el textbox ni en cuál formulario estás.

En esta parte del código tienes que poner el filtro:

For Each myfile In MySource.Files
    With Application.WorksheetFunction
        Extension = .Trim(Right(.Substitute(myfile.Name, ".", .Rept(" ", 500)), 500))
    End With
    If Ext1 = Extension Or Ext = Extension Then
        With frmImagenes
            .ListBox1.AddItem myfile.Path
            .ListBox1.List(.ListBox1.ListCount - 1, 1) = myfile.Name
        End With
    Else
    End If
Next

Lo que yo hice es poner el filtro así:

    For Each myfile In MySource.Files
        With Application.WorksheetFunction
            Extension = .Trim(Right(.Substitute(myfile.Name, ".", .Rept(" ", 500)), 500))
        End With
        If Ext1 = LCase(Extension) Or Ext = LCase(Extension) Then
            If InStr(1, LCase(myfile.Name), LCase("facturas")) > 0 Then
                With frmImagenes
                    .ListBox1.AddItem myfile.Path
                    .ListBox1.List(.ListBox1.ListCount - 1, 1) = myfile.Name
                End With
            End If
        Else
        End If
    Next

Cambia "facturas" por el contenido de tu textbox o cambia "facturas" por el texto que quieras, para que veas el funcionamiento. Una vez que comprendas cómo funciona el filtro, entonces ya puedes cambiar "facturas" por el textbox1, por ejemplo:

    For Each myfile In MySource.Files
        With Application.WorksheetFunction
            Extension = .Trim(Right(.Substitute(myfile.Name, ".", .Rept(" ", 500)), 500))
        End With
        If Ext1 = LCase(Extension) Or Ext = LCase(Extension) Then
            If InStr(1, LCase(myfile.Name), LCase(textbox1)) > 0 Then
                With frmImagenes
                    .ListBox1.AddItem myfile.Path
                    .ListBox1.List(.ListBox1.ListCount - 1, 1) = myfile.Name
                End With
            End If
        Else
        End If
    Next

O puede ser así:

    For Each myfile In MySource.Files
        With Application.WorksheetFunction
            Extension = .Trim(Right(.Substitute(myfile.Name, ".", .Rept(" ", 500)), 500))
        End With
        If Ext1 = LCase(Extension) Or Ext = LCase(Extension) Then
            If InStr(1, LCase(myfile.Name), LCase(userform1.textbox1)) > 0 Then
                With frmImagenes
                    .ListBox1.AddItem myfile.Path
                    .ListBox1.List(.ListBox1.ListCount - 1, 1) = myfile.Name
                End With
            End If
        Else
        End If
    Next

Entonces cambias userform1.textbox1 por el nombre de tus controles.

Sal u dos

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas