Este foro usa cookies
Este foro utiliza cookies para almacenar su información de inicio de sesión si está registrado y su última visita si no lo está. Las cookies son pequeños documentos de texto almacenados en su computadora; las cookies establecidas por este foro solo se pueden usar en este sitio web y no representan ningún riesgo de seguridad. Las cookies en este foro también rastrean los temas específicos que ha leído y la última vez que los leyó. Si Ud. continúa navegando, entenderemos que acepta todas las cookies.

Se almacenará una cookie en su navegador, independientemente de la elección, para evitar que se le vuelva a hacer esta pregunta. Podrá cambiar la configuración de sus cookies en cualquier momento utilizando el enlace en el pie de página.

El foro antiguo se encuentra accesible desde https://foro.gambas-es.org en modo de solo lectura.

Calificación:
  • 0 voto(s) - 0 Media
  • 1
  • 2
  • 3
  • 4
  • 5

Mostrar Archivos indexados por extensión
#1

Buenas!.

En el primer ejemplo que realicé clasificaba los archivos por la letra que comenzaba y luego añadía un indice a cada pestaña
de un TabStrip. Esta vez, se va a mostrar los archivos clasificados por extensiones y por la letra que comienza.

[Imagen: MBbBtZb.png]

Tiene dos controles TabStrip. Exterior e interno. El exterior tiene las pestañas superiores y el interno las inferiores.
Normalmente las pestañas puedes desplazarte con los cursores, pero eso solo funciona en el principal o solo
en pestañas superiores, en las inferiores no me ha funcionado. He añadido un botón para cerrar la aplicación.

La estructura de datos:

La colección principal, usa como clave las extensiones de los archivos.

[Imagen: ZpZ099J.png]

Selecciono los que tiene la extensión T64 y se muestran los indices disponibles.

[Imagen: GwIfIuh.png]

Del array total["T64"], se muestran los archivos que comienzan por "1".

[Imagen: BWyXlEq.png]

Espero que les valga y que se pueda mejorar. Consejos. Shy

Saludos

"El buen perfume en frasco pequeño se vende"
[-] Los siguientes 2 usuarios dicen gracias a Shell por este post:
  • Shordi, tincho
    ¡Gracias!
#2

He encontrado un error cuando se produce esta situación:

[Imagen: rXZAygn.png]

El nombre es que es raro. Lógicamente también aparecerá en los que tienen extensión torrent.
Habrá que buscar el lugar del punto desde la derecha y contar desde ahí hasta el final.

Actualmente es:

GAMBAS
  1. Public Sub IndexarPorExtension(ctodos As Collection, extension As String) As Collection
  2.  
  3.   Dim ctemp As New Collection
  4.   Dim aarchivos As String[]
  5.   Dim nom As String
  6.   Dim anom As String[]
  7.   Dim letra As String
  8.  
  9.   For Each anom In ctodos
  10.     For Each nom In anom
  11.       
  12.       'Buscamos por la derecha el "." y la extensión del mismo. ".jpg",".txt"..
  13.       If RInStr(nom, "." & extension) <> 0 Then
  14.    '     If nom = "linuxmint-19.3-mate-64bit-beta.iso.torrent" Then Stop
  15.         letra = Left(nom, 1)      
  16.         If Not ctemp.Exist(letra) Then
  17.           aarchivos = New String[]
  18.           ctemp[letra] = aarchivos
  19.           ctemp[letra].add(nom)
  20.         Else
  21.           ctemp[letra].add(nom)
  22.         Endif
  23.       Endif
  24.     Next  
  25.   Next
  26.  
  27.   Return ctemp
  28.  



Mañanaaaa. Wink

Buenas noches.

Vale, estoy enganchado, lo reconozco.... Rolleyes

He encontrado una solución temporal o fija. He cambiado el código de arriba por este:
Usando split y el "." como separador, lo que haya detrás del último punto es la extensión.

GAMBAS
  1. Public Sub IndexarPorExtension(ctodos As Collection, extension As String) As Collection
  2.  
  3.   Dim ctemp As New Collection
  4.   Dim aarchivos As String[]
  5.   Dim nom As String
  6.   Dim anom As String[]
  7.   Dim letra As String
  8.  
  9.   Dim sextension As String[]
  10.  
  11.   For Each anom In ctodos
  12.     For Each nom In anom      
  13.       sextension = Split(nom, ".")
  14.       If sextension.last = extension Then
  15.         letra = Left(nom, 1)      
  16.         If Not ctemp.Exist(letra) Then
  17.           aarchivos = New String[]
  18.           ctemp[letra] = aarchivos
  19.           ctemp[letra].add(nom)        
  20.         Else           
  21.           ctemp[letra].add(nom)
  22.         Endif
  23.       Endif
  24.     Next  
  25.   Next
  26.  
  27.   Return ctemp
  28.  



¿ Existe alguna forma de usar directamente la propiedad last con Split(nom, ".") ?
He usado una variable sextension...el nombre se las trae. Es que ha salido solo. Angel

[Imagen: QS38zKA.png]

Ahora si!.

Y ya de paso esta función también se puede aprovechar lo de antes.

GAMBAS
  1. Public Sub ObtenerExtensiones(aarchivos As String[]) As String[]
  2.  
  3.   Dim aextensiones As New String[]
  4.   Dim nombref As String
  5.   Dim extension As String
  6.  
  7.   'Dim pos As Integer
  8.  
  9.   For Each nombref In aarchivos
  10.     'pos = RInStr(nombref, ".")
  11.     'extension = Mid(nombref, pos + 1)    
  12.     extension = Split(nombref, ".").Last
  13.     If Not aextensiones.Exist(extension) Then aextensiones.Add(extension)
  14.   Next
  15.  
  16.   Return aextensiones
  17.  



Que me convierto en calabaza!!

"El buen perfume en frasco pequeño se vende"
    ¡Gracias!
#3

Prueba con

GAMBAS
  1. Public Sub ObtenerExtensiones(aarchivos As String[]) As String[]
  2.  
  3.   Dim aextensiones As New String[]
  4.   Dim nombref As String
  5.   Dim extension As String
  6.  
  7.   'Dim pos As Integer
  8.  
  9.   For Each nombref In aarchivos
  10.     extension = file.ext(nombref)
  11.     If Not aextensiones.Exist(extension) Then aextensiones.Add(extension)
  12.   Next
  13.  
  14.   Return aextensiones
  15.  



Para manejo de nombres de archivos existe la clase file. Es lo más simple y mejor.


Saludos

No podemos regresar
[-] Los siguientes 1 usuarios dice gracias a Shordi por este post:
  • Shell
    ¡Gracias!
#4

(20-10-2022, 23:12)Shell escribió:  ¿ Existe alguna forma de usar directamente la propiedad last con Split(nom, ".") ?

No exactamente, pero podes hacer esto otro:
GAMBAS
  1. extension = Split(nombref, ".")[Split(nombref, ".").Max]



Pero no es lo correcto en este caso sino:
GAMBAS
  1. File.Ext("/tmp/tuarchivo.iso.torrent")



1 Saludo.
[-] Los siguientes 1 usuarios dice gracias a tincho por este post:
  • Shell
    ¡Gracias!
#5

(21-10-2022, 01:56)Shordi escribió:  Para manejo de nombres de archivos existe la clase file. Es lo más simple y mejor.

Vaya, no conocía esa posibilidad. Y más ideal como decís.

Luego estuve solucionando  la clasificación de archivos por extensiones en la función indexar por extensiones.

Estuve probando entre funciones de cadena y la función Split, resultó que era más rápido con cadenas.
Se complicaba un poco usando funciones de cadena encadenadas pero es más rápido.

Cuando se crean expresiones que contienen funciones una dentro de otra  se vuelve compleja la expresión,
por el tema de paréntesis. Siempre se debe comenzar desde el más interior.

Primero lo hago en partes y si veo que funciona, la voy anidando.

Usando cadenas queda así la función indexar por extensiones.
He comentado desde el paréntesis interior hasta llegar al último exterior.

GAMBAS
  1. Public Sub IndexarPorExtension(ctodos As Collection, extension As String) As Collection
  2.  
  3.   Dim ctemp As New Collection
  4.   Dim aarchivos As String[]
  5.   Dim nom As String
  6.   Dim anom As String[]
  7.   Dim letra As String
  8.  
  9.   For Each anom In ctodos
  10.     For Each nom In anom      
  11.       'Obtener posición del punto. Obtener cadena desde el punto hasta el final. Comprobar que la cadena obtenida y la extensión concuerdan.
  12.       If RInStr(Mid(nom, RInStr(nom, ".")), "." & extension) <> 0 Then
  13.         letra = Left(nom, 1)      
  14.         If Not ctemp.Exist(letra) Then
  15.           aarchivos = New String[]
  16.           ctemp[letra] = aarchivos
  17.           ctemp[letra].add(nom)        
  18.         Else           
  19.           ctemp[letra].add(nom)
  20.         Endif
  21.       Endif
  22.     Next  
  23.   Next
  24.  
  25.   Return ctemp
  26.  



Con Split:

[Imagen: CkpBR3M.png]

Con funciones de cadenas.

[Imagen: qxWAUSK.png]

Lógicamente varía con cada ejecución. Siempre viendo que con las funciones de cadenas es más rápido.
Se necesitaría ejecutar muchas veces el test y hacer una media, si se quiere ver más.

He cambiado la función de obtener las extensiones de los archivos. Es mejor, naturalmente.
Pero observo que en el perfilado el tiempo que tarda no es muy distinto a la función original.

A veces no es cuestión de que una aplicación sea más rápida , es más de usar el método correcto como el caso de la clase File.
Los programadores buscamos una solución cuando se desconoce la existencia de otras posibilidades, en parte son cajas negras,
lo que conocemos como abstracción.

¿ Sabíais que la ventana de los resultados de perfilado se puede ir añadiendo una y otra según ejecutas la aplicación varias veces ?.

Subo el ejemplo con los cambios.

Saludos

"El buen perfume en frasco pequeño se vende"
    ¡Gracias!
#6

A ver, que no me entero.

He bajado la última versión. Al ejecutar me sale la pantalla y la solicitud de seleccionar directorio. Lo selecciono y entonces aparece esto:

[Imagen: 1rxF5Nx.png]
Es decir un tabstrip con tantas pestañas como archivos encontrados cuyo título es el nombre del archivo y que al ser pulsados me muestran... el nombre del archivo.
Debajo hay una barra precedida por un punto y el botón de seleccionar queda deshabilitado, con lo que no puedo seleccionar nada más ni hacer nada.
¿Ese es el comportamiento esperado o es un bug?

Salir.

No podemos regresar
[-] Los siguientes 1 usuarios dice gracias a Shordi por este post:
  • Shell
    ¡Gracias!
#7

(22-10-2022, 11:28)Shordi escribió:  Es decir un tabstrip con tantas pestañas como archivos encontrados cuyo título es el nombre del archivo y que al ser pulsados me muestran... el nombre del archivo.
Debajo hay una barra precedida por un punto y el botón de seleccionar queda deshabilitado, con lo que no puedo seleccionar nada más ni hacer nada.
¿Ese es el comportamiento esperado o es un bug?

Cierto al abrir el dialogo para seleccionar el directorio del usuario, encuentra archivos que su nombre comienzan por punto
y crea tantas pestañas como archivos que comiencen por punto. Así falla.

El botón se deshabilita intencionadamente. Rolleyes
Para cambiar el contenido actual de las pestañas y estas habría que eliminar todo el contenido de las pestañas primero.

No había caído en ese error.

Saludos

"El buen perfume en frasco pequeño se vende"
    ¡Gracias!
#8

Buenas!.

Estoy en ello, he logrado hacerlo funcionar, pero hay algo que no entiendo aún del TabStrip.
Más bien creo que es como se debe usar este control para que no de luego problemas.
Ejemplo eliminar lo que queda dentro de las pestañas sin que se vuelva invalido el control.

En principio como solo iba usar para las extensiones de archivos que las tuviera, ejemplos las extensiones de
los archivos de emuladores, no caí en los archivos ocultos que su nombre no es una extensión pero usan el punto.

Hay un evento que ocurre en el TabStrip cuando se define el número de pestañas que tiene y ese proceso, aparenta como si
se hiciera click en la pestaña.

Hace uno días vi en un código de la granja la sentencia "Try" y pensé, pero si el programa ya debe funcionar (subido a la granja) por qué no
lo habrá quitado. Misterios de la programación.

Mi problema ocurre aquí:

GAMBAS
  1. Public Sub TabStripExterior_Click()
  2.  
  3.   'FIXME: No terminado completamentente
  4.   'No levanta error, a pesar de que tb puede ser nulo o invalido. Es una chapuza que lo hace funcionar.
  5.   Try tb.Index = 0
  6.  
  7.   'If Error Then Message.Error(Error.Text & gb.NewLine & Error.Where & gb.NewLine & Error.Code)
  8.  



Como Try no levanta error, da la impresión de funcionar correctamente. Y es que no da error usando eso.
Pero no me parece correcto.

La idea es de que siempre que se selecciona una pestaña en el tabstrip exterior,
el indice de la pestaña interior se ponga a la primera que existe. Su indice a 0. Que ocurre?. Que puede
que aún no se haya creado esa pestaña interior, debido a ese evento click que se produce. ( Desconocimiento adecuado de TabStrip ).

Voy a subiros la nueva versión. A ver que podéis aconsejarme. Tampoco he encontrado un tutorial "adecuado" para entender
TabStrip.

¿ Sabíais que las pestañas se pueden ocultar ?.

Saludos

"El buen perfume en frasco pequeño se vende"
    ¡Gracias!
#9

La solución que se me ocurre es una variable global  al formulario que actuase como una bandera (boolean) y cuando se cree la primera
pestaña interior ponerla a True y cuando se borran todas las pestañas interiores del tabstrip superior, ponerla a False.

Así que el evento click que se produce de las pestañas del tabstrip superior  al decirle cuantas pestañas quieres que tenga quedaría así:
(que se puede elegir otro nombre para la variable).

GAMBAS
  1. Public Sub TabStripExterior_Click()
  2.  
  3.     If creadotb Then tb.Index = 0
  4.  



Anda que por decirle cuantas pestañas quieres que tenga el tabstrip se active el evento click.
Eso no quita que de alguna forma queden objetos inválidos. Controlar cuando existen
es lo complicado. Tenemos IsNull, pero no IsValid..  Cool

Pestaña superior - Pestaña inferior - Gridview ( que probablemente deben ser los que se quedan inválidos )

Saludos

"El buen perfume en frasco pequeño se vende"
    ¡Gracias!
#10

Ahora mejor. Big Grin Big Grin

Si selecciono directorios funciona bien, pero cuando después de haber seleccionado alguno selecciono un enlace simbólico a un directorio que sólo tiene carpetas, al volver a seleccionar otro levanta un error en la línea 218 de "Objeto Nulo".

Saludos.

No podemos regresar
    ¡Gracias!


Posibles temas similares…
Tema / Autor Respuestas Vistas Último mensaje

Salto de foro:


Usuarios navegando en este tema: 1 invitado(s)