Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel 识别一列中的重复项,并将相应的数据移动到另一列_Excel_Vba - Fatal编程技术网

Excel 识别一列中的重复项,并将相应的数据移动到另一列

Excel 识别一列中的重复项,并将相应的数据移动到另一列,excel,vba,Excel,Vba,我有一个非常大的数据表,我需要从列中删除重复项,但是在相应的列中有不同的数据,我需要保留 Example Record Incident Person 1 101 A 2 201 D 3 301 X 1 102 C 4 401 K 1 101 A

我有一个非常大的数据表,我需要从列中删除重复项,但是在相应的列中有不同的数据,我需要保留

Example                              
Record  Incident  Person
  1        101       A
  2        201       D    
  3        301       X
  1        102       C
  4        401       K
  1        101       A
  2        202       F
  1        101       W
  4        401       S
我需要成为:

Record  Incident  Person
  1        101       A, W
  2        201       D    
  3        301       X
  1        102       C
  4        401       K, S
  2        202       F
person列可以由一列分隔,也可以位于其他行中,我并不挑剔

到目前为止,我已经通过将每个副本移动到一个新的工作表,然后将其合并回原始工作表,从而改变了以下宏的工作方式

Sub macro()
Dim aIds As Variant
Application.ScreenUpdating = False
ActiveSheet.Copy after:=Worksheets(Worksheets.Count)
ActiveSheet.Name = "Temp"
Set origSh = ActiveSheet
Worksheets.Add
Set myRng = Range(origSh.Range("A2"), origSh.Range("A" & Rows.Count).End(xlUp))
myRng.Copy Destination:=ActiveSheet.Range("A1")
ActiveSheet.Range("A:A").RemoveDuplicates Columns:=1, Header:=xlNo
aIds = WorksheetFunction.Index(WorksheetFunction.Transpose(Range(Range("A1"), Range("A" & 
Rows.Count).End(xlUp)).Value), 1, 0)
Application.DisplayAlerts = False
ActiveSheet.Delete
Application.DisplayAlerts = True
Res = 0
For Each Item In aIds
Res = WorksheetFunction.Max(Res, WorksheetFunction.CountIf(myRng, Item))
Next
For Idx = 1 To Res
Worksheets.Add after:=Worksheets(Worksheets.Count)
ActiveSheet.Name = "Result" & Idx
origSh.Cells(1, "A").EntireRow.Copy ActiveSheet.Range("A1")
For Each Item In aIds
    Res1 = 0
    On Error Resume Next
    Res1 = WorksheetFunction.Match(Item, myRng, 0)
    On Error GoTo 0
    If Res1 Then
        origSh.Cells(Res1 + 1, "A").EntireRow.Copy ActiveSheet.Range("A" & Rows.Count).End(xlUp).Offset(1)
        origSh.Cells(Res1 + 1, "A").EntireRow.Delete
    End If
Next

Next
Application.DisplayAlerts = False
origSh.Delete
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
我确信可以避免这一额外的步骤,但是我承担了一个没有宏培训的新项目,我正在努力自己解决它。

带字符串操作的词典 根据需要调整常量部分中的值

Option Explicit

Sub writeUnique()

    ' Constants
    Const srcSheet As String = "Sheet1"  ' Source Worksheet Name
    Const tgtSheet As String = "Sheet2"  ' Target Worksheet Name
    Const FirstRow As Long = 2           ' Worksheet First Row (of values)
    Const srcCols As String = "A:C"      ' Source Columns Address
    Const tgtCell As String = "A2"       ' Target First Cell Address

    ' Other Variables
    Dim rng As Range        ' Last Non-Empty Cell in Source Columns,
                            ' Source Range (All Data in Source Columns)
    Dim dict As Object      ' Dictionary (Object)
    Dim Key As Variant      ' Dictionary Key (For Each Control Variable)
    Dim Source As Variant   ' Source Array
    Dim Curr As Variant     ' Current Value in Unique Column
    Dim First As Variant    ' First Column Array
    Dim Target As Variant   ' Target Array
    Dim i As Long           ' Source Array Rows Counter
    Dim k As Long           ' First Column Array or Target Array Rows Counter

    ' Read from Source Sheet and write to Source Array.
    With ThisWorkbook.Worksheets(srcSheet)
        Set rng = .Columns(srcCols) _
          .Find("*", , xlFormulas, , xlByRows, xlPrevious)
        If rng Is Nothing Then Exit Sub
        If rng.Row < FirstRow Then Exit Sub
        Set rng = .Columns(srcCols).Resize(rng.Row - FirstRow + 1) _
          .Offset(FirstRow - 1)
    End With
    Source = rng: Set rng = Nothing ' All data is in Source Array.

    ' Write from Source Array to the Dictionary and to First Column Array.
    Set dict = CreateObject("Scripting.Dictionary")
    ReDim First(1 To UBound(Source)) ' The Dictionary can only hold 2 values.
    For i = 1 To UBound(Source)
        Curr = Source(i, 2)
        If Curr <> 0 Then
            If Not dict.exists(Curr) Then
                dict(Curr) = Source(i, 3)
                k = k + 1
                First(k) = Source(i, 1)
            Else
                dict(Curr) = dict(Curr) & ", " & Source(i, 3)
            End If
        End If
    Next i
    ReDim Preserve First(1 To k)

    ' Write values from First Array and the Dictionary to Target Array.
    ReDim Target(1 To k, 1 To UBound(Source, 2))
    Erase Source ' All data is in First Array and the Dictionary.
    k = 0
    For Each Key In dict.Keys
        k = k + 1
        Target(k, 1) = First(k)
        Target(k, 2) = Key
        Target(k, 3) = dict(Key)
    Next

    ' Clear contents and write to Target Range.
    With ThisWorkbook.Worksheets(tgtSheet).Range(tgtCell)
      ' Clear contents in whole columns below Target First Cell.
      .Resize(.Parent.Rows.Count - .Row + 1, UBound(Target, 2)).ClearContents
      ' Write from Target Array to Target Range.
      .Resize(UBound(Target), UBound(Target, 2)) = Target
    End With

End Sub
选项显式
副编剧()
“常数
Const srcSheet As String=“Sheet1”源工作表名称
Const tgtSheet As String=“Sheet2”目标工作表名称
Const FirstRow长度=2'工作表第一行(值)
Const srcCols As String=“A:C”'源列地址
Const tgtCell As String=“A2”'目标第一个单元格地址
“其他变量
Dim rng作为范围“源列中的最后一个非空单元格,
'源范围(源列中的所有数据)
Dim dict作为对象的字典(对象)
Dim键作为变量字典键(针对每个控制变量)
变暗源作为变量的源数组
Dim Curr作为变量“唯一列中的当前值”
Dim First作为变量的第一列数组
变暗目标作为变型目标阵列
Dim i As Long“源阵列行计数器
Dim k As Long“第一列数组或目标数组行计数器
'从源工作表读取并写入源数组。
使用此工作簿。工作表(srcSheet)
设置rng=.Columns(srcCols)_
.Find(“*”,xlFormulas,xlByRows,xlPrevious)
如果rng为空,则退出Sub
如果rng.Row<第一行,则退出Sub
设置rng=.Columns(srcCols).Resize(rng.Row-FirstRow+1)_
.偏移量(第一行-1)
以
Source=rng:Set rng=Nothing'所有数据都在源数组中。
'从源数组写入字典和第一列数组。
Set dict=CreateObject(“Scripting.Dictionary”)
ReDim First(1到UBound(Source))'字典只能保存2个值。
对于i=1到UBound(源)
电流=源(i,2)
如果电流为0,则
如果不存在dict.exists(Curr),则
dict(Curr)=来源(i,3)
k=k+1
第一(k)=源(i,1)
其他的
dict(Curr)=dict(Curr)&“,”和Source(i,3)
如果结束
如果结束
接下来我
重拨先保留(1到k)
'将第一个数组和字典中的值写入目标数组。
重拨目标(1对k,1对UBound(震源,2))
擦除源“所有数据都在第一个数组和字典中。
k=0
对于dict.Keys中的每个键
k=k+1
目标(k,1)=第一个(k)
目标(k,2)=键
目标(k,3)=指令(键)
下一个
'清除内容并写入目标范围。
使用此工作簿。工作表(tgtSheet)。范围(tgtCell)
'清除目标第一个单元格下整列中的内容。
.Resize(.Parent.Rows.Count-.Row+1,UBound(目标,2)).ClearContent
'从目标阵列写入目标范围。
.Resize(UBound(目标),UBound(目标,2))=目标
以
端接头
带字符串操作的字典 根据需要调整常量部分中的值

Option Explicit

Sub writeUnique()

    ' Constants
    Const srcSheet As String = "Sheet1"  ' Source Worksheet Name
    Const tgtSheet As String = "Sheet2"  ' Target Worksheet Name
    Const FirstRow As Long = 2           ' Worksheet First Row (of values)
    Const srcCols As String = "A:C"      ' Source Columns Address
    Const tgtCell As String = "A2"       ' Target First Cell Address

    ' Other Variables
    Dim rng As Range        ' Last Non-Empty Cell in Source Columns,
                            ' Source Range (All Data in Source Columns)
    Dim dict As Object      ' Dictionary (Object)
    Dim Key As Variant      ' Dictionary Key (For Each Control Variable)
    Dim Source As Variant   ' Source Array
    Dim Curr As Variant     ' Current Value in Unique Column
    Dim First As Variant    ' First Column Array
    Dim Target As Variant   ' Target Array
    Dim i As Long           ' Source Array Rows Counter
    Dim k As Long           ' First Column Array or Target Array Rows Counter

    ' Read from Source Sheet and write to Source Array.
    With ThisWorkbook.Worksheets(srcSheet)
        Set rng = .Columns(srcCols) _
          .Find("*", , xlFormulas, , xlByRows, xlPrevious)
        If rng Is Nothing Then Exit Sub
        If rng.Row < FirstRow Then Exit Sub
        Set rng = .Columns(srcCols).Resize(rng.Row - FirstRow + 1) _
          .Offset(FirstRow - 1)
    End With
    Source = rng: Set rng = Nothing ' All data is in Source Array.

    ' Write from Source Array to the Dictionary and to First Column Array.
    Set dict = CreateObject("Scripting.Dictionary")
    ReDim First(1 To UBound(Source)) ' The Dictionary can only hold 2 values.
    For i = 1 To UBound(Source)
        Curr = Source(i, 2)
        If Curr <> 0 Then
            If Not dict.exists(Curr) Then
                dict(Curr) = Source(i, 3)
                k = k + 1
                First(k) = Source(i, 1)
            Else
                dict(Curr) = dict(Curr) & ", " & Source(i, 3)
            End If
        End If
    Next i
    ReDim Preserve First(1 To k)

    ' Write values from First Array and the Dictionary to Target Array.
    ReDim Target(1 To k, 1 To UBound(Source, 2))
    Erase Source ' All data is in First Array and the Dictionary.
    k = 0
    For Each Key In dict.Keys
        k = k + 1
        Target(k, 1) = First(k)
        Target(k, 2) = Key
        Target(k, 3) = dict(Key)
    Next

    ' Clear contents and write to Target Range.
    With ThisWorkbook.Worksheets(tgtSheet).Range(tgtCell)
      ' Clear contents in whole columns below Target First Cell.
      .Resize(.Parent.Rows.Count - .Row + 1, UBound(Target, 2)).ClearContents
      ' Write from Target Array to Target Range.
      .Resize(UBound(Target), UBound(Target, 2)) = Target
    End With

End Sub
选项显式
副编剧()
“常数
Const srcSheet As String=“Sheet1”源工作表名称
Const tgtSheet As String=“Sheet2”目标工作表名称
Const FirstRow长度=2'工作表第一行(值)
Const srcCols As String=“A:C”'源列地址
Const tgtCell As String=“A2”'目标第一个单元格地址
“其他变量
Dim rng作为范围“源列中的最后一个非空单元格,
'源范围(源列中的所有数据)
Dim dict作为对象的字典(对象)
Dim键作为变量字典键(针对每个控制变量)
变暗源作为变量的源数组
Dim Curr作为变量“唯一列中的当前值”
Dim First作为变量的第一列数组
变暗目标作为变型目标阵列
Dim i As Long“源阵列行计数器
Dim k As Long“第一列数组或目标数组行计数器
'从源工作表读取并写入源数组。
使用此工作簿。工作表(srcSheet)
设置rng=.Columns(srcCols)_
.Find(“*”,xlFormulas,xlByRows,xlPrevious)
如果rng为空,则退出Sub
如果rng.Row<第一行,则退出Sub
设置rng=.Columns(srcCols).Resize(rng.Row-FirstRow+1)_
.偏移量(第一行-1)
以
Source=rng:Set rng=Nothing'所有数据都在源数组中。
'从源数组写入字典和第一列数组。
Set dict=CreateObject(“Scripting.Dictionary”)
ReDim First(1到UBound(Source))'字典只能保存2个值。
对于i=1到UBound(源)
电流=源(i,2)
如果电流为0,则
如果不存在dict.exists(Curr),则
dict(Curr)=来源(i,3)
k=k+1
第一(k)=源(i,1)
其他的
dict(Curr)=dict(Curr)&“,”和Source(i,3)
如果结束
如果结束
接下来我
重拨先保留(1到k)
'将第一个数组和字典中的值写入目标数组。
重拨目标(1对k,1对UBound(震源,2))
擦除源“所有数据都在第一个数组和字典中。
k=0
对于di中的每个键