※ 오늘 Daily Tip은 곽승주님이 제공해주신 내용입니다오늘은 필터링 하는 예를 하나 만들어 보려고 합니다.
엑셀에서 제공하는 필터링 도구에는 자동필터와 고급필터가 있습니다.
물론 여기에서 소개하는 예가 엑셀이 제공하는 것 만큼 잘
만들어진 것은 아니지만 여러 가지 이유로 종종 직접 만들어서 사용하고 싶은 경우가 생길 것입니다.
예를 들어 다음과 같은 NorthWind.mdb 파일의
내용에서 공급업체를 필터링 해보도록 하겠습니다.

위의 내용을 Worksheet에 복사하여 다음과 같이
화면을 구성하였습니다.

Sheet2의 A2셀에는 컨트롤 도구상자의 ComboBox를 두었습니다. 그리고 코드는 일반모듈이 아닌 Sheet2에 두었습니다. ComboBox의
Change이벤트를 이용하기 때문에 일반모듈이 아닌 Sheet2의 클래스모듈에 두는
것입니다.
Option Explicit
'// 필터링할 항목을 담을 컬렉션개체변수를 선언합니다.
Dim clt As Collection
Private Sub ComboBox1_Change()
'// 필터링 콤보상자 값이 변경될 때마다 필터링을 합니다
If ComboBox1.ListIndex < 0 Then Exit Sub
Dim Row0 As Long
Dim Row1 As Long
Dim i As Long
Dim sGrp As String
Application.ScreenUpdating = False
Row0 = 5
i = Row0
'// 목록의 범위의 끝을 찾습니다
'// Range개체의 End메소드를 사용할 수 있지만
'// 예를 들어 Range("A65536").End(xlUp).Row
'// 필터링된 상태에서 사용하는 경우
'// 보이는 범위의 끝을 돌려주기 때문에
'// 정확한 범위의 끝을 돌려주지 못합니다
Do Until Len(Cells(i, 1)) = 0
i = i + 1
Loop
Row1 = i - 1
sGrp = ComboBox1.Text
If sGrp = "ALL" Then
'// ALL을 선택하는 경우
'// 모든 목록의 Hidden속성을 False로
'// 두어 목록의 전부를 보여줍니다
Rows(Row0 & ":" & Row1).EntireRow.Hidden = False
Else
'// 특정 항목을 선택하는 경우
'// 목록의 전부를 순환하면서
'// 선택한 값과 같은 경우 보여주고
'// 다른 경우 행전체를 숨깁니다.
For i = Row0 To Row1
'// 아래의 식 Rows(i).EntireRow.Hidden = sGrp <>
Cells(i, 1) 은
'// If sGrp <> Cells(i, 1) Then
'// Rows(i).EntireRow.Hidden =False
'// Else
'// Rows(i).EntireRow.Hidden =True
'// End If
'// 를 줄여 쓴 것입니다.
'// sGrp <> Cells(i, 1)의 연산결과가 True인 경우(필터링하는
데이터가 아닌 경우)
'// Hidden속성은 True가 되어 숨겨지고
'// sGrp <> Cells(i, 1)의 연산결과가 False인 경우(필터링하는
데이터가 맞는 경우)
'// Hidden속성은 False가 되어 보여줍니다.
Rows(i).EntireRow.Hidden = sGrp <> Cells(i, 1)
Next
End If
Application.ScreenUpdating = True
End Sub
Private Sub Worksheet_Activate()
'// 다른 워크시트에서 이 워크시트로 이동한 경우
'// 목록을 clt변수에 저장하는 초기화과정을
'// 실행합니다.
If Not clt Is Nothing Then Exit Sub
Call InitComponents
End Sub
Private Sub Worksheet_Change(ByVal Target As
Range)
'// 시트의 내용이 변경되는 경우
'// 목록을 clt변수에 저장하는 초기화과정을
'// 실행합니다.
Set clt = Nothing
Call InitComponents
End Sub
Private Sub InitComponents()
'// 필터링항목을 clt변수에 저장합니다.
Dim Row0 As Long
Dim Row1 As Long
Dim i As Long
Dim sGrp As String
Set clt = New Collection
Row0 = 5
i = Row0
Do Until Len(Cells(i, 1)) = 0
i = i + 1
Loop
Row1 = i - 1
On Error Resume Next
For i = Row0 To Row1
sGrp = CStr(Cells(i, 1))
'// 중복되지 않도록 clt 컬렉션변수에
'// 동일한 값과 키를 입력합니다.
'// 따라서 중복되는 항목은 입력하지 않게 됩니다.
'// 중복된 키를 입력하는 경우 Error가 생깁니다.
'// 그래서 위에서 On Error Resume Next를 두어 에러를 무시하도록
합니다.
clt.Add sGrp, sGrp
Next
'// 전부를 보이기 위해 마지막에는
'// ALL이라는 항목을 추가합니다.
clt.Add "ALL"
On Error GoTo 0
'// clt 값을 ComboBox에 넣기 위해
'// ComboBox 목록을 미리 지웁니다
ComboBox1.Clear
For i = 1 To clt.Count
ComboBox1.AddItem clt.Item(i)
Next
End Sub |
위의 코드는 다른 워크시트에서
Sheet2로 이동하거나 목록의 내용이 변경되는 경우
clt변수와 ComboBox가
초기화됩니다.
ComboBox의
목록을 열어보면 중복되지 않는 항목으로 구성되어 있는 것을 보실 수 있습니다.

위의 ComboBox항목에서 ‘우미제과(주)’를 선택하면
다음 그림과 같은 결과를 보실 수 있습니다.

비교적 간단한 필터링입니다.
위의 코드를 조금 더
개선한다면 범위를 필터링 하도록 할 수도 있을 겁니다.
날짜나 숫자의 경우 최소/최대값을 지정하거나,
한글이나 영문 항목을 필터링하는 경우 자음이나 알파벳을 지정하여 필터링 하도록 해볼 수도 있겠죠.
또 위의 예는 공급업체라는 하나의 열을 대상으로
필터링 하지만 모든 열의 내용을 대상으로 필터링 하고자 하는 경우 모든 열의 내용을 문자열로 묶어
저장하고 Like연산자를 이용하여 필터링 할 수 도 있을 겁니다.
|