Arrays 是否有一种方法可以构建高效的vba函数,该函数将范围作为其参数并返回一个唯一值数组(无重复)?
我想创建一个vba函数(Public function),给定一个1列范围,它将返回一个包含唯一值的数组。它必须执行与RemovedUpplicates方法相同的工作,但在不更改任何内容的情况下,它应该只返回一个唯一值数组 我写了这段代码Arrays 是否有一种方法可以构建高效的vba函数,该函数将范围作为其参数并返回一个唯一值数组(无重复)?,arrays,vba,function,Arrays,Vba,Function,我想创建一个vba函数(Public function),给定一个1列范围,它将返回一个包含唯一值的数组。它必须执行与RemovedUpplicates方法相同的工作,但在不更改任何内容的情况下,它应该只返回一个唯一值数组 我写了这段代码 Public varData() As Variant Public Sub Suplem(rng As Range) Dim tempSheet As Worksheet Size = rng.Rows.Count On Error GoTo tuda1
Public varData() As Variant
Public Sub Suplem(rng As Range)
Dim tempSheet As Worksheet
Size = rng.Rows.Count
On Error GoTo tuda1
Worksheets.Add.Name = "temp"
tuda1:
Set tempSheet = ActiveWorkbook.Worksheets("temp")
With tempSheet
tempSheet.Range(tempSheet.Cells(1, 1), tempSheet.Cells(Size, 1)).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
tempSheet.Range(tempSheet.Cells(1, 1), tempSheet.Cells(Size, 1)).RemoveDuplicates
varData = tempSheet.Range(tempSheet.Cells(1, 1), tempSheet.Cells(Size, 1)).Value
End With
tempSheet.Delete
End Sub
Public Function UniqueVals(rng As Range)
ReDim varData(rng.Rows.Count - 1)
Call Suplem(rng)
Dim a() As Variant
UniqueVals = varData
Erase varData
End Function
这里的UniqueVals函数调用Sub-Suplem,它创建临时工作表,将初始范围的副本粘贴到其中,并从中删除重复项。然后,它将从重复项中释放的最终范围记录到全局数组varData中。之后,UniqueVals函数返回varData中的数据并将其清除
问题是这个函数返回#VALUE!由于Sub内部创建和修改了临时工作表,您对如何避免此错误有何想法?我可以改为使用数组,但使用范围方式,即通过公式对其进行修改吗?如果没有动态数组公式
UNIQUE()
,则使用此使用字典的函数
Public Function UniqueVals(rng As Range) As Variant
Dim rngArray As Variant
rngArray = Intersect(rng, rng.Parent.UsedRange).Value
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
Dim t As Variant
For Each t In rngArray
On Error Resume Next
dict.Add t, t
On Error GoTo 0
Next t
Dim temp() As Variant
ReDim temp(1 To dict.Count, 1 To 1)
Dim x As Long
x = 1
Dim key As Variant
For Each key In dict.Keys
temp(x, 1) = key
x = x + 1
Next key
UniqueVals = temp
End Function
如果您有动态公式,则有一个
UNIQUE()
公式可以执行此操作。Office 365订阅中提供了动态数组公式。或者使用字典并利用.exists()
来避免错误,您可以使用现有工作表上的最后一列来执行相同的操作。我假设您的数据集不跨16384列,所以应该没有问题。代码完成后,只需在End Sub
之前清除此列的内容即可。其他解决方案都是理想的,这只是一个例子FYI@urdearboy但是,如果从工作表中调用此函数,它将不起作用,因为从工作表中调用的函数无法对其他单元格进行更改。必须没有使用UDFSE。与仅返回字典键数组相比,在最后创建临时数组做了什么?1d数组不能与工作表函数等一起使用吗?@NickSlash它将是一个水平数组,OP声明数组将是垂直的。我这样做是为了避免应用程序。转置限制项目的大小或数量。@NickSlash,据我所知,如果不转换为数组,就不能简单地将字典放入单元格中。实际上,这种方法是可行的,尽管我不确定在处理10k+行数据时是否会很快。但问题是,它只能用于完全相同的工作表的范围,而如果它来自不同的工作表,则会发生错误(#VALUE!)@MarkRoyale请参见编辑。它不会在不同的工作表上工作。而且,它应该是非常迅速,即使与大范围。