2012-06-01 163 views
30

Si tengo un filtro automático configurado en Excel y quiero recorrer todos los datos visibles en una columna con código VBA, ¿cuál es la forma más fácil de hacerlo?¿La forma más fácil de recorrer una lista filtrada con VBA?

No se deben incluir todas las filas ocultas que se han filtrado, por lo que un rango simple de arriba a abajo no ayuda.

¿Alguna buena idea? Gracias.

Respuesta

45

Supongamos que tengo los números del 1 al 10 en las celdas A2:A11 con mi autofiltro en A1. Ahora filtro para mostrar solo números mayores que 5 (es decir, 6, 7, 8, 9, 10).

Este código sólo se imprimirá celdas visibles:

Sub SpecialLoop() 
    Dim cl As Range, rng As Range 

    Set rng = Range("A2:A11") 

    For Each cl In rng 
     If cl.EntireRow.Hidden = False Then //Use Hidden property to check if filtered or not 
      Debug.Print cl 
     End If 
    Next 

End Sub 

Tal vez hay una manera mejor con SpecialCells pero lo anterior trabajó para mí en Excel 2003.

EDITAR

acaba de encontrar una mejor manera con SpecialCells:

Sub SpecialLoop() 
    Dim cl As Range, rng As Range 

    Set rng = Range("A2:A11") 

    For Each cl In rng.SpecialCells(xlCellTypeVisible) 
     Debug.Print cl 
    Next cl 

End Sub 
+0

Gracias por todas las respuestas! Todos eran más o menos lo mismo (el uso de SpecialCells (xlCellTypeVisible) era la clave que necesitaba) por lo que es difícil elegir cuál es la correcta. – mattboy

8

Una forma de asumir los datos filtrados en A1 hacia abajo;

dim Rng as Range 
set Rng = Range("A2", Range("A2").End(xlDown)).Cells.SpecialCells(xlCellTypeVisible) 
... 
for each cell in Rng 
    ...  
11

yo recomendaría usar Offset suponiendo que las cabeceras están en la fila 1. Vea este ejemplo

Option Explicit 

Sub Sample() 
    Dim rRange As Range, filRange As Range, Rng as Range 
    'Remove any filters 
    ActiveSheet.AutoFilterMode = False 

    '~~> Set your range 
    Set rRange = Sheets("Sheet1").Range("A1:E10") 

    With rRange 
     '~~> Set your criteria and filter 
     .AutoFilter Field:=1, Criteria1:="=1" 

     '~~> Filter, offset(to exclude headers) 
     Set filRange = .Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow 

     Debug.Print filRange.Address 

     For Each Rng In filRange 
      '~~> Your Code 
     Next 
    End With 

    'Remove any filters 
    ActiveSheet.AutoFilterMode = False 
End Sub 
+0

Esta es una buena manera de resolver el problema. Me gusta tu enfoque. –

+1

Buena solución Sid. Sin embargo, sería muy cuidadoso al usar 'SpecialCells'. Recientemente me enfrenté a un problema por la forma en que Excel envía la '.Address' de estas celdas (en función de sus apariciones continuas). –

+0

@PankajJaju: Lo siento, no te entendí. ¿Podrías por favor explicar a qué te refieres? quizás con un ejemplo? –

-1
Call MyMacro() 

ActiveCell.Offset(1, 0).Activate 

Do Until Selection.EntireRow.Hidden = False 
If Selection.EntireRow.Hidden = True Then 
ActiveCell.Offset(1, 0).Activate 
End If 
Loop 
+1

Sería útil si proporciona alguna explicación de lo que hace el código. –

Cuestiones relacionadas