• 👏 Bienvenido a nuestra comunidad Excel

    ¿Todavía no estás registrado? 😲

    Registrate gratis aquí y podrás:

    💪 Hacer preguntas a los expertos
    ⬇️ Descargar ejemplos y plantillas
    🏅 
    Acceder a contenidos premium

Problema con la carga de un listbox y el metodo Application.index

Hola estimados foristas, buen dia.

Estoy teniendo un problema para la populacion de un listbox (la carga del listbox), de una serie de datos (filas) no continuas en tiempo de ejecucion.

Me explico:

Tengo una hoja con datos la cual posee 15 columnas y varias filas (el numero va a ser variable).

Yo necesito buscar por fecha a traves de un textbox y que cuando la busqueda coincida con las filas que correspondan, se cargue en el listbox solo esas filas.

Yo lo que pude lograr es cargar el listbox con todos los datos. Pero yo solo necesito que se carguen las filas que coincidan con la busqueda.

Tengo entendido que una forma de hacer una carga de filas especificas es esta y funciona bien:


Código:
vector = Application.Index(.Value, Application.Transpose(Array(1,5,8)), Array(3, 1, 2, 14, 15))


Donde ahi solo cargo las filas 1,5 y 8 y solo las columnas 3,1,2,14 y 15.

Este codigo funciona bien para la carga de un vector y luego asigno ese vector al listbox1 y se carga perfecto.:

Código:
listbox1=vector



El problema es que yo no se de antemano cuales filas seran las que coincidan con la busqueda y lo unico que podria hacer
es cargar un vector con esas filas para saber que filas son, pero de ahi en adelante no se como avanzar para cargar el vector con el metodo Application.index y luego asi
asignar ese resultado al listbox.

Dejo el codigo que esta funcionando pero que esta cargando TODOS los datos en el listbox.
Dentro de la busqueda inteligente creo que deberia ir algo que me permita determinar las filas a cargar y luego con eso
poder cargar el vector con el metodo Application.index o directamente cargar el listbox, esa es la parte que no se como lograr.

Aclaro de antemano que no quiero usar el metodo Additem, ya que es ineficiente y tiene el limitante hasta la carga de 10 columnas ( aunque hay un artificio para lograr cargar mas de 10 columnas, no me interesaria ir por ese camino)

Código:
Private Sub UserForm_Initialize()

'Parametros del Listbox
With Me.Listbox1

    .ColumnCount = 15
    .ColumnHeads = True
   
End With


End Sub


Private Sub fechabusqueda_Change()

Worksheets("hoja1").Activate
ultimafila = Cells(Rows.Count, "A").End(xlUp).Row

Dim x, Arr As Variant


'Busqueda inteligente

For fila = 2 To ultimafila

    fechaingreso = Worksheets("hoja1").Range("A" & fila).Value

            If fechaingreso Like "*" & Me.fechabusqueda.Value & "*" Or fila = 1 Then


'  ' Deberia ir almancenando las filas que corresponden con la busqueda inteligente y solo esas filas cargarlas en el listbox

            End If

Next

   Arr = Application.Index(Cells, Evaluate("ROW(1:" & Cells(Rows.Count, "A").End(xlUp).Row & ")"), Application.Transpose([row(1:15)])) 'Generating Array

  'Formatea la columna 1 con formato de fecha "d/m/yyyy"
  For x = 1 To UBound(Arr)
    Arr(x, 1) = Format(Arr(x, 1), "d/m/yyyy")
  Next
 
Listbox1.List = Arr



End Sub



Este codigo esta funcionando pero con la carga de todos los datos.
Necesitaria que cargue solo las filas que coincidan con la busqueda inteligente.

Cualquier aporte sera bienvenido, desde ya muchas gracias.
 

Adjuntos

Cacho R

Well-known member
Hola!
Está claro que quieres filtrar las filas que contienen la fecha que pongas en el textBox.
Lo que no fuiste -para nada- claro es con las columnas. O sea:
  • ¿Quieres las cinco columnas: 3, 1, 2, 14 y 15 (en ese orden)?... o
  • ¿Quieres TODAS las columnas?... o
  • ¿Quieres TODAS las columnas pero en algún otro orden?
Cualquiera de las 3 opciones anteriores son factibles... ¡Pero indica cuál de ellas necesitas pues lo que comentas y lo que muestras en tu archivo son ideas no coincidentes!

Saludos, Cacho R.
 
Hola!
Está claro que quieres filtrar las filas que contienen la fecha que pongas en el textBox.
Lo que no fuiste -para nada- claro es con las columnas. O sea:
  • ¿Quieres las cinco columnas: 3, 1, 2, 14 y 15 (en ese orden)?... o
  • ¿Quieres TODAS las columnas?... o
  • ¿Quieres TODAS las columnas pero en algún otro orden?
Cualquiera de las 3 opciones anteriores son factibles... ¡Pero indica cuál de ellas necesitas pues lo que comentas y lo que muestras en tu archivo son ideas no coincidentes!

Saludos, Cacho R.
Hola Cacho R. Sabia que podia contar con UD. : )

Necesitaria todas las columnas, osea de la 1 hasta la 15

Código:
Arr = Application.Index(Cells, Evaluate("ROW(1:" & Cells(Rows.Count, "A").End(xlUp).Row & ")"), Application.Transpose([row(1:15)]))


Aca con este codigo hago la carga de todas las columnas (1 a la 15) en el vector Arr, pero no puedo filtrar las filas que se van creando de acuerdo a la busqueda inteligente.

Agregando este codigo, puedo filtrar filas especificas, pero no me sirve explicitamente, porque en realidad no se de antemano cuales filas seran.

Código:
Arr = Application.Index(Cells, Application.Transpose(Array(1,5,8)), Application.Transpose([row(1:15)])) 
' Ejemplo de seleccion de carga de sola las filas 1,5,8.



Cualquier aporte sera bienvenido. Muchas gracias.
 
Ok... Te muestro un "aporte cualquiera"... (Jejjjejeje)
Saludos, Cacho R.
Hola Cacho R.
Funciona muy bien el codigo, es decir fitra las filas que corresponden con la busqueda.

El unico tema es que la busqueda no es inteligente. Es decir si yo agrego solo un numero en la busqueda de fecha, no me muestra nada el listbox.

La busqueda necesitaria que sea inteligente y que busque solo ingresando un numero inclusive y muestre lo que encuentre como coincidencia.


Código:
If fechaingreso Like "*" & Me.fechabusqueda.Value & "*" Or fila = 1 Then


'  ' Deberia ir almancenando las filas que corresponden con la busqueda inteligente y solo esas filas cargarlas en el listbox

            End If


De todas maneras, ya esta bastante avanzada la idea y va cumpliendo casi toda la necesidad.
Gracias igualmente.
Saludos.
 

Héctor Miguel

Well-known member
La busqueda necesitaria que sea inteligente y que busque solo ingresando un numero inclusive y muestre lo que encuentre como coincidencia
(si se me permite "abundar" ?) considera lo siguiente:

1) las fechas (en excel) son "simples" enteros seriales (desde el 1/enero/1900 hasta el 31/diciembre/9999)
- el formato con que los quieras "ver" es solo maquillaje (o "máscara de presentación" en pantalla/impresora)

2) las cajas de texto (TextBox's) son solo "eso" (contenedores de texto) PERO...
- la interpretación de datos-fecha depende de la configuración del equipo Y las preferencias del usuario

3) el evento '_change' se dispara con cada pulsación en el control (el proceso es "machacante"), por lo que cabe preguntar:
- cual es el sentido de usar "comodines" ANTES Y DESPUÉS del texto que se va ingresando en la "caja de textos" ?
- como pretendes "hacer inteligente" la búsqueda para el cotejo: por el día ?, por el mes ?, por el año ? (piensa en los números seriales)
- como piensas "controlar" (y en su caso corregir) el orden de fechas que ingresa el usuario ? (o si pone el mes en letras ?)

por otro lado (si sigue siendo de tu interés), es posible "filtrar" las filas coincidentes y ponerlas en un array SIN usar rangos auxiliares aplacando (correctamente) la función "index" (por si resulta ser "algo nuevo" para ti)
- el inconveniente es que pierdes la opción de indicar en el control de lista los encabezados de las columnas (al no provenir de rangos)
- y/o tendrías que proveer "etiquetas" adosadas a la parte superior de cada columna en el control de lista
 
(si se me permite "abundar" ?) considera lo siguiente:

1) las fechas (en excel) son "simples" enteros seriales (desde el 1/enero/1900 hasta el 31/diciembre/9999)
- el formato con que los quieras "ver" es solo maquillaje (o "máscara de presentación" en pantalla/impresora)

2) las cajas de texto (TextBox's) son solo "eso" (contenedores de texto) PERO...
- la interpretación de datos-fecha depende de la configuración del equipo Y las preferencias del usuario

3) el evento '_change' se dispara con cada pulsación en el control (el proceso es "machacante"), por lo que cabe preguntar:
- cual es el sentido de usar "comodines" ANTES Y DESPUÉS del texto que se va ingresando en la "caja de textos" ?
- como pretendes "hacer inteligente" la búsqueda para el cotejo: por el día ?, por el mes ?, por el año ? (piensa en los números seriales)
- como piensas "controlar" (y en su caso corregir) el orden de fechas que ingresa el usuario ? (o si pone el mes en letras ?)

por otro lado (si sigue siendo de tu interés), es posible "filtrar" las filas coincidentes y ponerlas en un array SIN usar rangos auxiliares aplacando (correctamente) la función "index" (por si resulta ser "algo nuevo" para ti)
- el inconveniente es que pierdes la opción de indicar en el control de lista los encabezados de las columnas (al no provenir de rangos)
- y/o tendrías que proveer "etiquetas" adosadas a la parte superior de cada columna en el control de lista
Hola HectorMiguel, gracias por tu opinion.

Basicamente la busqueda intelignete la necesito para que por ejemplo, al solo ingresar un numero que coincida con una fecha, ya me muestre las filas correspondientes a esa coincidencia. Si ingresa una letra, no va a coincidir nada y por lo tanto no mostraria nada.

Con respecto a los encabezados, no habria problema de perderlos, de hecho en este caso yo los estoy ocultando cuando se ejecuta la rutina del evento change.

Me interesaria saber como hacer para poder filtrar filas (que va a ser un numero variable) con la funcion, Application.index.

basicamente en esta sentencia:

Código:
Arr = Application.Index(Cells, Application.Transpose(Array(1,5,8)), Application.Transpose([row(1:15)]))


En donde dice Array(1,5,8) tengo el problema, ya que ahi yo ya le estoy diciendo que muestre solo esas 3 filas.
Y en realidad la cantidad y variedad de filas sera siempre dinamica y variable.
Ahi radica mi problema.
 
Al final gracias a varios aportes e investigacion, pude dar solucion a mi problema.
Paso el codigo y el adjunto.

El problema radicaba en esta sentencia y con el arreglo que determinaba la seleccion de las filas que coincidian con la busqueda.

Código:
Arr = Application.Index(Cells, Application.Transpose(Array(1,5,8)), Application.Transpose([row(1:15)]))


Al final la sentencia quedo asi:

Código:
Arr = Application.Index(Cells, Application.Transpose(b), Application.Transpose([row(1:15)]))


Con esta sentencia lo que se logro, es enviar un Array , en este caso se llama b , el cual contiene las filas que coincidieron con la busqueda.


Pongo todo el codigo, que lo hace es, buscar una fecha en una serie de datos de forma inteligente, esto es ( Cuando uno ingresa un solo caracter,
ya te va mostrando el listbox con las coincidencias que se lograron hasta ese momento) :

Código:
Private Sub UserForm_Initialize()

'Parametros del Listbox
With Me.Listbox1

    .ColumnCount = 15
    .ColumnHeads = True
   
End With


End Sub


Private Sub fechabusqueda_Change()

Worksheets("hoja1").Activate
ultimafila = Cells(Rows.Count, "A").End(xlUp).Row
Listbox1.ColumnHeads = False

Dim x, Arr As Variant
Dim b() As Variant
Dim j As Long


'Busqueda inteligente

ReDim Preserve b(j)
b(0) = 1
j = 1

For fila = 2 To ultimafila

    fechaingreso = Worksheets("hoja1").Range("A" & fila).Value

            If fechaingreso Like "*" & Me.fechabusqueda.Value & "*" Or fila = 1 Then


            ReDim Preserve b(j)
            b(j) = fila
            j = j + 1

            End If

Next

If j = 0 Then
  MsgBox "No records"
  Exit Sub


Else

  ReDim Preserve b(j)
  b(j) = Worksheets("hoja1").Range("A" & Rows.Count).End(xlUp).Row + 1


End If


   Arr = Application.Index(Cells, Application.Transpose(b), Application.Transpose([row(1:15)])) 'Generando el Array "Arr"

  'Formatea la columna 1 con formato de fecha "d/m/yyyy"
  For x = 1 To UBound(Arr)
    Arr(x, 1) = Format(Arr(x, 1), "d/m/yyyy")
  Next
 
Listbox1.List = Arr



End Sub


Sin mas, agradezco a todos por sus aportes y doy por finalizado y solucionado el tema.
Saludos.
 

Adjuntos

Fíjate que pasa con estos dos métodos cuando escribes, por ejemplo:
  • 25/5
  • 25/05
  • /11
  • //19
Saludos, Cacho R.
Hola Cachor R.

Probe con esas entradas sugeridas:

  • 25/5
  • 25/05
  • /11
  • //19

, tanto en tu codigo como en el mio que propuse como solucion, y andan perfectos.

Tu codigo se nota bastante eficiente y elaborado. Aunque ahora si puedo pararme de frente y discutir un poco mas la eficiencia, jaja.
De todas maneras se que el tuyo sigue siendo mas eficiente y optimo.


Saludos y muchas gracias.
 

Cacho R

Well-known member
Tu codigo se nota bastante eficiente y elaborado.
Lo de la eficiencia no estoy tan seguro puesto que no lo medí...
Pero si en lugar de los "/" pones "-": ¡allí notas diferencias!

Además -y en mi caso- cuando pones: 25/5... ¡No aparece nada!
Y otro tema importante es que en tu código "pierdes" los títulos y los tienes que integrar al listBox. En cambio en el mío, y como cargo los datos con un RowSource: ¡No se pierde nada!
 
Lo de la eficiencia no estoy tan seguro puesto que no lo medí...
Pero si en lugar de los "/" pones "-": ¡allí notas diferencias!

Además -y en mi caso- cuando pones: 25/5... ¡No aparece nada!
Y otro tema importante es que en tu código "pierdes" los títulos y los tienes que integrar al listBox. En cambio en el mío, y como cargo los datos con un RowSource: ¡No se pierde nada!
En eso tenes razon. Detalles de expertos. Algun dia sere como vos. jjaja. Saludos.
 

Héctor Miguel

Well-known member
al solo ingresar un numero que coincida con una fecha, ya me muestre las filas correspondientes a esa coincidencia
1) dado que no te interesan los encabezados en el control de lista (ya que tomas la fila 1 del rango de origen)...
- puedes establecerlos en False (por omisión desde el tiempo de diseño o al inicio del procedimiento)

2) el siguiente código los busca con dos formatos (orden) de fechas, ya sea d/m/aa o m/d/aa
- el único requisito es que se use como separador el caracter " / "
- - (a menos que quieras alargar en 2 líneas más la fórmula implicada cambiando los "/" por "-" ?)

pros:
- carga "directa" al control de lista
- NO bucles
- NO rangos auxiliares
- NO Redim Preserve

contras:
- que el texto para el método Evaluate(... exceda de 255 caracteres (+/- 100+ registros ?)
- en ese caso, volvemos al Redim Preserve o... ??? :unsure:

Código:
Private Sub fechabusqueda_Change()
' procedimiento para cargar filas filtradas en controles de lista ' _
  base: R&D: Héctor Miguel Orozco Díaz (mayo de 2007) ' _
  adaptado para evitar el uso de "Redim Preserve", mejor conocido como pk² ' _
  (squared performance killer | asesino del rendimiento al cuadrado '
  Dim base As String, filas, mtz, n As Long: base = """" & fechabusqueda.Text & """"
  With Worksheets("hoja1")
    filas = Application.Transpose(Split(Application.Trim(Join(Application.Transpose(Evaluate(Replace( _
      "if((row('" & .Name & "'!a1:a#)=1)" & _
      "+(isnumber(search(" & base & ",text('" & .Name & "'!a1:a#,""d/m/yy""))))" & _
      "+(isnumber(search(" & base & ",text('" & .Name & "'!a1:a#,""m/d/yy""))))," & _
      "row('" & .Name & "'!a1:a#),"" "")", "#", .Cells(Rows.Count, "a").End(xlUp).Row)))))))
    mtz = Application.Index(.Cells, filas, [transpose(row(1:20))])
  End With: If UBound(filas) = 1 Then Listbox1.Clear: MsgBox "sin registro que coincida !": Exit Sub
  For n = 1 To UBound(mtz): mtz(n, 1) = Format(mtz(n, 1), "d/m/yyyy"): Next: Listbox1.List = mtz
End Sub
 
1) dado que no te interesan los encabezados en el control de lista (ya que tomas la fila 1 del rango de origen)...
- puedes establecerlos en False (por omisión desde el tiempo de diseño o al inicio del procedimiento)

2) el siguiente código los busca con dos formatos (orden) de fechas, ya sea d/m/aa o m/d/aa
- el único requisito es que se use como separador el caracter " / "
- - (a menos que quieras alargar en 2 líneas más la fórmula implicada cambiando los "/" por "-" ?)

pros:
- carga "directa" al control de lista
- NO bucles
- NO rangos auxiliares
- NO Redim Preserve

contras:
- que el texto para el método Evaluate(... exceda de 255 caracteres (+/- 100+ registros ?)
- en ese caso, volvemos al Redim Preserve o... ??? :unsure:

Código:
Private Sub fechabusqueda_Change()
' procedimiento para cargar filas filtradas en controles de lista ' _
  base: R&D: Héctor Miguel Orozco Díaz (mayo de 2007) ' _
  adaptado para evitar el uso de "Redim Preserve", mejor conocido como pk² ' _
  (squared performance killer | asesino del rendimiento al cuadrado '
  Dim base As String, filas, mtz, n As Long: base = """" & fechabusqueda.Text & """"
  With Worksheets("hoja1")
    filas = Application.Transpose(Split(Application.Trim(Join(Application.Transpose(Evaluate(Replace( _
      "if((row('" & .Name & "'!a1:a#)=1)" & _
      "+(isnumber(search(" & base & ",text('" & .Name & "'!a1:a#,""d/m/yy""))))" & _
      "+(isnumber(search(" & base & ",text('" & .Name & "'!a1:a#,""m/d/yy""))))," & _
      "row('" & .Name & "'!a1:a#),"" "")", "#", .Cells(Rows.Count, "a").End(xlUp).Row)))))))
    mtz = Application.Index(.Cells, filas, [transpose(row(1:20))])
  End With: If UBound(filas) = 1 Then Listbox1.Clear: MsgBox "sin registro que coincida !": Exit Sub
  For n = 1 To UBound(mtz): mtz(n, 1) = Format(mtz(n, 1), "d/m/yyyy"): Next: Listbox1.List = mtz
End Sub
Hola Hector, funciona perfecto.

Lo unico que le agregaria seria esta sentencia:

Código:
Listbox1.ColumnHeads = False


Sino se agrega eso, cuando generas el lisbox muestra esto (una serie de celdas arriba del encabezado):

c2.JPG

al colocarle esa sentencia que te puse arriba, ya se arregla y queda asi:

c1.JPG

entonces el codigo completo quedaria asi:

Código:
Private Sub fechabusqueda_Change()
' procedimiento para cargar filas filtradas en controles de lista ' _
  base: R&D: Héctor Miguel Orozco Díaz (mayo de 2007) ' _
  adaptado para evitar el uso de "Redim Preserve", mejor conocido como pk² ' _
  (squared performance killer | asesino del rendimiento al cuadrado '
  Dim base As String, filas, mtz, n As Long: base = """" & fechabusqueda.Text & """"
 Listbox1.ColumnHeads = False
  With Worksheets("hoja1")
    filas = Application.Transpose(Split(Application.Trim(Join(Application.Transpose(Evaluate(Replace( _
      "if((row('" & .Name & "'!a1:a#)=1)" & _
      "+(isnumber(search(" & base & ",text('" & .Name & "'!a1:a#,""d/m/yy""))))" & _
      "+(isnumber(search(" & base & ",text('" & .Name & "'!a1:a#,""m/d/yy""))))," & _
      "row('" & .Name & "'!a1:a#),"" "")", "#", .Cells(Rows.Count, "a").End(xlUp).Row)))))))
    mtz = Application.Index(.Cells, filas, [transpose(row(1:20))])
  End With: If UBound(filas) = 1 Then Listbox1.Clear: MsgBox "sin registro que coincida !": Exit Sub
  For n = 1 To UBound(mtz): mtz(n, 1) = Format(mtz(n, 1), "d/m/yyyy"): Next: Listbox1.List = mtz
End Sub



Muchas gracias por el aporte y el enfoque distinto que le diste. Saludos.
 

Héctor Miguel

Well-known member
Última edición:

Cacho R

Well-known member
Hola! protostecnologia
Como es una obviedad que te van a interesar los encabezados porque estás mostrando 15 columnas con información, el resultado del filtrado SIEMPRE tendrá que ir a parar a celdas y tomarlos de allí mediante RowSource.

Así que te dejo 4 maneras de hacerlo: la última forma ("Copiar y Pegar") parece ser la más eficiente, la que menos código requiere y la más alejada de códigos rebuscados o estrafalarios respetando los formatos de las 15 columnas (y no de solo una).

Saludos, Cacho R.
 
Última edición:
Hola! protostecnologia
Como es una obviedad que te van a interesar los encabezados porque estás mostrando 15 columnas con información, el resultado del filtrado SIEMPRE tendrá que ir a parar a celdas y tomarlos de allí mediante RowSource.

Así que te dejo 4 maneras de hacerlo: la última forma ("Copiar y Pegar") parece ser la más eficiente, la que menos código requiere y la más alejada de códigos rebuscados o estrafalarios respetando los formatos de las 15 columnas (y no de solo una).

Saludos, Cacho R.
Hola Cacho R. Muchas gracias por los aportes, realmente son de gran ayuda para mi, en esta etapa de puro aprendizaje.
Me siento un padwan jaja.

Quiero contarte que no sabia como realizar la medicion de la eficiencia y al ver tu codigo me di cuenta como realizarla.

Gracias a eso, pude determinar que de las 4 alternativas que me pasaste, en forma de ranking las mas eficientes son:
1)Indice
2)Recorset
3)Copiarypegar
4)Filtroavanzado

Es decir el Filtroavanzado seria el menos eficiente de los 4.

Y como conclusion final, esa medicion de la eficiencia la integre a mi propuesta de codigo y paradojicamente mi codigo tiene mas eficiencia a nivel de tiempos que el mejor de las propuestas que me enviaste.

Paso capturas:

Mi codigo, nivel de eficiencia con los mismos datos y el mismo ingreso en la busqueda: Tiempo 21.48 ms.

eficiencia1.PNG


El mejor de las propuestas que me enviaste (opcion indice): Tiempo 31.25 ms.


eficiencia2.PNG

Los otros metodos, Recorset, copiarypegar y filtro avanzado, tiraban de 48ms para arriba. (menos eficientes)

Con esto no quiero decir que mi codigo sea mas eficiente ni mucho menos, solo que en esa medicion mi codigo tiro un tiempo de respuesta menor y por ende en teoria mas eficiente.

Te agradezco mucho Cacho R por tus aportes y enseñanzas, realmente aprendo mucho con vos. Un gran saludo.
 

Cacho R

Well-known member
Con esto no quiero decir que mi codigo sea mas eficiente ni mucho menos, solo que en esa medicion mi codigo tiro un tiempo de respuesta menor y por ende en teoria mas eficiente.
Te cuento, mi estimado, que respecto de la medición de tiempos, habría que tener en cuenta varios detalles:
  • Es posible (de hecho me pasó en este caso) que en el mismo momento que estaba haciendo las pruebas, mi antivirus se estaba actualizando: eso distorsiona los resultados. Así como otras "distracciones" que pueden ocupar los recursos de tu máquina.
  • El primero de los códigos mostrados es IGUAL al tuyo (estudialo mejor y te vas a dar cuenta).
  • Pero el tuyo no muestra los títulos sino integrándolos al listBox: ¿Por qué?... Porque cargas los datos mediante "List" y no "RowSource" y de allí las milésimas de segundo de diferencia.
  • En ese sentido quiero que no pierdas de vista "un detalle" no menor y es que tu código termina dando formato-fecha a la columna de fecha: ¿Y si hubiese más columnas con fechas?... ¿Y si algunas columnas tuviesen números enteros y otras números con decimales?...
  • Todos estos detalles que tu código no tiene en cuenta terminarían por aumentar los tiempos de proceso y -ni hablar- aumentar la cantidad de código. Con "RowSource" todo eso ya está contemplado.
  • De hecho, tu código realiza muchísimos "ReDim" y el que mostré hace sólo uno.
  • ¿Conclusión?... Estás comparando cosas diferentes.
  • Y como te dije antes (aunque sería un cambio menor en tu código) si escribes "//19" no encuentras nada mientras que los 4 mostrados encuentran datos del año 2019.
  • Otro detalle a tener en cuenta en la medición de tiempos es la cantidad de casos: para medir tiempos yo hice -no menos- de 20 filtrados en cada propuesta, y de allí tomamos el valor promediado.
  • Si lo haces así, verás que quien se tarda más es el método basado en Recordset mientras que el basado en AdvancedFilter termina segundo.
  • ¿Y sabes qué?... Los valores promedio de tiempo terminan siendo -casi- similares y en el orden de los "milisegundos".
  • Por lo tanto -y desde mi punto de vista- son métodos equivalentes.
  • Sólo falta evaluar algo más de 400 filas con datos. Por ejemplo: 2 o 3 mil filas.
  • ¡Te dejo la inquietud!
Saludos, Cacho R.
 
¿Un Padawan?... ¡Estás viendo muchas películas ultimamente! (será por la pandemia)... Jajjjaja
Jja, soy poco peliculero. Pero me gusta la ciencia ficcion.

Te cuento, mi estimado, que respecto de la medición de tiempos, habría que tener en cuenta varios detalles:
  • Es posible (de hecho me pasó en este caso) que en el mismo momento que estaba haciendo las pruebas, mi antivirus se estaba actualizando: eso distorsiona los resultados. Así como otras "distracciones" que pueden ocupar los recursos de tu máquina.
  • El primero de los códigos mostrados es IGUAL al tuyo (estudialo mejor y te vas a dar cuenta).
  • Pero el tuyo no muestra los títulos sino integrándolos al listBox: ¿Por qué?... Porque cargas los datos mediante "List" y no "RowSource" y de allí las milésimas de segundo de diferencia.
  • En ese sentido quiero que no pierdas de vista "un detalle" no menor y es que tu código termina dando formato-fecha a la columna de fecha: ¿Y si hubiese más columnas con fechas?... ¿Y si algunas columnas tuviesen números enteros y otras números con decimales?...
  • Todos estos detalles que tu código no tiene en cuenta terminarían por aumentar los tiempos de proceso y -ni hablar- aumentar la cantidad de código. Con "RowSource" todo eso ya está contemplado.
  • De hecho, tu código realiza muchísimos "ReDim" y el que mostré hace sólo uno.
  • ¿Conclusión?... Estás comparando cosas diferentes.
  • Y como te dije antes (aunque sería un cambio menor en tu código) si escribes "//19" no encuentras nada mientras que los 4 mostrados encuentran datos del año 2019.
  • Otro detalle a tener en cuenta en la medición de tiempos es la cantidad de casos: para medir tiempos yo hice -no menos- de 20 filtrados en cada propuesta, y de allí tomamos el valor promediado.
  • Si lo haces así, verás que quien se tarda más es el método basado en Recordset mientras que el basado en AdvancedFilter termina segundo.
  • ¿Y sabes qué?... Los valores promedio de tiempo terminan siendo -casi- similares y en el orden de los "milisegundos".
  • Por lo tanto -y desde mi punto de vista- son métodos equivalentes.
  • Sólo falta evaluar algo más de 400 filas con datos. Por ejemplo: 2 o 3 mil filas.
  • ¡Te dejo la inquietud!
Saludos, Cacho R.
Entiendo todo el analisis que me comentas. Voy a probar con mas datos en las filas.
Y voy a corregir el tema de los titulos.

Hay cosas en el codigo que propusiste que no alcanzo a comprender aun. Pero se ve muy interesante.

Un gran saludo y mil gracias como siempre.
 
Arriba