descargar mas rapido seleccion multiple en listbox

13/12/2006 - 01:37 por Ivan | Informe spam
hola a todos

tengo un formulario con un listbox con 4 columnas y seleccion multiple,
que se carga con los registros de una hoja ("Oculta"), que a su vez se
carga con los de otra ("Listado") filtrados por lo escrito en un
combo.

Un commandbutton (cmdActualizarFavoritos) permite cargar los registros
seleccionados (que no esten ya) en el listbox (lstSeleccionar) en otra
hoja ("Favoritos").

a su vez otro boton (cmdSeleccionarTodos) hace lo que su nombre indica,
seleccionar todos los registros del listbox, que, aunque serian muy
extraño, podrian llegar a ser hasta 10000. En realidad lo normal es
que sean bastantes menos, pues para algo esta el 'filtro'.

en mis pruebas el maximo que se carga tras escribir la primera letra en
el combo, ronda los 4500

Desde aqui el usuario tiene varias opciones, pero si selecciona todos
cuando la cantidad es muy alta y los añade a "Favoritos", viene a
tardar en torno a los 15 segundos (para 4400), tiempo que, aunque no es
excesivo para algo que sera muy raro que ocurra (una seleccion tan
amplia), y que incluso se puede avisar en estas ocasiones, si me
gustaria saber de que forma se podria disminuir.

he pensado en los filtros avanzados o en los autofiltros, pero no se
como los podria utilizar en esta ocasion, compatibilizando a la vez la
busqueda de elementos seleccionados en el listbox y de no repetidos en
"Favoritos"

de momento, y tras bastantes pruebas, me he decantado por esta opcion,
que es la que me ha dado el mejor tiempo, aunque tendre que unirla a
otra que es mucho mas rapida cuando los registros son pocos y que
supongo que tendre que condicionar al nº de registros seleccionados

Private Sub cmdActualizarFavoritos_Click()
Dim nSel As Long, CeldaO As Range, tCol As Long, tcol2 As Long
Dim tarda, x As Long
''pasa los libros seleccionados en lstSeleccionar a_
''la hoja "Favoritos"
tarda = Timer * 1000
With lstSeleccionar
tCol = .TextColumn: .TextColumn = 1
Application.ScreenUpdating = False
For nSel = 0 To .ListCount - 1
If .Selected(nSel) = True Then
On Error Resume Next
If BuscaFilas(CLng(.List(nSel)), "Favoritos") > 0 Then
Worksheets("Oculta").Range("a" & nSel + 2 & ":z" & nSel +
2).Hidden = True
End If
On Error GoTo 0
End If
Next
.TextColumn = tCol
Application.ScreenUpdating = True
End With
With Worksheets("Oculta")
With .UsedRange.Cells.SpecialCells(xlCellTypeVisible)
.Offset(1).Resize(.Rows.Count - 1, .Columns.Count).Copy _
Worksheets("Favoritos").[a65536].End(xlUp).Offset(1, 0)
End With
.Rows.Hidden = False
End With
txtLibrosSeleccionados = 0
tarda = (Timer * 1000) - tarda
Debug.Print "tarda -> " & tarda
End Sub
'*****************************************************
Public Function BuscaFilas(ByVal Valor As Long, _
ByVal nHoja As String) As Long
On Error Resume Next
BuscaFilas = Evaluate("match(" & Valor & "," & nHoja & "!a:a,0)")
On Error GoTo 0
End Function


bueno, si se os ocurre algo sera bien recibido

un saludo y hasta pronto
Ivan

Preguntas similare

Leer las respuestas

#6 Ivan
16/12/2006 - 02:18 | Informe spam
hola y gracias de nuevo, Hector Miguel

creo que peco (entre otras muchas cosas ) de exceso de labia y falta de
concreccion. Voy a ver si me explico ->

-> para una 'carga' de elementos sin duplicados, puedes emplear diferentes metodos [p.e.]
- los filtros avanzados, objetos 'Dictionary', objetos 'Collection' [para no muchos elementos], etc.
[dependera de numero de elementos y probablemente otras 'circunstancias'] ;)



es uno de mis planteamientos iniciales, el problema esta en el doble
barrido, y en si resultaria productivo filtrar/desfiltrar/refiltrar
pongamos 4000 veces, dado que hay que comprobar si cada registro
seleccionado en el listbox esta ya en la hoja favoritos y si no es asi
agregarlo, o sea ->

1º comprobar si esta seleccionado el elemento en el listbox.
2º Comprobar si ya esta en la lista de favoritos
3º agregarlo a favoritos si no esta

en general funciona razonablemente bien (de varias maneras) cuando el
nº de elementos seleccionados no es demasiado grande (para 700
registros ronda los 2/3 segundos, dependiendo del numero de registros
que ya haya en favoritos, tiempo que no me parece mal)

-> [supongo que] cuando se 'deban/decida/...' seleccionar TODOS los elementos del control de lista...
[probablemente] te convendria 'mantener' una lista 'aparte' [p.e. la que se hubiera utilizado para el llenado del control] -?-



la lista que llena el control es la hoja "Oculta" y es el resultado de
filtrar (gracias a tus consejos y ayudas) un listado general. Aparte
tengo otra hoja ("Seleccion"(y tambien 'oculta')) que se actualiza con
los registros de/seleccionados, excepto cuando se seleccionan/borran
todos, caso en el que directamente pego/borro todos los registros sin
pasar para esto por el listbox.

esta hoja la utilizo para poder trabajar con los registros aunque no se
hayan cargado en una hoja 'visible', y en las ultimas pruebas que estoy
haciendo es la que uso para actualizar favoritos, aunque el doble bucle
sigue resultandome inevitable.

de todas formas creo que como está ahora (+o- 22sg para 4500 registros
seleccionados) es bastante aceptable. Es cuestion de avisarle al
usuario de que ha selecciondo agregar tropecientos registro y que eso
tiene su costo en tiempo.

en cuanto al posible uso de colecciones, aparte de mi poca mano con
ellas, pensaba que seria mas lento. Aunque segun escribo esto se me
ocurre que quizas teniendo una coleccion ya con los registros
contrenidos en favoritos y asignandole los del listbox, pero solo
admitiendo unicos, a lo mejor si es practico. Lo mismo me lio a
tantearlo.

> por cierto he cambiado el '= 0' final por '> 0', que me da la impresion que es lo que querias poner. o es otra de mis meteduras de pata?
> quizas era a esto, a lo que te referias con esta frase? ->



en realidad estas dos frases eran independientes (lo del 0 lo suponia,
pero por si acaso tenias algun motivo que se me escapaba) la segunda se
referia a lo que iba detras (sobre el/los barridos)

-> [hasta donde se] existen 'prioridades' en el orden de 'evaluacion' de instrucciones en codigo
aunque [siendo honesto]... no 'veo' por donde 'encaja la pregunta' en el orden de esta consulta [bucles ?, estructuras ?, ???]



en realidad era una consulta totalmente aparte, sobre la estructura de
ese tipo de setencias <triple igualdad>,

desde mi ignorancia, y hasta que ultimamente la he visto en el foro (en
general creo que para asignar un valor boolean a la primera parte de la
igualdad), siempre hubiera pensado que no tendria sentido y que
devolveria error. Y, dado que me parece una forma muy interesante de
matar dos pajaros de un tiro (expresion no demasiado afortunada) te
consultaba por saber un poco mas sobre su uso/funcionamiento.

bueno disculpa el rollo de nuevo

un saludo y hasta pronto
Ivan
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una pregunta AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida