VBA,找不到对象424错误-如何调试?

时间:2018-08-16 14:34:18

标签: excel vba debugging error-handling

我在Excel 2010上使用VBA,却收到可怕的424错误。但是调试器没有指向任何有助于解决问题的内容。是否有一个很好的做法可以缩小问题的范围?我检查了拼写,所有表格都在正确的工作表上,其中的列都在那里。

预先感谢您可能提供的建议。

Sub Finding_Zone()

Dim Data_Table As ListObject
Dim Freq_Table As ListObject
Dim i As Long
Dim x As Long
Dim Zone_Value As Long

Set Data_Table = Sheets("Sheet2").ListObjects("Table2")
Set Freq_Table = Sheets("Sheet2").ListObjects("Table3")

For i = 1 To Range(Data_Table).Rows.Count
    Zone_Value = data.Table.DataBodyRange.Cells(i, Data_Table.ListColumns("Zone").Index)


For x = 1 To Len(Zone_Value)

    Set Result = Freq_Table.ListColumns("Summary Code").DataBodyRange.Find(Zone_Value)

    If Result Is Nothing Then

        Zone_Value = Left(Zone_Value, Len(Zone_Value) - 1)

    Else
        Data_Table.DataBodyRange.Cells(i, Data_Table.ListColumns("Modified Zone").Index) = Zone_Value
        End If

Next x

Next i


End Sub

2 个答案:

答案 0 :(得分:2)

如所指出的,Option Explicit会捕获到data.Table的错字,从而导致Object Not Found错误。但是,这些额外的点应该可以帮助您优化代码。


  • Len(Zone_Value)不会返回区域编号中的位数,而是始终返回 4 -使用的字节数(Long的存储大小) 。有关更多详细信息,请参见MSDN - Data Type Summary。无论For x = 1 To Len(Zone_Value)有多少位,Len(Zone_Value) - 1都会循环4次,而Zone_Value等于3。因此,也许可以使用CstrZone_Value强制转换为String,然后检查其长度。

请考虑以下示例代码,其中显示了分配给1DoubleLongInteger变量时String的长度。

Sub TestLength()
    Dim a As Double, b As Long, c As Integer, d As String

    a = 1
    b = 1
    c = 1
    d = "1"

    Debug.Print "Length of a: " & Len(a)
    Debug.Print "Length of b: " & Len(b)
    Debug.Print "Length of c: " & Len(c)
    Debug.Print "Length of d: " & Len(d)
End Sub

输出为:

Length of a: 8
Length of b: 4
Length of c: 2
Length of d: 1

另一种想法:

  • Zone_Value = data.Table.DataBodyRange.Cells(i, Data_Table.ListColumns("Zone").Index)。添加ListColumn变量而不是多次引用Index可能更简单和更容易理解。

Dim Zone_Column As ListColumn: Set Zone_Column = Data_Table.ListColumns("Zone")


您修改后的代码,同时实现了两个建议,可能看起来像这样:

Option Explicit

Sub Finding_Zone()
    Dim Data_Table As ListObject: Set Data_Table = Sheets("Sheet2").ListObjects("Table2")
    Dim Freq_Table As ListObject: Set Freq_Table = Sheets("Sheet2").ListObjects("Table3")

    Dim Zone_Column As ListColumn: Set Zone_Column = Data_Table.ListColumns("Zone")
    Dim Summary_Column As ListColumn: Set Summary_Column = Freq_Table.ListColumns("Summary Code")
    Dim Mod_Zone_Column As ListColumn: Set Mod_Zone_Column = Data_Table.ListColumns("Modified Zone")

    Dim i As Long, x As Long
    Dim Zone_Value As Long
    Dim Result As Range
    Dim tmpStr As String

    With Zone_Column.DataBodyRange
        For i = 1 To .Rows.Count
            Zone_Value = .Cells(i, 1).Value
            tmpStr = CStr(Zone_Value)

            For x = 1 To Len(tmpStr)
                Set Result = Summary_Column.DataBodyRange.Find(Zone_Value)

                If Result Is Nothing Then
                    If Len(CStr(Zone_Value)) > 1 Then
                        Zone_Value = CLng(Left(CStr(Zone_Value), Len(CStr(Zone_Value)) - 1))
                    End If
                Else
                    Mod_Zone_Column.DataBodyRange.Cells(i, 1) = Zone_Value
                    Exit For
                End If

            Next x
        Next i
    End With

End Sub

答案 1 :(得分:1)

Option Explicit必须未指定,Big Ben saw the typo

  

data.Table中的Zone_Value = data.Table.DataBodyRange...是什么?您的ListObjectData_Table。 – BigBen

应该是Data_Table

Option Explicit放在模块的顶部 在VBA中向其添加代码的每个模块

然后,该代码将拒绝编译,因为未声明变量data(选项强制声明每个变量)。

结果,表达式data.Table.DataBodyRange在运行时被评估为成员调用,以查找名为{{1}的对象上的Table成员},由VBA即时声明(由于缺少data),其值为值为Option Explicit的隐式Variant,即... not一个对象

因此,需要对象,因为您不能在非对象上进行成员调用

Rubberduck会告诉您有关丢失的Empty的事实,即Option Explicit没有声明也从未分配过,并且未经分配就被使用。还可以帮助您使indentation更加一致;-)

免责声明:我管理那个开源项目