我使用Excel 2010创建了以下函数。它似乎仅在我在创建数组的同一张表中使用该函数时才起作用(sheet2),并且如果在函数中键入了值,例如:= KeyExists(1443)。我需要在工作簿中的另一个工作表中使用此函数,并且需要是单元格引用。难以理解为什么它不起作用。
Option Explicit
Function KeyExists(k)
Dim d As Object
Dim c As Variant
Dim i As Long
Dim lr As Long
Dim msg As String
Set d = CreateObject("Scripting.Dictionary")
lr = WorkSheets("Sheet2").Cells(Rows.Count, 1).End(xlUp).Row
c = Range("A2:A" & lr)
For i = 1 To UBound(c, 1)
d(c(i, 1)) = 1
Next i
If d.exists(k) Then
msg = "key exists"
Else
msg = "key does not exist"
End If KeyExists = msg
End Function
'parts of the code derived from:
'hiker95, 07/26/2012
'http://www.mrexcel.com/forum/showthread.php?649576-Extract-unique-values-from-one-column-using-VBA
答案 0 :(得分:0)
将其从Sheet2
更改为活动工作表:
lr = ActiveWorkbook.ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
答案 1 :(得分:0)
如果唯一键仅位于Sheet2列A2及以后...您可以创建一个动态命名范围并在工作簿中的任何位置引用它。
使用Keys
创建动态命名范围 =OFFSET(Sheet2!$A$1,1,0,COUNTA(Sheet2!$A:$A)-1,1)
。
然后说你要检查C4中的值,使用下面的公式:
=IF(ISNUMBER(IFERROR(MATCH(C4,Keys,0),"")),"key exists","key does not exists")
答案 2 :(得分:0)
我同意评论者对Dictionary
的看法。在我看来,没有它会更容易。我还认为其他方法会更快,具体取决于你拥有多少数据。
示例:
Function KeyExists(k As Range) As String
Dim ws As Worksheet
Dim c As Range, i As Long
' Set ws to the worksheet to which k belongs.
' This avoids activeworksheet and also allows for
' qualified references to other sheets if necessary.
ws = k.Worksheet
Set c = ws.Range("A2:A" & ws.Cells(Rows.Count, 1).End(xlUp).Row)
On Error Resume Next
i = Application.WorksheetFunction.Match(k.Value, c, 0)
On Error GoTo 0
If i <> 0 Then
KeyExists = "Key exists"
Else
KeyExists = "Key does not exist"
End If
End Function
使用MATCH
很可能比将每个数据条目添加到Dictionary
中要快得多。
如果您想确保该值是唯一的,那么您可能会争辩使用Dictionary
的情况稍微好一点。但即便如此,你还是必须使用循环逻辑来处理遇到重复键的假设 - 以及在那时要做什么。
您的问题并没有真正说明您是否需要执行此检查,或者如果发现重复检查该怎么办,因此很难就此提出建议。在任何情况下,如果你选择这个方法,我建议创建一个单独的过程来声明和构建字典并在Worksheet_Open
或类似的东西上运行它,让你使用一个非常短的函数来查询是否存在关键。这避免了每次公式运行时都必须构建字典,并且很可能比我的解决方案更快(并且需要更多编码)。