我在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
答案 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。因此,也许可以使用Cstr
将Zone_Value
强制转换为String
,然后检查其长度。请考虑以下示例代码,其中显示了分配给1
,Double
,Long
和Integer
变量时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...
是什么?您的ListObject
是Data_Table
。 – BigBen
应该是Data_Table
。
将Option Explicit
放在模块的顶部 在VBA中向其添加代码的每个模块。
然后,该代码将拒绝编译,因为未声明变量data
(选项强制声明每个变量)。
结果,表达式data.Table.DataBodyRange
在运行时被评估为成员调用,以查找名为{{1}的对象上的Table
成员},由VBA即时声明(由于缺少data
),其值为值为Option Explicit
的隐式Variant
,即... not一个对象。
因此,需要对象,因为您不能在非对象上进行成员调用。
Rubberduck会告诉您有关丢失的Empty
的事实,即Option Explicit
没有声明也从未分配过,并且未经分配就被使用。还可以帮助您使indentation更加一致;-)
免责声明:我管理那个开源项目