【问题标题】:"Subscript out of range" error when referencing another sheet引用另一张工作表时出现“下标超出范围”错误
【发布时间】:2017-10-26 01:38:48
【问题描述】:

我无法通过以下代码引起的“下标超出范围”错误。当我第一次设置 found 变量时它会抛出错误。 sub 用于工作簿中的每个工作表,用于从已知列中搜索员工并识别行,然后使用该行对变量求和。然后它用该总数填充活动工作表中的一个单元格。 “col”在主子中指定。

nDate = Range("B3")
Dim startDate As Date
startDate = Range("B2")
Dim emp As String
emp = Range("B8")
Dim rw As String
n = 0

Do While True
    Range("B99") = nDate
    stringDate = Range("B99").Text

    Set found = Worksheets(stringDate).Range("D38:D144").Find(emp, LookIn:=xlValues, _
                        LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext)
            If found = emp Then
                rw = found.row
                n = Worksheets(stringDate).Range(col + rw)
                tot = tot + n
            End If

    If nDate = startDate Then
            Exit Do
        End If
    nDate = nDate - 1
Loop

Range(col + "3") = tot

我的代码中有类似的 Subs,编译得很好。唯一的区别是在上面的 sub 中,我正在搜索一个范围。 下面是另一个不会抛出错误的子。

n = 0
Dim startDate As Date
Dim endDate As Date
startDate = Range("B2")
nDate = Range("B3")

Do While True
    Range("B99") = nDate
    stringDate = Range("B99").Text
    n = Worksheets(stringDate).Range(col + rw)
    tot = tot + n
    If nDate = startDate Then
        Exit Do
    End If
    nDate = nDate - 1
Loop

Range(col + "3") = tot

我知道有关于相同错误的类似问题,但没有一个涉及引用外部工作表。 有关如何调试的任何建议?

【问题讨论】:

  • 每个模块的顶部都有Option Explicit 吗?如果没有,您的代码将编译,但可能会在运行时抛出错误。
  • 我没有那个。我得到错误天气我编译代码或运行它。
  • 您将 stringDate 设置为日期(在 Excel 中只是一个数字)。然后,当您调用 Worksheets(activeDate) 时,您试图按索引获取工作表,其索引可能为数千(日期的表示方式)。您需要确保 stringDate 是一个实际的字符串,并且它与有效的工作表名称匹配。所以将 stringDate 调暗为字符串。我不确定您的工作表是如何命名的,因此您可能需要适当地重新格式化 stringDate 变量。
  • 我最初在编写它时遇到了这个问题。这就是为什么通过从临时单元格中获取当前迭代日期的 .text 来将“stringDate”变量设置为字符串的原因。这样,stringDate 现在是一个字符串。
  • 在您将 steingDate 的 Debug.print 语句设置为 B99 的值之后,您介意告诉我它是什么吗?

标签: vba excel error-handling


【解决方案1】:

在子/函数的开头添加这个:

Dim targetWs As Excel.Worksheet

然后将循环改为:

Do While True
    Range("B99") = nDate
    stringDate = Range("B99").Text

    Set targetWs = Nothing
    Set found = Nothing

    On Error Resume Next
    Set targetWs = Worksheets(stringDate)
    On Error GoTo 0

    If targetWs Is Nothing Then
        MsgBox "Worksheet not found: " & stringDate
    Else
        Set found = targetWs.Range("D38:D144").Find(emp, LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext)
    End If

    If Not found Is Nothing Then
        If found = emp Then
            rw = found.row
            n = targetWs.Range(col + rw)
            tot = tot + n
        End If
    End If

    If nDate = startDate Then
        Exit Do
    End If
    nDate = nDate - 1
Loop

如果出现消息框,您就会知道您点击了一个不属于 Worksheets 集合的工作表名称。

【讨论】:

    【解决方案2】:

    感谢大家的帮助。我终于能够调试潜艇了。 下面是正确运行的代码。 当变量 stringDate 重新格式化为日期而不是字符串时,在 while 循环的第二次迭代中出现下标错误。我不确定为什么它发生在这个子中,并且没有在其他具有相同逻辑的情况下发生。转换为字符串的目的是浏览以该格式(例如 2016 年 10 月 25 日)标记的工作表。 无论哪种方式,我通过手动格式化保存当前迭代日期的单元格来解决此问题。 我还更改了 .find 执行后如何识别“found”。

    nDate = Range("B3")
    Dim startDate As Date
    startDate = Range("B2")
    Dim emp As String
    emp = Range("B8")
    Dim rw As String
    n = 0
    
    Do While True
        Range("B99") = nDate
        Range("B99").NumberFormat = "[$-409]mmmm d, yyyy;@"
        stringDate = Range("B99").Text
    
        Set found = Worksheets(stringDate).Range("D12:D144").Find(emp, LookIn:=xlValues, _
                            LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext)
    
            If Not found Is Nothing Then
                rw = found.Row
                n = Worksheets(stringDate).Range(col + rw)
                Else
                    n = 0
            End If
                tot = tot + n
    
        If nDate = startDate Then
            Exit Do
        End If
        nDate = nDate - 1
    Loop
    
    Range(col + "3") = tot
    

    【讨论】:

    • 我很确定,如果您在所有代码模块中使用Option Explicit,您将不会遇到这些问题。 (它会强制你在代码中包含Dim stringDate As String 声明,然后VBA 不会尝试将读取的值转换为Variant/Date。它还会拾取xlValue 的原始错误而不是xlValues.)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多