ピボットテーブルの備忘録 ② クラス化(5)合計か平均か

先日から、マクロによるピボットテーブルの扱いを纏めている(備忘録)。
先日は、作成したピボットテーブルの書式を整えることに挑戦した。
infoment.hatenablog.com

今日は、集計方法の変更に挑戦する。
f:id:Infoment:20200318224347p:plain

さて、先日からサンプルとして扱っている「なんちゃって個人情報」の集計結果について。ピボットテーブル作成直後は、各県の性別・婚姻別者の「年齢の合計」が表示されている。
f:id:Infoment:20200318224844p:plain

しかし例えば上記の例のように、この表における愛知県の既婚男性の年齢が合計で1843歳と言われても、全くピンと来ない。例えばここは合計ではなく、せめて平均年齢としたいところ。

というわけで、メソッドを一つ追加してみた。

' 値フィールドの設定。
Public Sub SetValueField(Optional consolidation_function _
                            As XlConsolidationFunction = xlSum, _
                         Optional data_field_index _
                            As Long = 0)

    ' 指定した「data_field_index」番目が存在しない場合、処理を中断する。
    If data_field_index > Pvt.DataFields.Count Then Exit Sub

    ' 指定した「data_field_index」が「0番目」である場合、すべての
    ' データフィールドの集計方法を統一する。
    Dim arr As Variant
        Select Case data_field_index
            Case 0
                Dim DataField As PivotField
                    For Each DataField In Pvt.DataFields
                        
                        ' データフィールドの名称が、「平均 / 合計 / 年齢」のように
                        ' 意図しない表示になる場合がある。対策として、キャプションを
                        ' 一旦「 / 」で分割し、その最後の配列要素に集計名を付している。
                        ' 集計名は「AggregationMethodNameDict」を作成して取得している。
                        DataField.Function = consolidation_function
                        arr = Split(DataField.Caption, " / ")
                        DataField.Caption = AggregateMethodNameDict(consolidation_function) & _
                                            " / " & arr(UBound(arr))
                    Next
            Case Else
                With Pvt.DataFields(data_field_index)
                    .Function = consolidation_function
                    arr = Split(.Caption, " / ")
                    .Caption = AggregateMethodNameDict(consolidation_function) & _
                               " / " & arr(UBound(arr))
                End With
        End Select

End Sub

' 値フィールドの設定に使用する集計名辞書。
Private Property Get AggregateMethodNameDict() As Object
    Dim Dict As Object
    Set Dict = CreateObject("Scripting.Dictionary")
        
        Dict(xlSum) = "合計"
        Dict(xlCount) = "データの個数"
        Dict(xlAverage) = "平均"
        Dict(xlMax) = "最大値"
        Dict(xlMin) = "最小値"
        Dict(xlProduct) = "積"
        Dict(xlCountNums) = "数値の個数"
        Dict(xlStDev) = "標本標準偏差"
        Dict(xlStDevP) = "標準偏差"
        Dict(xlVar) = "標本分散"
        Dict(xlVarP) = "分散"
        
    Set AggregateMethodNameDict = Dict
End Property

それでは早速、実験してみよう。

Sub Test()
    Dim PvtTable As VBAProject.PvtTable
    Set PvtTable = New VBAProject.PvtTable
    
        If PvtTable.MakePivotTable(ActiveSheet.ListObjects(1)) = False Then
            MsgBox "ピボットテーブルの作成に失敗しました。"
            Exit Sub
        End If
        
        With PvtTable
            ' 各フィールドを設定。
            .SetFields xlPageField, "カレーの食べ方", "キャリア"
            .SetFields xlRowField, "都道府県", "性別"
            .SetFields xlColumnField, "婚姻"
            .SetFields xlDataField, 6
            
            ' 表形式で表示。
            .SetRowAxisLayout layout_row_type:=xlTabularRow
            
            ' 小計を非表示。
            .SetSubTotals subtotal_visible:=False
            
            ' 平均値で集計。
            .SetValueField xlAverage
        End With
End Sub

今回は、↓ この部分が追加となっている。

            ' 平均値で集計。
            .SetValueField xlAverage

結果が ↓ こちら。
f:id:Infoment:20200318225342g:plain

小数点以下の表示など、修正すべき点はあるが、取り敢えず平均値への切り替えは上手く行ったので良しとしよう。

なお今回までのコードは、まとめてこちらに畳んでおく。


次回に続きます。

参考まで。