VBA에서 클래스를 만들고 테이블 작업

14648 단어 VBA

개요



Excel을 이용한 업무로, 데이터에 필터를 걸고는 다른 시트에 복사하는 작업을 반복할 필요가 있어, 조작이나 코드의 기술이 번잡해졌기 때문에, 클래스화해 정리하려고 생각했습니다.

전제


  • Sheet1에는 아래와 같은 테이블 1이 있다.
  • Sheet2에는 아래와 같은 테이블 2가 있다.
  • 클래스 모듈의 이름은 WSheet로 한다.

  • 코드



    기본 설정



    멤버 변수는 Private로 했습니다.
    표준 모듈에서 Worksheet 객체나 ListObject 객체를 조작하고 싶을 때도 있으므로 Property Get 프로시저로 액세스할 수 있도록 해 둡니다.

    클래스 모듈
    Option Explicit
    Private WS_ As Worksheet
    Private sheetName_ As String
    Private tableName_ As String
    Private listObj_ As ListObject
    
    Public Property Get sheetName() As String
        sheetName = sheetName_
    End Property
    Public Property Get WS() As Worksheet
        Set WS = WS_
    End Property
    Public Property Get tableName() As String
        tableName = tableName_
    End Property
    Public Property Get listObj() As ListObject
        Set listObj = listObj_
    End Property
    

    클래스 모듈
    Public Function CreateListObj(ByVal sheetName As String, ByVal tableName As String)
        sheetName_ = sheetName
        Set WS_ = Worksheets(sheetName)
        tableName_ = tableName
        Set listObj_ = WS_.ListObjects(tableName)
    End Function
    

    예) Sheet1에 있는 테이블 1과 Sheet2에 있는 테이블 2에 대해 인스턴스를 생성한다.

    표준 모듈
    Dim table1 As WSheet: Set table1 = New WSheet
    table1.CreateListObj "Sheet1", "テーブル1"
    
    Dim table2 As WSheet: Set table2 = New WSheet
    table2.CreateListObj "Sheet2", "テーブル2"
    

    열 이름에서 열 번호 가져오기



    절각 테이블에서 구조화된 참조를 사용하고 있는데, VBA 메소드에 따라서는 일부러 열 번호를 지정해야 하는 경우가 있습니다.
    운용해 가는 가운데 열의 교환이 발생할지도 모르고, 「열 번호는 모르겠어, 나는 어쨌든 「성명」이라고 열을 조작하고 싶다!」라고 하는 때도 있겠지요.
    그러면 테이블(ListObject 객체)과 열 이름을 제공하여 열 번호를 가져오는 메서드를 준비합니다.
    이것은 나중에 작성하는 다른 메소드내에서도 이용합니다.

    클래스 모듈
    Public Function GetCol(ByVal itemName As String) As Integer
        GetCol = listObj_.ListColumns(itemName).Range(1).Column
    End Function
    

    예) 표 1의 「이름」열이 몇번인가 취득한다

    표준 모듈
    Dim colNum as Integer
    colNum = table1.GetCol("氏名")
    

    테이블의 Body 삭제



    예를 들어 월 1에서 처리를 돌릴 때 등 지난 달 분의 레코드를 삭제하고 싶을 때가 있습니다.
    그럴 때는 테이블의 헤더를 남겨 모든 행 삭제합니다.
    만약을 위해 .Range.AutoFilter 에서 필터를 해제한 후 삭제를 하고 있습니다.

    클래스 모듈
    Public Function DeleteTableBody()
        With listObj_
            .Range.AutoFilter
            If Not (.DataBodyRange Is Nothing) Then
                .DataBodyRange.Delete
            End If
        End With
    End Function
    

    예) 표 2에서 헤더 이외의 행 삭제

    표준 모듈
    table2.DeleteTableBody
    

    정렬



    배열을 전달하면 여러 조건으로 정렬할 수 있습니다.
    이번에는 오름차순이므로 Order:=xlAscending내림차순으로 하고 싶을 때는 Order:=xlDescending이것도 인수로 지정할 수 있도록 해도 좋을지도 모릅니다.

    클래스 모듈
    Public Function SetSort(ByVal ConditionArr As Variant)
        With listObj_.Sort
            .SortFields.Clear
            Dim itemName
            For Each itemName In ConditionArr
                .SortFields.Add Key:=Range(tableName_ & "[[#All],[" & itemName & "]]"), Order:=xlAscending
            Next
            .Header = xlYes
            .Apply
        End With
    End Function
    

    예) 테이블 1에 대해 '연령'을 우선도 1, '신장'을 우선도 2로 정렬

    표준 모듈
    Dim sortConditionArr() As String: ReDim Preserve sortConditionArr(1)
    sortConditionArr(0) = "年齢"
    sortConditionArr(1) = "身長"
    table1.SetSort sortConditionArr
    

    자동 필터



    클래스 모듈의 메소드를 통하지 않고 표준 모듈에서 Worksheet 및 ListObject 객체를 쉽게 조작할 수 있습니다.

    예) 테이블 1에 대해 "성별"이 "남자"로 필터링

    표준 모듈
    table1.listObj.Range.AutoFilter .GetCol("性別"), "男"
    

    열별로 데이터 복사



    자동 필터로 추출한 데이터를 다른 시트의 동일한 열 이름 위치로 복사할 수 있습니다.

    클래스 모듈
    Public Function DataBodyRangeCopy(ByVal targetWS As WSheet, ByVal itemName As String)
        listObj_.ListColumns(Me.GetCol(itemName)).DataBodyRange.Copy Worksheets(targetWS.sheetName).Cells(2, (targetWS.GetCol(itemName)))
    End Function
    

    예) 표 1의 "이름"열의 데이터를 표 2의 "이름"열에 복사

    표준 모듈
    table1.DataBodyRangeCopy table2, "氏名"
    

    계산 결과만 복사하고 싶을 때 등, 값만 복사의 경우는 이쪽.

    클래스 모듈
    Function DataBodyRangePasteSpecial(ByVal targetWS As WSheet, ByVal itemName As String)
        listObj_.ListColumns(Me.GetCol(itemName)).DataBodyRange.Copy
        Worksheets(targetWS.sheetName).Cells(2, targetWS.GetCol(itemName)).PasteSpecial Paste:=xlPasteValues
    End Function
    

    예) 표 1의 "BMI"열의 데이터를 표 2의 "BMI"열에 값만 복사

    표준 모듈
    table1.DataBodyRangePasteSpecial table2, "BMI"
    

    사이고에게



    코딩이 매우 쉬워졌습니다.
    클래스화하고 요카타!

    좋은 웹페이지 즐겨찾기