我将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
请注意,为了确保声明了一个类的对象,“ Attribute 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”在各处捕获错误。
在正常情况下一切正常,事件得到处理。
但是每隔一段时间,我会收到一条错误消息,指出未定义对象“ Component”,或者事件处理在没有警告或错误的情况下一起停止工作。
如果我手动输入开发人员工具并运行引用“组件”的方法,它将再次起作用。
我怀疑问题与预先声明的“组件”对象的初始化有关。
有人对如何预防这些偶发性不稳定有想法吗? 也许有另一种方法可以确保“组件”的对象始终可用。
答案 0 :(得分:0)
该问题似乎有多种根本原因。 1-全局变量未定义。 2- Office 2016有多个错误,包括在Workbooks.Open中(我在代码中使用)。
要解决1,我将全局变量替换为一个返回该变量的函数,并使用该函数代替全局变量:
select XMLType('<root>
<TPL>
<fld>f7</fld><val><![CDATA[v1&v2]]></val>
</TPL>
</root>') from dual;
要解决2,请不要将Workbooks.Open的返回值分配给任何变量。 而是调用Workbooks.Open,然后将变量分配给Workbooks(nameOfWB):
Private lComponents As Components
Function MyComponents() As Components
If lComponents Is Nothing Then
Set lComponents = New Components
End If
Set MyComponents = lComponents
End Function
这两个更改极大地提高了稳定性。由于变量未定义,我不再出现随机错误。