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中的每个键