[英]Excel VBA - Getting a list of unique entries across various columns and combine into a single column of unique items
I am trying to get a list of unique data from multiple columns into a single column.我正在尝试将多列中的唯一数据列表放入单列中。
I found the following code which works great;我发现以下代码效果很好;
RanglFilterCopy, CopyToRange:=Range("B1"), Uniqe("A1:A6").AdvancedFilter Action:=xue:=True
Source of this was (and thank you to https://stackoverflow.com/users/495455/jeremy-thompson for posting): Quicker way to get all unique values of a column in VBA?其来源是(感谢https://stackoverflow.com/users/495455/jeremy-thompson发布): 在 VBA 中获取列的所有唯一值的更快方法?
My issue is, I don't want to be limited to a set range (ie I want the range to be dynamic based on the entered data) as the range may change and I want to capture unique values across multiple columns, not just 1.我的问题是,我不想被限制在一个设定的范围内(即我希望范围根据输入的数据是动态的),因为范围可能会改变,我想在多个列中捕获唯一值,而不仅仅是 1 .
I am thinking that I need to do something along the following lines but really am lost where to start in terms of VBA code.我想我需要按照以下几行做一些事情,但在 VBA 代码方面真的迷失了从哪里开始。
Points to consider;要考虑的要点;
Range("Table1[StileCode]")
数据包含在特定工作表上“表格”内的“列”中我的表格中的列示例是 -> Range("Table1[StileCode]")
Summary I want to basically dynamically create a unique list on the fly (or when I choose to run the code) which captures all the unique values at that point in time.总结 我想基本上动态地动态创建一个唯一的列表(或者当我选择运行代码时),该列表捕获该时间点的所有唯一值。
I know this is a big ask but any assistance/guidance would be greatly appreciated.我知道这是一个很大的问题,但任何帮助/指导将不胜感激。
OK - Done a little homework and the following seems to work, please don't laugh, I am no VBA expert so I am imagining that the code is clunky and could most probably be achieved with less code.好的 - 做了一点功课,以下似乎有效,请不要笑,我不是 VBA 专家,所以我想象代码很笨重,很可能用更少的代码来实现。
Any suggestions would be appreciated.任何建议将不胜感激。
I created a new workbook with Sheet1 and Sheet 2.我用 Sheet1 和 Sheet 2 创建了一个新工作簿。
The data is in columns A, B, C, D and E of Sheet1.数据位于 Sheet1 的 A、B、C、D 和 E 列中。
Code as follows;代码如下;
Sub TestTheoryCopy()
Dim sourceWS As Worksheet
Dim targetWS As Worksheet
Dim sourceValues As Range
Dim targetRange As Range
Set sourceWS = ThisWorkbook.Sheets("Sheet1")
Set targetWS = ThisWorkbook.Sheets("Sheet2")
Dim i As Integer
Dim dataColA As Integer
dataColA = 1
Dim dataColC As Integer
dataColC = 3
Dim dataColE As Integer
dataColE = 5
Dim startRange As Range
Dim ra As Range
targetWS.Cells.Clear
For i = dataColA To dataColA
Set startRange = sourceWS.Range("A2").Offset(0, i - 1)
Set ra = sourceWS.Range(startRange, sourceWS.Cells(Rows.Count, startRange.Column).End(xlUp))
ra.Copy
targetWS.Range("A" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial Paste:=xlPasteValues
Next i
For i = dataColC To dataColC
Set startRange = sourceWS.Range("A2").Offset(0, i - 1)
Set ra = sourceWS.Range(startRange, sourceWS.Cells(Rows.Count, startRange.Column).End(xlUp))
ra.Copy
targetWS.Range("A" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial Paste:=xlPasteValues
Next i
For i = dataColE To dataColE
Set startRange = sourceWS.Range("A2").Offset(0, i - 1)
Set ra = sourceWS.Range(startRange, sourceWS.Cells(Rows.Count, startRange.Column).End(xlUp))
ra.Copy
targetWS.Range("A" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial Paste:=xlPasteValues
Next i
targetWS.Activate
RemoveBlankCells 'If blank cells are included I wanted to remove them from the dataset
Dim FoundFromColumnsRangeA As Range
Dim uniqueIDs As Range
Set FoundFromColumnsRangeA = Sheets("Sheet2").UsedRange
FoundFromColumnsRangeA.Columns(1).Select
With Selection
.AdvancedFilter Action:=xlFilterCopy, CopyToRange:=Range("B1"), Unique:=True
End With
Set uniqueIDs = Sheets("Sheet2").UsedRange
FoundFromColumnsRangeA.Columns(2).Select
With Selection
.AdvancedFilter Action:=xlFilterCopy, CopyToRange:=Range("C2"), Unique:=True
End With
RemoveBlankCells
Columns("A:B").EntireColumn.Delete
End Sub
Private Sub RemoveBlankCells()
'PURPOSE: Deletes single cells that are blank located inside a designated range
'SOURCE: www.TheSpreadsheetGuru.com
Dim ws As Worksheet
Dim rng As Range
Set ws = ThisWorkbook.Sheets("Sheet2")
'Store blank cells inside a variable
On Error GoTo NoBlanksFound
Set rng = ws.Range("A:A").SpecialCells(xlCellTypeBlanks)
On Error GoTo 0
'Delete blank cells and shift upward
rng.Rows.Delete Shift:=xlShiftUp
Exit Sub
'ERROR HANLDER
NoBlanksFound:
MsgBox "No Blank cells were found"
End Sub
} }
In this day and age I would use Power Query / Get and Transform.在这个时代,我会使用 Power Query/Get 和 Transform。 Pull all the data tables into queries, delete all but the one column you are interested in, append the queries and delete duplicates.将所有数据表拉入查询,删除除您感兴趣的一列之外的所有数据表,附加查询并删除重复项。
If the data changes, just hit the Refresh All button.如果数据发生变化,只需点击“全部刷新”按钮。 Viola.中提琴。
Here is some code that should run reasonably quickly.下面是一些应该可以相当快地运行的代码。 As written, the Table name, worksheet names, and the particular columns to copy are hard coded.正如所写,表名称、工作表名称和要复制的特定列是硬编码的。
The data is read into a variant array for speed of processing (usually faster than accessing the worksheets).数据被读入变体数组以提高处理速度(通常比访问工作表更快)。
The Collection
object is used to remove duplicates (and blanks are tested for and skipped). Collection
对象用于删除重复项(测试并跳过空白)。 One could use the Dictionary
object, and which would be faster depends on the size of the data.可以使用Dictionary
对象,哪个更快取决于数据的大小。 Other differences:其他区别:
Collection
object throws an error if you have a duplicate key.如果您有重复的键,则Collection
对象会引发错误。Dictionary
object has a .Exists
method Dictionary
对象有一个.Exists
方法Dictionary
object requires early or late binding to Microsoft Scripting Runtime
Dictionary
对象需要早期或晚期绑定到Microsoft Scripting Runtime
Collection
object is native VBA. Collection
对象是本机 VBA。Hopefully, this code will give you some clues.希望这段代码能给你一些线索。
Option Explicit
Sub deDupe()
Dim wsSrc As Worksheet, wsRes As Worksheet, rRes As Range
Dim vSrc As Variant, vRes As Variant
Dim cUniques As Collection
Dim I As Long, J As Long
Dim colArray
Dim V
'Columns to include
' 1 = first column in table
colArray = Array(1, 3, 5) 'Note this will be zero-based array
'Change sheet names for data and results as needed
Set wsSrc = Worksheets("sheet1")
Set wsRes = Worksheets("sheet2")
Set rRes = wsRes.Cells(1, 1) 'put first cell of unique list anyplace
'Read data into variant array for speed
vSrc = wsSrc.ListObjects("Table1").DataBodyRange
'Collect the unique values
Set cUniques = New Collection
On Error Resume Next 'Duplicate keys in .Add method --> error
For J = 0 To UBound(colArray)
For I = 1 To UBound(vSrc)
V = vSrc(I, colArray(J))
If V <> "" Then
cUniques.Add Item:=V, Key:=CStr(V)
End If
Next I
Next J
On Error GoTo 0
'create results array
ReDim vRes(1 To cUniques.Count, 1 To 1)
For I = 1 To UBound(vRes, 1)
vRes(I, 1) = cUniques(I)
Next I
'Write the results
Set rRes = rRes.Resize(UBound(vRes, 1), 1)
With rRes
.EntireColumn.Clear
.Value = vRes
.EntireColumn.AutoFit
End With
End Sub
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.