在 table 列中显示每个唯一值的计数
Display a count for each unique value in a table column
如何从 table 的列中获取每个唯一值的计数,加上实际值,并将其放入另一个单元格中。
Table 1 的状态栏
**status**
------
itemA
itemA
itemB
itemC
将所需结果放入单个单元格中:
Table 1 Status summary |2 itemA, 1 itemB, 1 itemC
我会接受一个简单的逗号分隔列表,其中包含所有不同的值,没有计数。
背景信息:
我有一份 excel 文档,我们正在使用它来跟踪新应用程序的验收测试。包含多个工作表的文档(每个工作表代表一个需要测试的代码区域)并且每个工作表都有多个 tables(代表每个案例应该多次测试或以不同方式等测试的测试用例)然后有一个摘要工作表,我想要其中的数据快照。在摘要页面上,每个工作表中的每个 table 都有一行,还有一个状态列。在该状态列中,我想显示在相应 table 中选择的每个状态的计数。我最初创建了一个冗长的公式,如果计数 > 0,则对值及其计数进行硬编码,但在我们进行测试时,我们发现需要添加新的状态值,然后公式变得难以保持更新。
编辑:添加公式
这是我原来的公式
=IF(COUNTIF(Table1[Status],"itemA"),COUNTIF(Table1[Status],"itemA")&" itemA"," ") & IF(COUNTIF(Table1[Status],"itemB"), ", " &COUNTIF(Table1[Status],"itemB")&" itemB"," ") & IF(COUNTIF(Table1[Status],"itemC"), ", " &COUNTIF(Table1[Status],"itemC")&" itemC"," ")
这个问题是,公式在摘要页面上重复了大约 100 次(基础工作表中每个 table 重复一次),每次我想添加状态时我都需要编辑每个公式。
如果您的单元格在 A1:A4
中,请将此数组公式放入单元格 B1:B4
:
{=$A:$A&": "&COUNTIF($A:$A,$A:$A)}
这将创建类似于 itemA: 2
和 itemB: 1
的字符串,但会有重复。
然后,您将使用您在评论中建议的 VBA 代码。为了完整起见,我把它放在这里:
Function ConcatUniq(ByRef rng As Range) As String
Dim r As Range
Static dic As Object
If dic Is Nothing Then Set dic = CreateObject("Scripting.Dictionary")
For Each r In rng
If r.Value <> Empty Then
dic(r.Value) = Empty
End If
Next
ConcatUniq = Join$(dic.keys, ", ")
dic.RemoveAll
End Function
因此您最终字符串的单元格公式将如下所示:
=ConcatUniq(B1:B4)
此 VBA 解决方案使用用户定义的函数,该函数:
.- 验证 Target Range
属于 ListObject
(Excel Table).
.- 使用 Array
来保存来自 table.
的所有状态值
.- 使用 Control
字符串来验证唯一性状态。
.- 使用 Output
字符串来保存具有相应计数的唯一状态列表。
注意:该列表的顺序与它们在 table 中的顺序相同。排序不在问题的范围内,但如果你想对它进行排序,我建议根据需要对 ListObject
进行排序(不包括在内)。
试试这个过程(查看代码中的注释):
Private Function Lob_Status_Count(rTrg As Range) As String
Const kStt As String = "Status"
Dim lob As ListObject
Dim sControl As String, sOutput As String
Dim aStt As Variant, vStt As Variant, bStt As Byte
Rem Validate Input
On Error Resume Next
Set lob = rTrg.ListObject 'Set ListObject
On Error GoTo 0
If lob Is Nothing Then GoTo ExitTkn 'Exit if Target range is not a ListObject
With lob.ListColumns(kStt).DataBodyRange
Rem Set Status Array
aStt = WorksheetFunction.Transpose(.Value2)
Rem Set Status Output
For Each vStt In aStt
If InStr(sControl, Chr(167) & vStt & Chr(167)) = 0 Then 'Validates uniqueness
bStt = WorksheetFunction.CountIf(.Cells, vStt) 'Gets Status Count
sOutput = sOutput & ", " & bStt & " " & vStt 'Adds to Results
sControl = sControl & Chr(167) & vStt & Chr(167) 'Adds to Control
End If: Next
Rem Cleanup Output
sOutput = Replace(sOutput, ", ", vbNullString, 1, 1)
End With
Rem Set Results
Lob_Status_Count = sOutput
Exit Function
ExitTkn:
Lob_Status_Count = "!Err ListObject"
End Function
建议阅读以下页面以更深入地了解所使用的资源:
Using Arrays,
ListObject Members (Excel),
WorksheetFunction Object (Excel),
For Each...Next Statement, InStr Function,
On Error Statement.
如何从 table 的列中获取每个唯一值的计数,加上实际值,并将其放入另一个单元格中。
Table 1 的状态栏
**status**
------
itemA
itemA
itemB
itemC
将所需结果放入单个单元格中:
Table 1 Status summary |2 itemA, 1 itemB, 1 itemC
我会接受一个简单的逗号分隔列表,其中包含所有不同的值,没有计数。
背景信息: 我有一份 excel 文档,我们正在使用它来跟踪新应用程序的验收测试。包含多个工作表的文档(每个工作表代表一个需要测试的代码区域)并且每个工作表都有多个 tables(代表每个案例应该多次测试或以不同方式等测试的测试用例)然后有一个摘要工作表,我想要其中的数据快照。在摘要页面上,每个工作表中的每个 table 都有一行,还有一个状态列。在该状态列中,我想显示在相应 table 中选择的每个状态的计数。我最初创建了一个冗长的公式,如果计数 > 0,则对值及其计数进行硬编码,但在我们进行测试时,我们发现需要添加新的状态值,然后公式变得难以保持更新。
编辑:添加公式 这是我原来的公式
=IF(COUNTIF(Table1[Status],"itemA"),COUNTIF(Table1[Status],"itemA")&" itemA"," ") & IF(COUNTIF(Table1[Status],"itemB"), ", " &COUNTIF(Table1[Status],"itemB")&" itemB"," ") & IF(COUNTIF(Table1[Status],"itemC"), ", " &COUNTIF(Table1[Status],"itemC")&" itemC"," ")
这个问题是,公式在摘要页面上重复了大约 100 次(基础工作表中每个 table 重复一次),每次我想添加状态时我都需要编辑每个公式。
如果您的单元格在 A1:A4
中,请将此数组公式放入单元格 B1:B4
:
{=$A:$A&": "&COUNTIF($A:$A,$A:$A)}
这将创建类似于 itemA: 2
和 itemB: 1
的字符串,但会有重复。
然后,您将使用您在评论中建议的 VBA 代码。为了完整起见,我把它放在这里:
Function ConcatUniq(ByRef rng As Range) As String
Dim r As Range
Static dic As Object
If dic Is Nothing Then Set dic = CreateObject("Scripting.Dictionary")
For Each r In rng
If r.Value <> Empty Then
dic(r.Value) = Empty
End If
Next
ConcatUniq = Join$(dic.keys, ", ")
dic.RemoveAll
End Function
因此您最终字符串的单元格公式将如下所示:
=ConcatUniq(B1:B4)
此 VBA 解决方案使用用户定义的函数,该函数:
.- 验证 Target Range
属于 ListObject
(Excel Table).
.- 使用 Array
来保存来自 table.
.- 使用 Control
字符串来验证唯一性状态。
.- 使用 Output
字符串来保存具有相应计数的唯一状态列表。
注意:该列表的顺序与它们在 table 中的顺序相同。排序不在问题的范围内,但如果你想对它进行排序,我建议根据需要对 ListObject
进行排序(不包括在内)。
试试这个过程(查看代码中的注释):
Private Function Lob_Status_Count(rTrg As Range) As String
Const kStt As String = "Status"
Dim lob As ListObject
Dim sControl As String, sOutput As String
Dim aStt As Variant, vStt As Variant, bStt As Byte
Rem Validate Input
On Error Resume Next
Set lob = rTrg.ListObject 'Set ListObject
On Error GoTo 0
If lob Is Nothing Then GoTo ExitTkn 'Exit if Target range is not a ListObject
With lob.ListColumns(kStt).DataBodyRange
Rem Set Status Array
aStt = WorksheetFunction.Transpose(.Value2)
Rem Set Status Output
For Each vStt In aStt
If InStr(sControl, Chr(167) & vStt & Chr(167)) = 0 Then 'Validates uniqueness
bStt = WorksheetFunction.CountIf(.Cells, vStt) 'Gets Status Count
sOutput = sOutput & ", " & bStt & " " & vStt 'Adds to Results
sControl = sControl & Chr(167) & vStt & Chr(167) 'Adds to Control
End If: Next
Rem Cleanup Output
sOutput = Replace(sOutput, ", ", vbNullString, 1, 1)
End With
Rem Set Results
Lob_Status_Count = sOutput
Exit Function
ExitTkn:
Lob_Status_Count = "!Err ListObject"
End Function
建议阅读以下页面以更深入地了解所使用的资源:
Using Arrays, ListObject Members (Excel), WorksheetFunction Object (Excel),
For Each...Next Statement, InStr Function, On Error Statement.