2017-12-21 2 views
0

어떻게 다차원 배열을 필터링 할 수 있습니까?Excel VBA의 필터 배열

내 코드도 일을하지 않으며 깔끔한 보인다 :

Option Explicit 
Sub CalcE() 
Dim TotalRows As Long 
Dim myArray, myArray2 As Variant 
Dim i, a As Integer 

채우기 배열 myArray2에

TotalRows = Sheets("Data").Rows(Rows.Count).End(xlUp).Row 
myArray = Sheets("Data").Range("A5:F" & TotalRows) 
MsgBox "Array populated with " & UBound(myArray) & "entries." 

필터에서 myArray 항목 만 열 1, 4, 6

a = 0 
For i = 0 To UBound(myArray) 
    If myArray(i, 1) > 1 Then 
     myArray2(a, 1) = myArray(i, 1) 
     myArray2(a, 2) = myArray(i, 4) 
     myArray2(a, 3) = myArray(i, 6) 
     a = a + 1 
    End If 
Next i  
MsgBox "Array populated now with " & UBound(myArray2) & "entries." 
End Sub 

저는 인터넷 검색이 매우 유연하지 않은 것 같아서 잘 작동하지 않는 것 같았습니다. 사람들은 대개 VBA 배열을 포기하고 대신 AutoFilter 메서드를 사용합니다. 나는 정말로 좋은 방법이 아닌지에 관해 깨닫는다. 가지고있는 것은 매우 산뜻 할 것이다! 모두 당신이 필요 myArray2에 열 1, 4, 6을 저장하는 경우

답변

1

, ... ...이 시도

Dim ws As Worksheet 
Set ws = Sheets("Data") 
TotalRows = ws.Rows(Rows.Count).End(xlUp).Row 
myArray2 = Application.Index(ws.Cells, Evaluate("Row(5:" & TotalRows & ")"), Array(1, 4, 6)) 

를 제공하거나이 같은 코드를 조정할 수 있습니다

Dim ws As Worksheet 
Set ws = Sheets("Data") 
Dim cnt As Long, j As Long 
TotalRows = ws.Rows(Rows.Count).End(xlUp).Row 
myArray = ws.Range("A5:F" & TotalRows).Value 
cnt = Application.CountIf(ws.Range("A5:A" & TotalRows), ">1") 
If cnt = 0 Then Exit Sub 
ReDim myArray2(1 To cnt, 1 To 3) 
For i = 1 To UBound(myArray, 1) 
    If myArray(i, 1) > 1 Then 
     j = j + 1 
     myArray2(j, 1) = myArray(i, 1) 
     myArray2(j, 2) = myArray(i, 4) 
     myArray2(j, 3) = myArray(i, 6) 
    End If 
Next i 

MsgBox UBound(myArray2, 1) 
+0

감사합니다. 하지만 어떻게 필터링 할 수 있습니까? 예를 들어, 1 열에서 1보다 작은 값을 가진 모든 항목을 제거하려고합니다. – Bendaua

+0

이 경우 응답에 표시된대로 코드를 조정할 수 있습니다. 편집 된 답변을 참조하십시오. – sktneer

+0

이것은 내 문제를 해결하고 루프 내 ReDim을 피할 수 있습니다. 다시 한번 감사드립니다. – Bendaua

0

배열은 매우 유연하지 않은 : 당신이 Redim Preserve를 사용하여 그렇게 할 수 있지만, 특히 쉽지는 (크기를 조정하면 WA 경우

는 개인적으로 내가 컬렉션을 사용합니다. 항목 수를 가변하고 VBA에서 항목을 필터링하려고합니다.

먼저 2D 배열의 열을 나타내는 속성 또는 필드를 사용하여 클래스 모듈을 정의합니다. 당신은 클래스를 제공해야하며 속성에게 의미있는 이름, 적절한 데이터 형식을,하지만 그래서 내가 사용하는 것입니다 응용 프로그램을 모르는 :

Class Module "MyClass": 

    Public Col1 As Variant 
    Public Col4 As Variant 
    Public Col6 As Variant 

그런 다음 컬렉션을 만들 수에 클래스의 인스턴스를 추가 다음과 같이 당신이 엑셀 시트로 다시 쓸 수 있도록

Dim col2 As Collection 
Set col2 = New Collection 
For Each c In col 
    If c.Col1 = 5 Then 
     col2.Add c 
    End If 
Next c 

그리고 마지막으로 2 차원 배열로 다시 복사 :

Dim col As Collection 
Set col = New Collection 
For i = LBound(myArray, 1) To UBound(myArray, 1) 
    If myArray(i, 1) > 1 Then 
     Dim c As MyClass 
     Set c = New MyClass 
     c.Col1 = myArray(i, 1) 
     c.Col4 = myArray(i, 4) 
     c.Col6 = myArray(i, 6) 
     col.Add c 
    End If 
Next I 

그런 다음, 더 예를 들어 그것을 필터링 할 수 있습니다

Dim myArray2() As Variant 
Dim c As MyClass 
ReDim myArray2(0 To col2.Count - 1, 0 To 6) 
For i = 0 To col2.Count - 1 
    Set c = col2(i + 1) ' Collection indexes are 1-based 
    myArray2(i, 1) = c.Col1 
    myArray2(i, 4) = c.Col4 
    myArray2(i, 6) = c.Col6 
Next i 

당신도 strongly-typed collectionMyClass의 오브젝트, 링크 된 블로그 문서에 설명 된대로 클래스 모듈 MyClassCollection 인 클래스 모듈을 작성할 수 있습니다.