excel - Excel VBA 类对象未定义
问题描述
我将 Excel 工作簿中所有事件的处理集中在一个名为“组件”的类中。该类被移动到单独的“xlam”文件和 Excel 工作簿中引用的“xlam”文件。
“组件”类定义如下:
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
END
Attribute VB_Name = "Components"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Public WithEvents WorkbookSD As Workbook, _
WithEvents SheetConfig As Worksheet, _
TableConfig As ListObject, _
TableVerValues1 As ListObject, _
TableVerValues2 As ListObject, _
TableDValues As ListObject, _
TableIGRValues As ListObject
...
Private Sub Class_Initialize()
On Error GoTo ErrorHandling
ToggleAppUpdate False
Set WorkbookSD = ActiveWorkbook
Set SheetConfig = WorkbookSD.Worksheets(SHEET_CONFIG)
Set TableConfig = SheetConfig.ListObjects(TABLE_CONFIG)
...
Private Sub SheetConfig_Activate()
On Error GoTo ErrorHandling
...
ErrorHandling:
If Err.Number <> 0 Then
ReportError
End If
End Sub
请注意“属性 VB_PredeclaredId = True”,以确保声明类的对象。有点像表单是如何做到的。
所以我在这个类和WithEvents中声明了我想要处理事件的所有对象。“组件”在“Class_Initialize”事件中初始化。
我在代码的其他地方通过“Component.XXXX”引用了这个类的对象和方法。这是“xlam”文件中另一个模块的示例:
Public Function FindCnfg(pTerm As String, pSearchBy As SearchBy) As Range
Dim lTable As ListObject, _
lRow As Range, _
lCol As Long
On Error GoTo ErrorHandling
Set FindCnfg = Nothing
Set lTable = Components.TableConfig
If lTable.DataBodyRange Is Nothing Then
Exit Function
End If
Select Case pSearchBy
Case SearchBy.ID
lCol = 1
Case SearchBy.Key
lCol = 2
Case Else
RaiseError ErrorCode.INVALID_PARAM
End Select
Set lRow = lTable.DataBodyRange.Columns(lCol).Find(What:=pTerm, LookIn:=xlFormulas, LookAt:=xlWhole, SearchOrder:=xlByRows)
If Not lRow Is Nothing Then
Set lRow = lRow.EntireRow
Set FindCnfg = lRow
End If
ErrorHandling:
Set lTable = Nothing
Set lRow = Nothing
If Err.Number <> 0 Then
RaiseError Err.Number, "FindCnfg", Err.Description
End If
End Function
我使用“On Error GoTo X”到处捕捉错误。
在正常情况下一切正常,事件得到处理。
但是时不时地,我会收到一个错误消息,指出对象“组件”未定义或事件处理在没有警告或错误的情况下停止工作。
如果我手动输入开发人员工具并运行引用“组件”的方法,它会再次起作用。
我怀疑这个问题与预先声明的“组件”对象的初始化有关。
有谁知道如何防止这些零星的不稳定性?也许另一种方法可以确保“组件”的对象始终可用。
解决方案
这个问题似乎有多个根本原因。1-全局变量未定义。2- Office 2016 有多个错误,包括 Workbooks.Open(我在我的代码中使用)。
为了解决 1,我将全局变量替换为返回变量的函数并使用该函数而不是全局变量:
Private lComponents As Components
Function MyComponents() As Components
If lComponents Is Nothing Then
Set lComponents = New Components
End If
Set MyComponents = lComponents
End Function
要解决 2,请不要将 Workbooks.Open 的返回值分配给任何变量。相反,调用 Workbooks.Open,然后将变量分配给 Workbooks(nameOfWB):
Workbooks.Open Filename:=lPath
Set WB = Workbooks(nameOfWB)
这两个变化大大提高了稳定性。由于未定义的变量,我不再有随机错误。
推荐阅读
- raku - 让 perl6 调用由 subtype(subset) 专门化的正确的 multi sub
- scala - 带有 Play-json 验证的 Apache Spark Scala
- html - 视差横幅图像从上到下滚动
- scala - 在 build.sbt 文件中使用外部库
- rx-java - RxJava2 - 如何观察一个已经初始化的空可观察对象一旦改变?
- c# - WPF 单击按钮并将文本块更新为新问题
- node.js - 如何从 MongoDB 和 Node.js 中匹配用户输入的文档中获取价值
- .net - VB.Net 保存按钮未将数据添加到文本文件
- mongodb - 如何使用 MongoDB 实现 Redis 缓存?
- android - 重复的 jar 条目 - android