Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel VBA类对象未定义_Excel_Vba - Fatal编程技术网

Excel VBA类对象未定义

Excel VBA类对象未定义,excel,vba,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

我已将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
1.0版类
开始
多用途=-1'真
结束
属性VB_Name=“组件”
属性VB_GlobalNameSpace=False
属性VB_createable=False
属性VB_PredeclaredId=True
属性VB_Exposed=False
将事件工作簿作为工作簿公开_
使用事件SheetConfig作为工作表_
TableConfig作为ListObject_
TableVerValues1作为ListObject_
TableVerValues2作为ListObject_
作为ListObject的TabledValue_
TablerValue作为ListObject
...
私有子类_Initialize()
关于错误转到错误处理
toggleappupdatefalse
设置工作簿D=ActiveWorkbook
设置SheetConfig=WorkbookSD.Worksheets(工作表配置)
Set TableConfig=SheetConfig.ListObjects(表配置)
...
专用子表配置_激活()
关于错误转到错误处理
...
错误处理:
如果错误号为0,则
报告错误
如果结束
端接头
请注意“Attribute VB_PredeclaredId=True”以确保声明类的对象。有点像一个表单是怎么做的

因此,我在这个类和WithEvents中声明了我想要处理事件的所有对象。 “组件”在“Class_Initialize”事件中初始化

我在代码的其他地方通过“Component.XXXX”引用此类中的对象和方法。以下是“xlam”文件中另一个模块的示例:

公共函数FindCnfg(pTerm作为字符串,pSearchBy作为SearchBy)作为范围
将lTable设置为ListObject_
lRow作为射程_
只要
关于错误转到错误处理
Set FindCnfg=Nothing
设置lTable=Components.TableConfig
如果lTable.DataBodyRange为空,则
退出功能
如果结束
选择Case pSearchBy
Case SearchBy.ID
lCol=1
案例检索键
lCol=2
其他情况
RaiseError ErrorCode.INVALID_参数
结束选择
设置lRow=lTable.DataBodyRange.Columns(lCol).Find(What:=pTerm,LookIn:=xlFormulas,LookAt:=xlWhole,SearchOrder:=xlByRows)
如果不是lRow,那就什么都不是了
设置lRow=lRow.EntireRow
设置FindCnfg=lRow
如果结束
错误处理:
设置lTable=Nothing
设置lRow=Nothing
如果错误号为0,则
RaiseError错误编号,“FindCnfg”,错误描述
如果结束
端函数
我使用“On Error GoTo X”捕捉任何地方的错误

在正常情况下,这一切都很好,事件都得到了处理

但偶尔,我会收到一个错误,指出对象“组件”未定义,或者事件处理在没有警告或错误的情况下停止一起工作

如果我手动输入开发工具并运行引用“组件”的方法,它会再次工作

我怀疑这个问题与预先声明的“组件”对象的初始化有关

有人知道如何防止这些零星的不稳定吗?
也许有一种不同的方法可以确保“组件”的对象始终可用。

问题似乎有多个根本原因。 1-全局变量未定义。 2-Office 2016有多个bug,包括Workbook.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(nameOfWB):


这两个变化极大地提高了稳定性。我不再因为未定义的变量而出现随机错误。

问题似乎有多个根本原因。 1-全局变量未定义。 2-Office 2016有多个bug,包括Workbook.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(nameOfWB):


这两个变化极大地提高了稳定性。由于未定义的变量,我不再有随机错误。

介于
VERSION 1.0 CLASS
属性VB\u Exposed=False
之间的代码不是有效的VBA代码。在VBA编辑器中看到该代码部分了吗?请澄清你能不能也提供一个?@peh对我来说就像是类模块的导出。在IDE中不可见,但在文本中查看导出文件时有效editor@chrisneilsen是的,我看到了,这就是为什么我问他是否看到VBE中的代码部分。因为我看到有人导出模块,而不是正确导入模块,所以我在记事本中打开了文件并复制了内容。我的问题旨在确保这种情况不会在这里发生。@Pᴇʜ:正如“克里斯·尼尔森”所描述的那样。这是一种出口。我在上面添加了一个事件处理示例。“Components”类的其余部分非常简单。只是通常的事件处理。我想知道是否在工作簿完全加载之前初始化了类,从而导致一些未定义的行为。您可以尝试在工作簿\打开事件中手动创建类;甚至可能使用
Application.OnTime Now+TimeValue(“00:00:01”),“CreateComponentClass”
来确保一切就绪。根据创建对象的位置,可能需要全局声明变量,并在
.xlam
中包含工厂方法,因为外接程序中的类最多只能是
publicnotcreateable
VERSION 1.0 CLASS
属性VB_Exposed=False
之间的代码不是有效的VBA代码。在VBA编辑器中看到该代码部分了吗?请澄清
Workbooks.Open Filename:=lPath
Set WB = Workbooks(nameOfWB)