El filtrado de la Columna en función de la Gama de VBA

Actualmente estoy trabajando con los datos de un mainframe, no a diferencia de los datos que se presentan aquí. En este caso, todo lo que tengo son cadenas semejante a 100-AAA para mi criterio y mi objetivo conjunto de datos. He buscado una solución similar, pero no he encontrado un directo filtrar por rango de cuestión de VBA en TAN.

Estoy tratando de filtro de un gran conjunto de datos basado en una serie de criterios. Originalmente, empecé a jugar con las colecciones en clases separadas/subrutinas, pero luego me comprimido para el uso de los rangos dentro de una sola subrutina, de la siguiente manera:

Sub FilterTest1()

Dim RngOne As Range
Dim LastCell As Long

Sheets("Criteria").Activate
Sheets("Criteria").Select
Range("A1").Select

LastCell = Application.WorksheetFunction.CountA(ActiveSheet.Range("A:A"))

Set RngOne = ActiveSheet.Range("A2:A" & LastCell)

Sheets("Sheet 1").Activate
Sheets("Sheet 1").Select

With ActiveSheet
    If .FilterMode Then
    .ShowAllData
    End If
End With

Columns("A:A").Select
Selection.AutoFilter
ActiveSheet.Range("A:A").AutoFilter Field:=1, Criteria1:=RngOne, Operator:=xlOr

End Sub

Por desgracia, mi rango de celdas no filtrar los datos, incluso cuando se utilizan criterios tales como Operator:=xlOr – sólo muestra el último valor de la celda utilizada para los criterios. El código de VBA no falla – simplemente no filtra correctamente basándose en el rango.

Tengo la certeza de que no existe una solución simple, pero yo no puedo ver.

  • Hizo considerar el uso de ADO de modo que usted puede utilizar comandos SQL para hacer el filtrado (pero aún con Excel)? La realización de un inner join entre sus criterios y el conjunto de datos podría encajar el proyecto de ley
  • Hace esto antes de responder a una pregunta similar de ayuda stackoverflow.com/a/7863452/53614 ? Yo uso ADO en las máquinas en el trabajo donde no tengo derechos de administrador y funciona bien. YMMV pero vale la pena darle una oportunidad
  • Bien; voy a darle un tiro durante el fin de semana y ver cómo se despliega a principios de la próxima semana. Puede ser bien vale la pena utilizar ADO para algunos de mis grandes conjuntos de datos, como cualquier cosa de confiar en SQL es probable que para ejecutar mucho más rápido en el largo plazo. Si funciona, bien que significa otro +1 por tu respuesta =)

2 Kommentare

  1. 8

    Su actual línea:

    ActiveSheet.Range("A:A").AutoFilter Field:=1, Criteria1:=RngOne, Operator:=xlOr

    está tratando de filtrar el primer campo por un Range objeto, no por cada valor del rango.

    Me ha proporcionado una manera para hacer esto más adelante, por la carga de sus valores en un array y luego transferirlo a los criterios de filtro.

    Un par de puntos que vale la pena destacar para ayudar a usted (y a cualquier otra persona en el futuro):

    • Me enteré de la sintaxis correcta para filtrar en una selección de objetos utilizando la grabadora de macros.
    • Este sitio me ayudó a aprender acerca de la matriz truco: Pasar de la Matriz de Criterios de Filtro
    • También he limpiado el código para hacerlo más eficiente y más rápido, por deshacerse de inútil instrucciones select y tal. (No es una gran oferta para este poco de código, pero salir de esa práctica te ayudará para proyectos más grandes!)

    Código De Abajo:

    Sub FilterTest1()
    
    Dim RngOne As Range, cell As Range
    Dim LastCell As Long
    Dim arrList() As String, lngCnt As Long
    
    With Sheets("Criteria")
        LastCell = .Range("A" & Sheets("Criteria").Rows.Count).End(xlUp).Row
        Set RngOne = .Range("A2:A" & LastCell)
    End With
    
    'load values into an array
    lngCnt = 0
    For Each cell In RngOne
        ReDim Preserve arrList(lngCnt)
        arrList(lngCnt) = cell.Text
        lngCnt = lngCnt + 1
    Next
    
    
    With Sheets("Sheet 1")
    
        If .FilterMode Then .ShowAllData
    
        .Range("A:A").AutoFilter Field:=1, Criteria1:=arrList, Operator:=xlFilterValues
    
    End With
    
    End Sub
    • Hola Scott, creo que ver a dónde va con esto de usar un array de strings como los criterios en lugar de un rango. Como para la limpieza del código – muchas gracias, me van regularmente a través de 10.000 filas a la vez. Sin embargo, cuando he probado el código, me encontré con un «no coincide el tipo de» mensaje de error. Después de entrar en el código y comprobar el resto de la sintaxis del código, se produce en la línea 25: .Range("A:A").AutoFilter Field:=1, Criteria1:=Array(strList), Operator:=xlFilterValues . ¿Usted sabe por qué puede ser que ocurran? El resto del código parece funcionar correctamente.
    • Hizo ver editado mi respuesta? He arreglado ese problema en mi original (pero eliminado) post.
    • Voy a probar ahora – acabo de volver en. =)
    • Probado – una coincidencia exacta de los criterios. Parece una matriz hace el trabajo muy bien. Tuve grandes y de conmutación para el marco de trabajo de colecciones, diccionarios y hashsets tanto como sea posible en C# para fines de ordenación, pero las operaciones que se pueden hacer con las matrices parecen funcionar mejor para VBA. En el fondo, yo espero un fuerte, genérico O solución, y es probable que un post Q hacia ese fin, tal vez en codereview.stackexchange. Dicho esto, su respuesta es excelente, y se hace el trabajo mucho más rápido que el bucle recursivo que he usado que se estrelló mi hoja de excel 😉
  2. 3

    Una cosa a tener en cuenta es que el Criteria1 requiere que las variables de cadena como argumento. Usted puede asignar un rango de una matriz, a continuación, pasar a la string de la matriz de los criterios. Otra nota es que para pasar una matriz a los criterios que, a mi conocimiento, que tiene que ser en una fila, no una columna, por ejemplo. StringArray(0,3) en lugar de StringArray(3,0). Por lo tanto ¿por qué usted estaba recibiendo el último valor en su rango. Sólo uso Application.Transpose(StringArray) a convertir en una fila.

    De este pedacito de código que funciona para mí, y es fácilmente ampliado para mayor matrices.

    Sub test()
    Dim StringArray(0, 1 To 3) As String 'This is a fixed dimension of an array, you can easily change to dynamic by using the ReDim statement.
    ActiveSheet.AutoFilterMode = False 'To reset autofilter
    
    Range("D3:D5").Select
    
    For c = 1 To 3 'Step through the range that you wish to use as the criteria.
    StringArray(0, c) = CStr(Selection(c, 1).Value)
    Next
    
    Range("A:A").AutoFilter Field:=1, Criteria1:=StringArray, Operator:=xlFilterValues
    
    End Sub
    • Su explicación es útil y añade a la aceptación de la respuesta. +1

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea