List 动态范围表中的唯一列表,可能为空
我在表1中有一个Excel表格,其中A列: 公司名称List 动态范围表中的唯一列表,可能为空,list,excel,unique,vba,List,Excel,Unique,Vba,我在表1中有一个Excel表格,其中A列: 公司名称公司1公司2公司 3公司1公司4公司1公司 3 我想将公司名称的唯一列表提取到sheet2的a列中。如果公司名称之间没有空格,我只能在助手列的帮助下执行此操作,但当我有空时,我会得到另一家公司,这是一个空格 另外,我也做过研究,但这个例子是针对非动态表的,所以它不起作用,因为我不知道我的列的长度 我想在第2页A列: 公司名称公司1公司2公司3 公司4 寻找需要较少计算能力的解决方案Excel或Excel VBA。它们在表2中出现的最终顺序实际上
公司1
公司2
公司 3公司1公司4公司1公司 3
我想将公司名称的唯一列表提取到sheet2的a列中。如果公司名称之间没有空格,我只能在助手列的帮助下执行此操作,但当我有空时,我会得到另一家公司,这是一个空格 另外,我也做过研究,但这个例子是针对非动态表的,所以它不起作用,因为我不知道我的列的长度 我想在第2页A列:
公司名称
公司1
公司2
公司3
公司4
寻找需要较少计算能力的解决方案Excel或Excel VBA。它们在表2中出现的最终顺序实际上并不重要。对记录器生成的代码稍作修改:
Sub Macro1()
Sheets("Sheet1").Range("A:A").Copy Sheets("Sheet2").Range("A1")
Sheets("Sheet2").Range("A:A").RemoveDuplicates Columns:=1, Header:=xlYes
With Sheets("Sheet2").Sort
.SortFields.Clear
.SortFields.Add Key:=Range("A2:A" & Rows.Count) _
, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.SetRange Range("A2:A" & Rows.Count)
.Header = xlGuess
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub
样本1:
样本表2:
排序将删除空格
编辑#1: 如果Sheet1中的原始数据来自公式,则使用PasteSpecial将删除不需要的公式复制。还有一个空单元格的最终扫描:
Sub Macro1_The_Sequel()
Dim rng As Range
Sheets("Sheet1").Range("A:A").Copy
Sheets("Sheet2").Range("A1").PasteSpecial Paste:=xlPasteValues
Sheets("Sheet2").Range("A:A").RemoveDuplicates Columns:=1, Header:=xlYes
Set rng = Sheets("Sheet2").Range("A2:A" & Rows.Count)
With Sheets("Sheet2").Sort
.SortFields.Clear
.SortFields.Add Key:=rng, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.SetRange rng
.Header = xlGuess
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Call Kleanup
End Sub
Sub Kleanup()
Dim N As Long, i As Long
With Sheets("Sheet2")
N = .Cells(Rows.Count, "A").End(xlUp).Row
For i = N To 1 Step -1
If .Cells(i, "A").Value = "" Then
.Cells(i, "A").Delete shift:=xlUp
End If
Next i
End With
End Sub
有两张名为
1
和2
+---+-----------------+
| | A |
+---+-----------------+
| 1 | Name of company |
| 2 | Company 1 |
| 3 | Company 2 |
| 4 | Company 3 |
| 5 | Company 4 |
+---+-----------------+
内页名称:1
+----+-----------------+
| | A |
+----+-----------------+
| 1 | Name of company |
| 2 | Company 1 |
| 3 | Company 2 |
| 4 | |
| 5 | Company 3 |
| 6 | Company 1 |
| 7 | |
| 8 | Company 4 |
| 9 | Company 1 |
| 10 | Company 3 |
+----+-----------------+
在名为:2
+---+-----------------+
| | A |
+---+-----------------+
| 1 | Name of company |
| 2 | Company 1 |
| 3 | Company 2 |
| 4 | Company 3 |
| 5 | Company 4 |
+---+-----------------+
在常规模块中使用此代码:
Sub extractUni()
Dim objDic
Dim Cell
Dim Area As Range
Dim i
Dim Value
Set Area = Sheets("1").Range("A2:A10") 'this is where your data is located
Set objDic = CreateObject("Scripting.Dictionary") 'use a Dictonary!
For Each Cell In Area
If Not objDic.Exists(Cell.Value) Then
objDic.Add Cell.Value, Cell.Address
End If
Next
i = 2 '2 because the heading
For Each Value In objDic.Keys
If Not Value = Empty Then
Sheets("2").Cells(i, 1).Value = Value 'Store the data in column D below the heading
i = i + 1
End If
Next
End Sub
代码返回未排序的日期,只是数据的显示方式
如果需要排序列表,只需在las行之前添加以下代码:
Dim sht As Worksheet
Set sht = Sheets("2")
sht.Activate
With sht.Sort
.SetRange Range("A:A")
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
这样,结果将始终被排序
(subrutine将是这样的)
如果您对代码有任何疑问,我很乐意解释。
< P>这是另一种使用Excel内置代码<删除重复> <代码>功能的方法,以及一种编程方法来删除空白行: 编辑 我已经用上面的方法删除了代码,因为运行时间太长了。我将其替换为一个方法,该方法使用VBA的collection对象来编译公司的唯一列表 第一种方法,在我的机器上,运行大约需要两秒钟;方法如下:约0.02秒Sub RemoveDups()
Dim wsSrc As Worksheet, wsDest As Worksheet
Dim rRes As Range
Dim I As Long, S As String
Dim vSrc As Variant, vRes() As Variant, COL As Collection
Set wsSrc = Worksheets("sheet1")
Set wsDest = Worksheets("sheet2")
Set rRes = wsDest.Cells(1, 1)
'Get the source data
With wsSrc
vSrc = .Range(.Cells(1, 1), .Cells(.Rows.Count, 1).End(xlUp))
End With
'Collect unique list of companies
Set COL = New Collection
On Error Resume Next
For I = 2 To UBound(vSrc, 1) 'Assume Row 1 is the header
S = CStr(Trim(vSrc(I, 1)))
If Len(S) > 0 Then COL.Add S, S
Next I
On Error GoTo 0
'Populate results array
ReDim vRes(0 To COL.Count, 1 To 1)
'Header
vRes(0, 1) = vSrc(1, 1)
'Companies
For I = 1 To COL.Count
vRes(I, 1) = COL(I)
Next I
'set results range
Set rRes = rRes.Resize(UBound(vRes, 1) + 1)
'Write the results
With rRes
.EntireColumn.Clear
.Value = vRes
.EntireColumn.AutoFit
'Uncomment the below line if you want
'.Sort key1:=.Columns(1), order1:=xlAscending, MatchCase:=False, Header:=xlYes
End With
End Sub
注意:你写的不关心顺序,但是如果你想对结果进行排序,这会给例程增加大约0.03秒。所有这些答案都使用VBA。最简单的方法是使用透视表 首先,选择数据,包括标题行,然后转到插入->数据透视表: 然后会出现一个对话框。您不需要在此处选择任何选项,只需单击“确定”。这将创建一个带有空白透视表的新工作表。然后,您需要告诉Excel您要查找的数据。在这种情况下,您只需要在行部分中输入公司的名称。在Excel的右侧,您将看到一个名为“数据透视表字段”的新部分。在此部分中,只需单击标题并将其拖动到“行”部分: 这将给出一个只包含唯一名称的结果和底部带有
(空白)
的条目:
如果不想进一步使用透视表,只需将感兴趣的结果行(在本例中为唯一的公司名称)复制并粘贴到新的列或表中,即可获得未附加透视表的结果行。如果要保留数据透视表,可以右键单击总计并删除该数据透视表,还可以过滤列表以删除(空白)
条目
无论哪种方式,您现在都有了一个没有空格的独特结果列表,它不需要任何公式或VBA,而且完成它所需的资源相对较少(远远少于任何VBA或公式解决方案)。您好,@Gary的学生。你在桌子上试过吗?在SeET2的头下,我仍然有空白空间。其余的似乎都是顺理成章的。我根据sheet1的其他列得到了我的公司名称,不确定是否相关。我也切换到自动计算,现在我只得到标题和a#REF!在它下面。我不知道该怎么办。@carlos_cs我将尝试修改代码以处理这两个问题。@carlos_cs查看我的编辑#1:wow,它在不到1秒的时间内完成了我想要的。这一次编辑#1非常有效。嗨,@Elbert Villarreal。我在我的案例中尝试了你代码的排序版本。我在第一行有一个空格,在第二行有一个标题,列表的其余部分在标题下未排序。我不知道为什么会这样。我得到的公司名称是基于sheet1的其他列的公式,不确定是否相关。您的结果没有公式,但在我更改为“自动计算”后,所有结果都保持不变。这些空白单元格真的是空白的吗???或者可以是空格或不可打印的字符?如果刷新数据,可以重新运行宏并返回唯一的单元格。您好,我今天重新调整了代码,第一行为空,然后按字母顺序获取所有内容(包括标题)。我相信这是一个真正的空白,但由于它是人工输入的人,我永远不能肯定。在这种情况下,我相信这是一个真正的空白,因为当我点击那个单元格时,我不能从中删除任何内容。您的代码大约需要7秒钟才能完成。标题应该在第一行,其余的应该在下面排序。如果您不知道数据的最后一个单元格,在VBA中很容易得到最后一行。声明一个名为
LastRow
的变量,然后使用以下命令:LastRow=Range(“A1048576”).End(xlUp)。row
将给出数据的最后一行,因为y像您一样进入单元格A1048576
并按CRTL+UpArrow.Hi,@Ron Rosenfeld。我用我的箱子试过你的代码,它完全符合我的要求!我唯一不喜欢的是10k行大约需要20秒。@carlos_cs我没有意识到使用Excel函数需要这么长时间。我将添加另一个使用