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

动态数组Subscript out of range错误排查求助

下标越界问题:数组统计唯一值时的错误修复

尝试遍历Excel列,检查值的唯一性并统计指定字符串出现次数,但调用UBound或LBound时始终报错:

subscript out of range


问题代码片段

主逻辑代码

Dim uniqueValues() As Variant
Dim occurrences() As Variant
Dim partNumber As String
Dim partNumberRange As Range
                
Erase uniqueValues
Erase occurrences
                
Dim tempVar1 As String
Dim tempVar2 As String
Dim j As Long
Dim k As Long

'fastenerSheets 数组已在其他位置定义                
Set partNumberRange = fastenerSheets(i - 1).Range("A2", "A" & CStr(diameterTestCount(i - 1) + 1))
Debug.Print partNumberRange.Address
                
Dim cell As Variant
For Each cell In partNumberRange
    partNumber = cell.value
    Debug.Print partNumber
    If IsInArray(partNumber, uniqueValues) Then
        ' 若已存在,找到索引并增加计数
        For j = LBound(uniqueValues) To UBound(uniqueValues)
            If uniqueValues(j) = partNumber Then
                Debug.Print uniqueValues(j)
                occurrences(j) = occurrences(j) + 1
                Exit For
            End If
        Next j
    Else
        ' 若不存在,添加到uniqueValues并将计数设为1
        ' 此处调用UBound时触发错误
        k = UBound(uniqueValues) + 1
        ReDim Preserve uniqueValues(1 To k)
        ReDim Preserve occurrences(1 To k)
        uniqueValues(k) = partNumber
        occurrences(k) = 1
    End If
Next cell

调用的IsInArray函数

Function IsInArray(val As Variant, arr As Variant) As Boolean
    Dim element As Variant
    On Error Resume Next
    IsInArray = (UBound(Filter(arr, val)) > -1)
    On Error GoTo 0
End Function

错误原因

  1. 空数组的边界调用问题:Erase执行后,uniqueValues和occurrences变成未初始化的空数组,直接调用UBound或LBound会触发下标越界——空数组没有有效的上下界。
  2. Filter函数的局限性:IsInArray中的Filter无法处理空数组,虽然错误捕获跳过了报错,但第一次检查时数组为空,函数返回False后,后续执行UBound(uniqueValues)仍会触发错误。

修复方案

方案1:修正数组初始化与边界判断

修改数组初始化逻辑,处理空数组的特殊情况:

Dim uniqueValues() As Variant
Dim occurrences() As Variant
Dim partNumber As String
Dim partNumberRange As Range
                
' 初始化数组为含一个空元素的结构,避免空数组调用UBound报错
ReDim uniqueValues(1 To 1)
ReDim occurrences(1 To 1)
uniqueValues(1) = ""
occurrences(1) = 0
                
Dim tempVar1 As String
Dim tempVar2 As String
Dim j As Long
Dim k As Long

Set partNumberRange = fastenerSheets(i - 1).Range("A2", "A" & CStr(diameterTestCount(i - 1) + 1))
Debug.Print partNumberRange.Address
                
Dim cell As Variant
For Each cell In partNumberRange
    partNumber = cell.value
    Debug.Print partNumber
    ' 处理数组初始状态(仅含空元素)
    If uniqueValues(1) = "" Then
        uniqueValues(1) = partNumber
        occurrences(1) = 1
    ElseIf IsInArray(partNumber, uniqueValues) Then
        ' 已存在则更新计数
        For j = LBound(uniqueValues) To UBound(uniqueValues)
            If uniqueValues(j) = partNumber Then
                Debug.Print uniqueValues(j)
                occurrences(j) = occurrences(j) + 1
                Exit For
            End If
        Next j
    Else
        ' 不存在则扩容数组
        k = UBound(uniqueValues) + 1
        ReDim Preserve uniqueValues(1 To k)
        ReDim Preserve occurrences(1 To k)
        uniqueValues(k) = partNumber
        occurrences(k) = 1
    End If
Next cell

' 修复IsInArray函数,增加空数组判断
Function IsInArray(val As Variant, arr As Variant) As Boolean
    Dim arrBound As Long
    ' 先判断数组是否未初始化
    On Error Resume Next
    arrBound = UBound(arr)
    If Err.Number <> 0 Then
        IsInArray = False
        Exit Function
    End If
    On Error GoTo 0
    
    ' 处理数组仅含初始空元素的情况
    If arr(LBound(arr)) = "" And UBound(arr) = LBound(arr) Then
        IsInArray = False
        Exit Function
    End If
    
    IsInArray = (UBound(Filter(arr, val)) > -1)
End Function

方案2:改用Dictionary(更高效简洁)

用VBA的Dictionary对象自动处理唯一值,彻底避免数组边界问题:

Dim partCounts As Object
Set partCounts = CreateObject("Scripting.Dictionary")

Dim partNumber As String
Dim partNumberRange As Range
Set partNumberRange = fastenerSheets(i - 1).Range("A2", "A" & CStr(diameterTestCount(i - 1) + 1))

Dim cell As Variant
For Each cell In partNumberRange
    partNumber = cell.Value
    If partCounts.Exists(partNumber) Then
        partCounts(partNumber) = partCounts(partNumber) + 1
    Else
        partCounts(partNumber) = 1
    End If
Next cell

' 输出统计结果示例
Dim key As Variant
For Each key In partCounts.Keys
    Debug.Print key & ": " & partCounts(key)
Next key

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 15:53:13