Supongo que desea utilizar solo VBA.
Creo que depende de varios parámetros, principalmente en:
- con qué frecuencia se ejecuta la misma condición => ¿Almacena el resultado de un filtro o qué vuelve a calcular cada vez?
- con qué frecuencia necesita filtrar material => si con frecuencia, vale la pena tener una estructura de código adecuada en su lugar, si no, entonces un bucle único es claramente el camino a seguir.
Desde una perspectiva OO, suponiendo que el rendimiento (velocidad & memoria) no es un problema, me gustaría ir para el siguiente diseño (no voy a entrar en los detalles de la aplicación, sólo dan la idea general). Cree una clase (llamémoslo imaginativamente ArrayFilter) que pueda usar así.
de configuración del filtro
Dim filter As New ArrayFilter
With filter
.name = "sam"
.category = "Medium"
.maxValue = 10
End With
O
filter.add(1, "sam") 'column 1
filter.add(3, "Medium") 'column 3
filter.addMax(2, 10) 'column 2
Crear los datos filtrados establecen
filteredArray = getFilteredArray(originalArray, filter)
El getFilteredArray es bastante sencillo de auto e: se recorre la matriz de comprobar si los valores coinciden con el filtro y poner las líneas válidos en una nueva matriz:
If filter.isValidLine(originalArray, lineNumber) Then 'append to new array
Pros
- Diseño limpio
- reutilizable, especialmente con la segunda versión donde usa el número de columna. Esto se puede usar para filtrar cualquier arrays realmente.
código
- filtrado está en una función que se puede probar
- Corolario: evitar la duplicación de código
Contras
- de filtrado se vuelve a calcular cada vez, incluso si se utiliza el mismo filtro dos veces. Puede almacenar los resultados en un diccionario, por ejemplo, ver a continuación.
- Memoria: cada llamada a getFilteredArray crea una nueva matriz, pero no estoy seguro de cómo se puede evitar de todos modos
- Esto agrega bastantes líneas de código, así que lo haría solo si ayuda a hacer que el código sea más fácil leer/mantener
ps: Si necesita almacenar en caché los resultados para mejorar el rendimiento, una manera sería almacenar los resultados en un diccionario y agregar algo de lógica a la función getFilteredArray. Tenga en cuenta que a menos que sus matrices sean realmente grandes y/o ejecute el mismo filtro mucho, probablemente esto no valga la pena.
filters.add filter, filteredArray 'filters is a dictionary
De esta manera, cuando se llama getFilteredArray próxima vez, se puede hacer algo como esto:
For each f in filters
'Check if all conditions in f and newFilter are the same
'If they are:
getFilteredArray = filters(f)
Exit Function
Next
'Not found in cache: compute the result
Tenga en cuenta que el cuarto ejemplo no es un filtro, sino una operación en la matriz, lo que probablemente conduzca a una respuesta diferente. – assylias
No estoy seguro de que sea posible sin las funciones de bucle/personalizado en VBA. Usted dice que tiene experiencia en otros idiomas, ¿ha considerado una impedancia de VSTO/.NET y luego utiliza LINQ? –
Para este tipo de cosas en VBA usaría un conjunto de registros ADO desconectado. Te da clasificación y filtrado. –