Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vba Excel中的唯一值函数_Vba_Excel_Excel 2010 - Fatal编程技术网

Vba Excel中的唯一值函数

Vba Excel中的唯一值函数,vba,excel,excel-2010,Vba,Excel,Excel 2010,我使用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

我使用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

将其从
Sheet2
更改为活动工作表:

lr = ActiveWorkbook.ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row

如果唯一键仅在第2页A2列及以后。。。您可以创建动态命名范围并在工作簿中的任何位置引用它

假设您有数据:

使用
=偏移量(Sheet2!$a$1,1,0,COUNTA(Sheet2!$a:$a)-1,1)创建一个动态命名范围

然后,假设要检查C4中的值,请使用以下公式:
=IF(iNumber(iError(匹配(C4,键,0),“”),“键存在”,“键不存在”)

没有必要使用VBA来实现您的目标。e、 g.

我同意关于
词典的评论。在我看来,没有它会容易得多。我还认为其他方法会快得多,这取决于你有多少数据

例如:

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
函数KeyExists(k作为范围)作为字符串存在
将ws设置为工作表
尺寸c为范围,i为长度
'将ws设置为k所属的工作表。
'这避免了activeworksheet,还允许
“如有必要,可参考其他图纸。
ws=k.工作表
设置c=ws.Range(“A2:A”和ws.Cells(Rows.Count,1).End(xlUp).Row)
出错时继续下一步
i=Application.WorksheetFunction.Match(k.Value,c,0)
错误转到0
如果我是0那么
KeyExists=“Key exists”
其他的
KeyExists=“密钥不存在”
如果结束
端函数
使用
MATCH
很可能比将每个数据条目添加到
字典中要快得多

如果您希望确保值是唯一的,那么您可能会认为使用
字典
稍微好一点。但即使这样,您也必须使用循环逻辑来处理遇到重复键的情况以及在那个时该怎么办


你的问题并没有具体说明你是否需要执行此检查,或者如果发现重复项该怎么办,因此很难给出建议。在任何情况下,如果您选择此方法,我建议您创建一个单独的过程来声明和构建字典,并在
工作表\u Open
或类似的东西上运行它,这样您就可以使用一个非常短的函数来查询键的存在。这避免了您每次运行公式时都必须构建字典,并且很可能比我的解决方案更快(并且需要更多的编码)。

当您查找最后一行
lr=WorkSheets(“Sheet2”)。单元格(Rows.Count,1)。End(xlUp)。row
您总是引用
Sheet2
。如果您将其替换为
ActiveSheet
,那么它应该可以工作:
lr=ActiveSheet.Cells(Rows.Count,1)。End(xlUp)。Row
至于第二个问题,也许您可以在函数头中的参数
k
之前插入限定符
ByVal
,并包括行
If-TypeName(k)=“Range”然后k=k.Value
。我猜
d.exists(k)
在传递一个范围时犹豫不决。我将在本工作簿的其他工作表中使用此函数。我想使用表2中范围内的值。例如,我想测试sheet2.Range(A2:A”)中的唯一值是否与Sheet1.Range(“A18”)中的值匹配。因此,在Sheet1中的单元格中,我将输入=KeyExists(A18)您需要包括@JohnColeman指出的部分。此外,您必须指定从哪个表中调用
.Range
方法,因此您应该像这样设置变量
c
c=Worksheets(“Sheet2”).Range(“A2:A”&lr)
您肯定不需要字典吗?只要找到k的匹配项,就可以退出第一个循环。。。