2009-09-02 1 views
8

다음은 값 범위를 사용하여 Sheet1 워크 시트 (목록 범위)의 A 열에 고급 필터를 적용하는 코드입니다. Sheet2 (조건 범위)Excel (VBA)에서 고급 필터를 적용한 후 보이는 행의 범위를 얻는 방법

Range("A1:A100").AdvancedFilter Action:=xlFilterInPlace, CriteriaRange:= _ 
     Sheets("Sheet2").Range("A1:A10"), Unique:=False 

이 코드를 실행 한 후에는 현재 화면에 표시되는 행을 사용해야합니다.

현재 나는 눈에 보이는 고급 필터를 적용한 후 나에게 행의 범위를 줄 수있는 간단한 속성이 있나요이

For i = 1 to maxRow 
    If Not ActiveSheet.Row(i).Hidden then 
    ...do something that I need to do with that rows 
    EndIf 
Next 

같은 코드를 사용?

답변

14
ActiveSheet.Range("A1:A100").Rows.SpecialCells(xlCellTypeVisible) 

이렇게하면 Range 개체가 생성됩니다.

+1

감사합니다. Excel 2007에서 작동합니다. Excel 2003에서 확인합니다. –

15

랜스의 솔루션은 대부분의 상황에서 작동합니다.

큰/복잡한 스프레드 시트를 처리하는 경우 "SpecialCells Problem"으로 실행될 수 있습니다. 간단히 말해, 생성 된 범위가 연속되지 않는 영역이 8192 개 이상일 경우 (이 될 수 있음) 그러면 SpecialCell에 액세스하려고 시도 할 때 Excel에서 오류가 발생하고 코드가 실행되지 않습니다. 워크 시트가 충분히 복잡하여이 문제가 발생할 것으로 예상되는 경우 루핑 방식을 계속 사용하는 것이 좋습니다.

이 문제는 SpecialCells 속성 자체가 아니라, Range 개체와 관련이 있습니다. 즉, 매우 복잡 할 수있는 범위 객체를 얻으려고 시도 할 때마다 직원에게 오류 처리기를 지정하거나 이미 수행 한대로 수행해야합니다. 이는 프로그램이 범위의 각 요소에서 작동하게합니다. 범위 위로).

다른 가능한 접근법은 Range Objects 배열을 반환 한 다음 배열을 반복하는 것입니다. 나는 주변에서 놀기 위해 몇 가지 예제 코드를 게시했다. 그러나 문제가 설명되어지기를 기대하거나 코드가 튼튼하다는 것을 확신하기를 원한다면 정말로 걱정해야합니다. 그렇지 않으면 단지 불필요한 복잡성 일뿐입니다. 이 도움이

Excel.Range visibleRange = Excel.Application.ActiveWindow.VisibleRange 

희망 :


Option Explicit 

Public Declare Function GetTickCount Lib "kernel32"() As Long 

Public Sub GenerateProblem() 
    'Run this to set up an example spreadsheet: 
    Dim row As Long 
    Excel.Application.EnableEvents = False 
    Sheet1.AutoFilterMode = False 
    Sheet1.UsedRange.Delete 
    For row = 1 To (8192& * 4&) + 1& 
     If row Mod 3& Then If Int(10& * Rnd) 7& Then Sheet1.Cells(row, 1&).value = "test" 
    Next 
    Sheet1.UsedRange.AutoFilter 1&, "" 
    Excel.Application.EnableEvents = True 
    MsgBox Sheet1.UsedRange.SpecialCells(xlCellTypeVisible).address 
End Sub 

Public Sub FixProblem() 
    'Run this to see various solutions: 
    Dim ranges() As Excel.Range 
    Dim index As Long 
    Dim address As String 
    Dim startTime As Long 
    Dim endTime As Long 
    'Get range array. 
    ranges = GetVisibleRows 
    'Do something with individual range objects. 
    For index = LBound(ranges) To UBound(ranges) 
     ranges(index).Interior.ColorIndex = Int(56 * Rnd + 1) 
    Next 

    'Get total address if you want it: 
    startTime = GetTickCount 
    address = RangeArrayAddress(ranges) 
    endTime = GetTickCount 
    Debug.Print endTime - startTime, ; 'Outputs time elapsed in milliseconds. 

    'Small demo of why I used a string builder. Straight concatenation is about 
    '10 times slower: 
    startTime = GetTickCount 
    address = RangeArrayAddress2(ranges) 
    endTime = GetTickCount 
    Debug.Print endTime - startTime 
End Sub 

Public Function GetVisibleRows(Optional ByVal ws As Excel.Worksheet) As Excel.Range() 
    Const increment As Long = 1000& 
    Dim max As Long 
    Dim row As Long 
    Dim returnVal() As Excel.Range 
    Dim startRow As Long 
    Dim index As Long 
    If ws Is Nothing Then Set ws = Excel.ActiveSheet 
    max = increment 
    ReDim returnVal(max) As Excel.Range 
    For row = ws.UsedRange.row To ws.UsedRange.Rows.Count 
     If Sheet1.Rows(row).Hidden Then 
      If startRow 0& Then 
       Set returnVal(index) = ws.Rows(startRow & ":" & (row - 1&)) 
       index = index + 1& 
       If index > max Then 
        'Redimming in large increments is an optimization trick. 
        max = max + increment 
        ReDim Preserve returnVal(max) As Excel.Range 
       End If 
       startRow = 0& 
      End If 
     ElseIf startRow = 0& Then startRow = row 
     End If 
    Next 
    ReDim Preserve returnVal(index - 1&) As Excel.Range 
    GetVisibleRows = returnVal 
End Function 

Public Function RangeArrayAddress(ByRef value() As Excel.Range, Optional lowerindexRV As Variant, Optional upperindexRV As Variant) As String 
    'Parameters left as variants to allow for "IsMissing" values. 
    'Code uses bytearray string building methods to run faster. 
    Const incrementChars As Long = 1000& 
    Const unicodeWidth As Long = 2& 
    Const comma As Long = 44& 
    Dim increment As Long 
    Dim max As Long 
    Dim index As Long 
    Dim returnVal() As Byte 
    Dim address() As Byte 
    Dim indexRV As Long 
    Dim char As Long 
    increment = incrementChars * unicodeWidth 'Double for unicode. 
    max = increment - 1& 'Offset for array. 
    ReDim returnVal(max) As Byte 
    If IsMissing(lowerindexRV) Then lowerindexRV = LBound(value) 
    If IsMissing(upperindexRV) Then upperindexRV = UBound(value) 
    For index = lowerindexRV To upperindexRV 
     address = value(index).address 
     For char = 0& To UBound(address) Step unicodeWidth 
      returnVal(indexRV) = address(char) 
      indexRV = indexRV + unicodeWidth 
      If indexRV > max Then 
       max = max + increment 
       ReDim Preserve returnVal(max) As Byte 
      End If 
     Next 
     returnVal(indexRV) = comma 
     indexRV = indexRV + unicodeWidth 
     If indexRV > max Then 
      max = max + increment 
      ReDim Preserve returnVal(max) As Byte 
     End If 
    Next 
    ReDim Preserve returnVal(indexRV - 1&) As Byte 
    RangeArrayAddress = returnVal 
End Function 

Public Function RangeArrayAddress2(ByRef value() As Excel.Range, Optional lowerIndex As Variant, Optional upperIndex As Variant) As String 
    'Parameters left as variants to allow for "IsMissing" values. 
    'Code uses bytearray string building methods to run faster. 
    Const incrementChars As Long = 1000& 
    Const unicodeWidth As Long = 2& 
    Dim increment As Long 
    Dim max As Long 
    Dim returnVal As String 
    Dim index As Long 
    increment = incrementChars * unicodeWidth 'Double for unicode. 
    max = increment - 1& 'Offset for array. 
    If IsMissing(lowerIndex) Then lowerIndex = LBound(value) 
    If IsMissing(upperIndex) Then upperIndex = UBound(value) 
    For index = lowerIndex To upperIndex 
     returnVal = returnVal & (value(index).address & ",") 
    Next 
    RangeArrayAddress2 = returnVal 
End Function 
+1

+1 그렇다면 SO가 굉장합니다. –

+0

[참고 :이 문제는 Excel 2010에서 수정되었습니다. Excel 2010에서 선택할 수있는 인접하지 않은 셀 : 2,147,483,648 셀] (https : //www.rondebruin.nl/win/s4/win003.htm) – danieltakeshi

1

당신은 세포의 가시 범위를 얻기 위해 다음 코드를 사용할 수 있습니다.

+0

잘못된 것입니다. 이것은 창에서 볼 수있는 셀 범위를 나타내며 숨겨진 행의 문제를 실제로 무시합니다. 윈도우의 왼쪽 상단에 보이는 셀에서부터 윈도우의 오른쪽 하단에 보이는 셀까지의 범위 ... – epeleg

관련 문제