Páginas (2): 1 2   
Shell   20-10-2022, 21:28
#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
Última modificación: 21-10-2022, 11:56 por Shell.

"El conocimiento es la mejor inversión que se puede hacer" - Abraham Lincoln
Shell   20-10-2022, 23:12
#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:

Código:
Public Sub IndexarPorExtension(ctodos As Collection, extension As String) As Collection
 
  Dim ctemp As New Collection
  Dim aarchivos As String[]
  Dim nom As String
  Dim anom As String[]
  Dim letra As String
 
  For Each anom In ctodos
    For Each nom In anom
      
      'Buscamos por la derecha el "." y la extensión del mismo. ".jpg",".txt"..
      If RInStr(nom, "." & extension) <> 0 Then
   '     If nom = "linuxmint-19.3-mate-64bit-beta.iso.torrent" Then Stop
        letra = Left(nom, 1)      
        If Not ctemp.Exist(letra) Then
          aarchivos = New String[]
          ctemp[letra] = aarchivos
          ctemp[letra].add(nom)
        Else
          ctemp[letra].add(nom)
        Endif
      Endif
    Next  
  Next
 
  Return ctemp
 
End

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.

Código:
Public Sub IndexarPorExtension(ctodos As Collection, extension As String) As Collection
 
  Dim ctemp As New Collection
  Dim aarchivos As String[]
  Dim nom As String
  Dim anom As String[]
  Dim letra As String
 
  Dim sextension As String[]
 
  For Each anom In ctodos
    For Each nom In anom      
      sextension = Split(nom, ".")
      If sextension.last = extension Then
        letra = Left(nom, 1)      
        If Not ctemp.Exist(letra) Then
          aarchivos = New String[]
          ctemp[letra] = aarchivos
          ctemp[letra].add(nom)        
        Else           
          ctemp[letra].add(nom)
        Endif
      Endif
    Next  
  Next
 
  Return ctemp
 
End

¿ 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.

Código:
Public Sub ObtenerExtensiones(aarchivos As String[]) As String[]
 
  Dim aextensiones As New String[]
  Dim nombref As String
  Dim extension As String
 
  'Dim pos As Integer
 
  For Each nombref In aarchivos
    'pos = RInStr(nombref, ".")
    'extension = Mid(nombref, pos + 1)    
    extension = Split(nombref, ".").Last
    If Not aextensiones.Exist(extension) Then aextensiones.Add(extension)
  Next
 
  Return aextensiones
 
End

Que me convierto en calabaza!!
Última modificación: 20-10-2022, 23:58 por Shell.

"El conocimiento es la mejor inversión que se puede hacer" - Abraham Lincoln
Shordi   21-10-2022, 01:56
#3
Prueba con

Código:
 
  Dim aextensiones As New String[]
  Dim nombref As String
  Dim extension As String
 
  'Dim pos As Integer
 
  For Each nombref In aarchivos
    extension = file.ext(nombref)
    If Not aextensiones.Exist(extension) Then aextensiones.Add(extension)
  Next
 
  Return aextensiones
 
End

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


Saludos
Última modificación: 21-10-2022, 01:59 por Shordi.

No podemos regresar
tincho   21-10-2022, 09:13
#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:
Código:
extension = Split(nombref, ".")[Split(nombref, ".").Max]

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

1 Saludo.
Shell   21-10-2022, 11:55
#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.

Código:
Public Sub IndexarPorExtension(ctodos As Collection, extension As String) As Collection
 
  Dim ctemp As New Collection
  Dim aarchivos As String[]
  Dim nom As String
  Dim anom As String[]
  Dim letra As String
 
  For Each anom In ctodos
    For Each nom In anom      
      'Obtener posición del punto. Obtener cadena desde el punto hasta el final. Comprobar que la cadena obtenida y la extensión concuerdan.
      If RInStr(Mid(nom, RInStr(nom, ".")), "." & extension) <> 0 Then
        letra = Left(nom, 1)      
        If Not ctemp.Exist(letra) Then
          aarchivos = New String[]
          ctemp[letra] = aarchivos
          ctemp[letra].add(nom)        
        Else           
          ctemp[letra].add(nom)
        Endif
      Endif
    Next  
  Next
 
  Return ctemp
 
End

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
Última modificación: 26-10-2022, 14:51 por Shell.

"El conocimiento es la mejor inversión que se puede hacer" - Abraham Lincoln
Shordi   22-10-2022, 11:28
#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
Shell   24-10-2022, 16:46
#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 conocimiento es la mejor inversión que se puede hacer" - Abraham Lincoln
Shell   26-10-2022, 14:50
#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í:

Código:
Public Sub TabStripExterior_Click()
 
  'FIXME: No terminado completamentente
  'No levanta error, a pesar de que tb puede ser nulo o invalido. Es una chapuza que lo hace funcionar.
  Try tb.Index = 0
 
  'If Error Then Message.Error(Error.Text & gb.NewLine & Error.Where & gb.NewLine & Error.Code)
 
End

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
Última modificación: 26-10-2022, 20:18 por Shell.

"El conocimiento es la mejor inversión que se puede hacer" - Abraham Lincoln
Shell   26-10-2022, 19:54
#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).

Código:
Public Sub TabStripExterior_Click()

    If creadotb Then tb.Index = 0
 
End

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
Última modificación: 26-10-2022, 19:56 por Shell.

"El conocimiento es la mejor inversión que se puede hacer" - Abraham Lincoln
Shordi   26-10-2022, 19:54
#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
Páginas (2): 1 2   
  
Usuarios navegando en este tema: 3 invitado(s)
Powered By MyBB, © 2002-2024 MyBB Group.
Made with by Curves UI.