使用数据透视表计算唯一值

时间:2018-07-11 15:18:46

标签: excel excel-formula pivot-table

请帮助我创建一个Excel数据透视表,该表将计算下表中的唯一值的数量。下表列出了服务器机架连接电缆及其类型:

Source SDevice  Dest DDevice Cable_tape 
1.1    node1    2.1  switch1 Fiber
1.1    node2    2.2  switch2 Copper
2.1    server1  3.7  switch1 SAN
2.1    node12   1.1  switch5 Fiber

我想创建一个数据透视表,该数据透视表将根据端到端的唯一方向计算每种电缆类型的总数,以便输出看起来类似于以下内容:

From  To     Copper  SAN  Fiber
1.1   2.1                   2
1.1   2.2      1            
2.1   3.7             1 

如果源和目标方向相反,则在结果中应该只出现一次(例如1.1> 2.1,然后是2.1> 1.1)。是否可以使用数据透视表来实现? 预先感谢您的支持。

1 个答案:

答案 0 :(得分:0)

假设SourceDest列始终可解析为数字,则可以添加一个新列来计算路径……类似于=MIN([@Source],[@Dest]) & " -> " & MAX([@Source],[@Dest])

然后,数据透视表将仅以该字段作为行,并将电缆类型作为列:

enter image description here

但是,这没有考虑不能解析为数字的值(例如1.1.1或解析为数字时相同但语义上不同的值(例如1.11.10 )。

要解决此问题,您可以在VBA中创建2个用户定义的函数,然后从Excel中调用它们。我不确定您是否完全熟悉VBA(我知道您的问题当然没有标记为VBA。可以在here中找到有关在Excel中编写VBA函数的很好的介绍。需要以下功能:         显式选项

    Public Function StringMax(rng As Excel.Range, Optional ignoreCase As Boolean = True) As Variant
        Dim cell As Excel.Range, maxValue As String, comp As VbCompareMethod

        If ignoreCase Then
            comp = vbTextCompare
        Else
            comp = vbBinaryCompare
        End If

        ' make sure the range you're passing in only has 1 column
        If rng.Columns.Count > 1 Then
            StringMax = CVErr(XlCVError.xlErrNA)
        Else
            ' loop through cells in the range, checking if each one is > the current max
            StringMax = CStr(rng.Cells(1, 1).Value)
            For Each cell In rng.Cells
                If VBA.StrComp(CStr(cell.Value), StringMax, comp) > 0 Then
                    StringMax = CStr(cell.Value)
                End If
            Next cell
        End If

    End Function

    Public Function StringMin(rng As Excel.Range, Optional ignoreCase As Boolean = True) As Variant
        Dim cell As Excel.Range, maxValue As String, comp As VbCompareMethod

        If ignoreCase Then
            comp = vbTextCompare
        Else
            comp = vbBinaryCompare
        End If

        ' make sure the range you're passing in only has 1 column
        If rng.Columns.Count > 1 Then
            StringMin = CVErr(XlCVError.xlErrNA)
        Else
            ' loop through each cell in the range, checking if each one is < the current max
            StringMin = CStr(rng.Cells(1, 1).Value)
            For Each cell In rng.Cells
                If VBA.StrComp(CStr(cell.Value), StringMin, comp) < 0 Then
                    StringMin = CStr(cell.Value)
                End If
            Next cell
        End If

    End Function