【发布时间】:2013-09-01 06:44:05
【问题描述】:
我这几天一直在与 Excel 2007 问题作斗争。下面列出了我能想到的所有可能相关的事实:
IDetailSheet 是一个在 VBA 项目中声明的类,具有多种方法,并且在其类初始化器中引发错误,因此无法实例化(使其抽象)。
Option Explicit在所有模块中设置。
VBA 项目中的十个工作表实现 IDetailSheet 并干净地编译(整个项目也是如此)。
CDetailSheets 是在 VBA 项目中声明的一个类,它包装了一个 Collection 对象并将 Collection 对象公开为 IDetailSheet 的一个 Collection。它还公开了一些额外的方法来对所有集合成员执行 IDetailSheet 的某些方法。
-
在其 Class 初始化程序(从 Workbook_Open 事件处理程序调用并分配给全局变量)中,CDetailSheet 执行以下代码填充私有集合 DetailSheets:
Dim sht as EXCEL.WorkSheet For Each sht in ActiveWorkbook.Worksheets If TypeOf sht is IDetailSheet Then Dim DetailSheet as IDetailSheet Set DetailSheet = sht DetailSheets.Add DetailSheet, DetailSheet.Name End If Next sht -
在某些功能区回调中,会运行以下代码:
If TypeOf ActiveWorkbook.ActiveSheet is IDetailSheet Then Dim DetailSheet as IDetailSheet Set DetailSheet = ActiveWorkbook.ActiveSheet DetailSheet.Refresh *[correction]* End If 在确定存在其他稳定性问题(最初有几十个)之后,已从工作簿中删除所有 ActiveX 控件。已创建 Fluent 界面功能区来替换最初与 ActiveX 控件关联的功能。
企业模板中有一个 Hyperion 加载项,但本工作簿中没有使用它。
说到底,运行工作簿时出现以下症状:
- TypeOf Is 在 CDetailSheets 初始化程序中识别任意数量的 IDetailSheet 实例,从 1(最常见)到偶尔的 2 或 3。永远不会为零,永远不会超过 3,而且肯定永远不会全部 10 个可用。 (并不总是同一个,尽管靠近片场的前面似乎会增加被认出的可能性。)
- 在 CDetailSheets 初始化程序中发现的任何 IDetailSheet 实现实例(据我所知,只有这样的实例)在功能区回调中也被 TypeOf ... Is 识别。
谁能解释为什么大多数 TypeOf ... Is 操作都失败了?或者如何解决这个问题?
我已经求助于手动创建 v-tables(即大丑 Select Case ... End Select 语句)来使功能正常工作,但实际上我发现在旁边有我的名字相当尴尬这样的代码。除此之外,我可以看到这是未来维护的噩梦。
考虑到这可能是一个过时的 p 代码问题,我从扩展的 XLSM zip 中删除了 Project.Bin 文件,然后手动将所有 VBA 代码重新导入。没有任何变化。我还尝试将项目名称添加到 IDetailSheet 的所有用法中以使其成为 miFab.IDetailSheet,但再次无济于事。 (miFab 是项目名称。)
【问题讨论】:
-
您的问题中是否有
Foreach和EndIf拼写错误? -
是的,但在 VBA 中它将是
For Each和End If。 -
此blog entry 建议将
Implements与Worksheet对象一起使用会导致不稳定 -
这当然是一个有趣的问题,而且我以前从未遇到过。如果有任何方法可以重构您的 VBA 应用程序以使用封装而不是继承,您可以定义一堆不扩展/实现任何内容的裸用户定义类型或类,并将它们声明为每个中的私有字段工作表,具有所需的属性/方法/功能来跟踪您需要的数据。这很丑,但它可能工作,因为问题似乎专门针对实现接口的工作表。
-
不是真的...?在您的情况下,“VBA 项目中的十个工作表实现了 IDetailSheet”。我不是这里唯一认为特别是在 Worksheet 对象上使用继承/接口是问题的原因的评论者。这就是为什么我建议您创建一个实现
IDetailSheet的每张普通旧类模块,并将 those 放入您的集合中。您可以通过多种方式编写代码以确定哪个IDetailSheet实例属于哪个工作表,而无需使用TypeOf或Select ... End Select。
标签: vba excel excel-2007