消除重复并列出单个单元格中的第二列

时间:2014-08-27 20:06:46

标签: excel vba excel-vba

我有大量数据(40,000多行),它都是多个id号。它们列在第1列中。然后在第10列中,我有一个SsoftGroup名称,用于他们符合条件的多个职位。我想把我所拥有的东西拿到一个单独的标签中,我需要的数据......

我有什么......

Column 1   Column 10
EmplNum    SsoftGroup
1          Assembly
1          Assembly
1          Cleaning
2          Bakery
2          Assembly
2          Assembly
2          Bakery
3          Cleaning
3          Cleaning
3          Bakery
3          Assembly
3          Assembly
4          Bakery
4          Bakery

我需要在另一个标签中

Column 1       Column 2
1              Staff Assembly:Staff Cleaning
2              Staff Assembly:Staff Bakery
3              Staff Assembly:Staff Bakery:Staff Cleaning
4              Staff Bakery

我不知道怎么做,因为我对Mac的VBA不太熟悉。我知道连接可以用于我需要的第2列;由于存在可变数组大小,我只是不确定如何做到这一点。

3 个答案:

答案 0 :(得分:1)

您可以使用Dictionary对象将关键/值对中的数据存储起来。 Value部分可以是任何数据类型,因此我们只使用字符串&连接B列中的各个项目,以获取A列中的唯一ID值。

关于词典......

字典以两种方式创建键/值,或者通过.Add方法明确地

dict.Add "key", "value"

或隐式引用尚不存在的键:

dict("key") = "value"   

如果密钥已存在,后者将覆盖现有值。所以我们可以使用返回布尔值的.Exists方法来查看该项是否已存在。

If dict.Exists("key") then 
    dict("key") = dict("key") & " some other text!"
Else
    dict.Add "key", "value"
End If

在您的情况下,我们只使用Instr函数检查并查看列B中的值是否已经附加到A列中每个ID的Value

未经测试,但我认为应该这样做:

Sub foo()
Dim dict as Object
Dim rng as Range
Dim r as Range
Dim val as String
Dim id as String
Dim key as Variant
Dim i as Long

Set rng = Range("A1", Range("A1").End(xlDown)) 'Modify as needed
Set dict = CreateObject("scripting.dictionary")

'iterate the range.rows:
For each r in rng.Rows
    '
    id = r.Value

    'get the value from the same row, cell in column 10 and prefix with "Staff "
    val = "Staff " & r.Offset(0,9).Value

    'Add this item if it doesn't already exist:
    If Not dict.Exists(id) Then 
        dict.Add id, val
    Else
        'avoid printing duplicate "values" in the dictionary using some string functions:
        If Instr(1, dict(id), val) = 0 Then
            dict(id) = dict(id) & ":" & val
        End If
    End If

Next

'Print the data to another sheet in columns A, B:
With Worksheets("Sheet2")          '<~~ MODIFY AS NEEDED TO USE YOUR SHEET NAME
    For each key in dict.Keys()
        .Range("A1").Offset(i).Value = key
        .Range("B1").Offset(i).Value = dict(key)
        i = i + 1
    Next
End With

End Sub

答案 1 :(得分:0)

如果您对VBA不熟悉或不熟悉且上述解决方案令人生畏,您还可以使用几个Excel函数和许多额外列来实现目标。

基本上,您将创建一个表,该表计算与每个唯一作业组匹配的唯一员工ID的每个实例。您只需将重复数据删除的员工ID列表放在表的最左侧列中,并在最顶行中放置一个重复数据删除的作业组列表(使用转置命令)。

以下是使用示例数据的示例:

Column 1    Assembly    Cleaning    Bakery      ...     Column 2
1                                                 
2   
3   
4   
...

然后,您可以使用COUNTIFS(...)在表的每个单元格中放置一个逻辑值,该值可以在IF(...)语句中使用,以返回空白单元格或字符串...和然后你只需连接最后一列中该行的每个单元格。

我在表格单元格中使用了这个公式并且工作正常(显然你必须更改工作表名称并调整单元格引用):

=IF(COUNTIFS(Sheet1!$A:$A, $B4, Sheet1!$B:$B, D$2) > 0, "Staff " & D$2 & ":", "")

您知道整个数据集的第10列中有多少个唯一作业组吗?连续连接很多单元格可能非常繁琐,所以如果它超过50,你可能应该去VBA路线。

答案 2 :(得分:0)

数据透视表。通过此,您可以使用简单的Excel countif以及sum函数获取您想要的任何信息。也就是说,如果枢轴尚未提供您想要的信息。

pivot

如果要实现要在工作表中使用的VBA函数,可以使用:

Function JobCat(ByVal BaseValue, ByRef rng As Range, ByVal delim As String) As String
Dim a, i, k As Long
Dim last_col As Integer


Set jobs = New Collection
last_col = rng.Columns.Count

a = rng.Value
    On Error Resume Next
    For i = 1 To UBound(a, 1)
        If Val(a(i, 1)) = Val(BaseValue) Then
            jobs.Add "Staff " & a(i, last_col), "Staff " & a(i, last_col)
        End If
    Next


    For k = 1 To jobs.Count
        JobCat = JobCat & IIf(JobCat = "", "", delim) & jobs.Item(k)
    Next
End Function

参数1是EmplNum,参数2是整个范围(两列),参数3是文本分隔符(如&#34;:&#34;或&#34;,&#34;等)。如截图所示

enter image description here

更新以显示它使用命名范围:

named_range