You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VBA中ArrayList查找Range对象索引报错原因及自定义类实现要求

关于VBA中ArrayList使用IndexOf的问题解答

1. 报错的原因是什么?

这事儿核心在于**.NET ArrayList的IndexOf默认用引用相等性判断对象**,而VBA里的Range对象有个特殊点:每次你写Range("a1"),VBA都会生成一个全新的Range对象实例——哪怕它们指向同一个单元格,这两个实例在内存里的引用是完全不同的。

你代码里先Add了Range("a1")(第一个实例),然后调用IndexOf时又传了Range("a1")(第二个新实例),ArrayList找不到第二个实例的引用,自然就抛出“值不在预期范围内”的错误了。

2. 自定义myClass类需实现什么才能让IndexOf生效?

如果想用自定义类让IndexOf正确匹配,你需要在类模块里实现Equals方法,重写默认的引用比较逻辑,改成基于你需要的属性值来判断相等。

举个例子,假设你的myClass有个ID属性,类模块代码可以这么写:

' 在myClass类模块中
Public ID As Integer

Public Function Equals(ByVal other As Variant) As Boolean
    ' 先判断传入的对象是不是myClass类型
    If Not TypeOf other Is myClass Then
        Equals = False
        Exit Function
    End If
    ' 基于ID属性判断相等
    Equals = Me.ID = other.ID
End Function

这样ArrayList的IndexOf就会调用这个Equals方法来比较对象,而不是只看引用是否相同。

3. 是否无法在ArrayList中查找对象?

当然不是!只是要注意正确的查找姿势:

  • 如果是引用查找:你需要先把对象实例保存到变量里,Add和IndexOf都用同一个变量(也就是同一个引用)。比如修改你的测试代码:
    Sub testFixed()
        Dim testList As Object
        Dim targetRng As Range
        Set testList = CreateObject("System.Collections.ArrayList")
        Set targetRng = Range("a1") ' 保存同一个实例
        testList.Add targetRng
        Debug.Print testList.IndexOf(targetRng) ' 会返回0,正常找到索引
    End Sub
    
  • 如果是值查找:对于自定义类就像上面说的实现Equals方法;对于内置类型(比如字符串、数字),ArrayList本身就能直接用IndexOf找到,因为它们的Equals方法已经是基于值比较的了。

内容的提问来源于stack exchange,提问作者Greedo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:13:29