VBA实现EXCEL透视表功能(汇总+计数)

Enum 数值
    计数
    求和
End Enum
Enum 总计
    对行列禁用
    对行列启用
    仅对行启用
    仅对列启用
End Enum

Sub 调用()
    y = 透视(Sheets(1).Range("a1:d15"), True, 2, 3, 数值.求和, 总计.对行列启用, Sheets(1).[a21], 1)
    MsgBox "透视" & IIf(y, "成功", "失败")
End Sub

Function 透视(数据源 As Range, 首行为标题 As Boolean, 列标签所在列号 As Integer, 计数求和列所在列号 As Integer, 汇总方式, 总计方式, 结果起始单元格 As Range, ParamArray 行标签所列号()) As Boolean
    On Error GoTo ErrProcess
    sp1 = "|_|"
    Dim re()
    arr = 数据源
    数据起始行 = IIf(首行为标题, 2, 1)
    数据结束行 = UBound(arr)
    Set d = CreateObject("scripting.dictionary")
    Set d1 = CreateObject("scripting.dictionary")
    For i = 数据起始行 To 数据结束行
        d(arr(i, 列标签所在列号)) = ""
    Next
    列标签 = d.keys
    d.RemoveAll
    
    For i = 数据起始行 To 数据结束行
        键 = ""
        列数 = 0
        For Each t In 行标签所列号
            If t <> 列标签所在列号 And t <> 计数求和列所在列号 Then
                列数 = 列数 + 1
                键 = 键 & arr(i, t) & sp1 '作为列标签,则不能为行标签
            End If
        Next
        d1(键) = ""
        键 = 键 & arr(i, 列标签所在列号)
        If 汇总方式 = 数值.计数 Then
            d(键) = d(键) + 1
        ElseIf 汇总方式 = 数值.求和 Then
            d(键) = d(键) + arr(i, 计数求和列所在列号) * 1
        End If
    Next
    maxr = d1.Count + 2
    maxc = UBound(列标签) + 列数 + 2
    ReDim re(1 To maxr, 1 To maxc)
    列数 = 0
    For Each t In 行标签所列号
        If t <> 列标签所在列号 And t <> 计数求和列所在列号 Then
            列数 = 列数 + 1
            re(1, 列数) = IIf(首行为标题, arr(1, t), "")
        End If
    Next
    re(1, maxc) = "总计"
    re(maxr, 1) = "总计"
    For i = 0 To UBound(列标签)
        re(1, maxc - 1 - i) = 列标签(UBound(列标签) - i)
    Next
    rekey = d1.keys
    For i = 2 To maxr - 1
        tmp = Split(rekey(i - 2), sp1)
        For j = 0 To UBound(tmp) - 1
            re(i, j + 1) = tmp(j)
        Next
        For j = 0 To UBound(列标签)
            re(i, maxc - 1 - j) = d(rekey(i - 2) & 列标签(UBound(列标签) - j))
            re(maxr, maxc - 1 - j) = re(maxr, maxc - 1 - j) + re(i, maxc - 1 - j)
            re(i, maxc) = re(i, maxc) + re(i, maxc - 1 - j)
        Next
        s = s + re(i, maxc)
    Next
    re(maxr, maxc) = s
    Select Case 总计方式
        Case 总计.对行列禁用: maxr = maxr - 1: maxc = maxc - 1
        Case 总计.对行列启用 '默认
        Case 总计.仅对行启用: maxr = maxr - 1
        Case 总计.仅对列启用: maxc = maxc - 1
    End Select
    结果起始单元格.Resize(maxr, maxc) = re
    结果起始单元格.Resize(maxr, maxc).Interior.Color = 16051688
    透视 = True
    Exit Function
ErrProcess:
    Set d = Nothing
    Set d1 = Nothing
    透视 = False
End Function

你可能感兴趣的:(VBA,EXCEL)