excel - Rubberduck VBA 代码检查 : Member 'x' has a 'VB_VarHelpID' attribute with value '-1' , 但没有相应的注释

标签 excel vba rubberduck

我正在使用“工作表抽象\工作表代理”技术开发一个 Excel VBA 项目,如 There is no worksheet 中所述。文章和后续文章my question here 。我的 VBA 代码采用 MVP 设计模式构建,并且我编写了尽可能多的 OOP 代码。 Rubberduck 的“代码检查”功能一直以来提供了很大的帮助,但是在最近的版本中(我认为是从 v2.4.1.4*** 开始,但无法确切地指出确切的版本)我开始始终得到一些我不太明白的“橡皮鸭机会”和“代码质量问题”警告。

第一个,如标题中提到的,是成员“x”具有值为“-1”的“VB_VarHelpID”属性,但没有相应的注释Rubberduck 机会。每当我在“WorksheetProxy”类中声明一个事件公开工作表(或其他事件公开对象,即 CommandButton)时,我都会得到这个。下面代码中的两行都会触发此错误:

' This code sits in my ProcessMasterProxy class
Private WithEvents sheet As Worksheet
Private WithEvents buttonHideOwnerToAvailability As CommandButton

然后,每当我声明事件公开的“SheetProxy”类或事件公开的 UserForm 的实例时,我都会在“Presenter”类中遇到相同的错误:

' Here I am declaring an instance of the ProcessMasterProxy class from the above snippet
Private WithEvents assetPrx As ProcessMasterProxy
Private WithEvents view As ChecklistPopup

Rubberduck 的代码检查为我提供了针对此类错误的两种操作: 1.“添加属性注释”,在声明上方插入 '@MemberAttribute VB_VarHelpID, -1 行 AND 2.“删除属性”貌似没有任何作用,点击后依然报错。

我想知道“添加属性注释”修复对我的 VBA 项目有什么影响,以及我是否应该应用它,或者应该更改代码中的某些内容以避免完全出现错误。

同样,我担心“代码质量问题”部分中出现的相关错误:对于声明类型“EXCEL.EXE:Excel.Worksheet”的变量“sheet”,设置了一个值不兼容的声明类型“ProcessMgmt.ProcessMaster”与上面第一个代码片段中“ProcessMasterProxy”类中的以下代码相关:

Private WithEvents sheet As Worksheet
Private WithEvents buttonHideOwnerToAvailability As CommandButton

Private Sub Class_Initialize()
    ***Set sheet = ProcessMaster***
    Set buttonHideOwnerToAvailability = ProcessMaster.btnHideAssetOwnerToAvailability
End Sub

“ProcessMaster”是实际 Excel 工作表的名称,上面的代码位于其相应的“SheetProxy”类中。

代码检查针对此错误提供的唯一选项是“忽略一次”,我想再次知道这样做是否安全。我之前在几个项目中出现过这个错误,但那里一切正常。但是,在我最近的项目中,我在打开工作簿时开始随机收到“运行时错误 35010”,其中我的 Workbook_Open 事件中有以下代码:

Private pres As Presenter
If pres Is Nothing Then
    Set pres = New Presenter
End If

此问题是否与上述两个代码检查建议/错误有关?

最佳答案

这些检查的作用是揭示 VBE 可能添加的隐藏属性。这些属性通常会影响类的使用方式( VB_ExposedVB_PredeclaredId )或成员的行为方式( VB_UserMemId 等)。但它们在编辑器中也是完全不可见的,并且如果没有相应的注释/注释,通常无法分辨它们的存在。

inspection result for "Missing member annotation"

在这种特殊情况下,Rubberduck 通知1有一个隐藏的 VB_VarHelpId WithEvents 上的属性变量。

通过添加相应的注释注释,我们使隐藏代码在编辑器中可见并可修改:更改注释的参数值,Rubberduck 检查现在会说属性和注释不同步,这意味着隐藏代码说一个事情,但可见的评论说的是另一回事。

删除属性应该具有将模块导出到临时文件、修改该文件以删除隐藏属性以及将修改后的模块重新导入到项目中的效果。请注意,由于文档模块(例如ThisWorkbook或工作表模块)无法以这种方式导入到项目中,因此这在文档模块中不起作用,因此Rubberduck不应警告这些模块中的注释/属性不同步。如果快速修复没有做任何事情,请report a bug ,因为这绝对应该有效! (编辑:确认在构建 2.4.1.5229 中按预期工作)

底线,“Rubberduck 机会”检查就是:利用 Rubberduck 特定功能的机会(例如管理隐藏属性的注释注释):它们并不表明代码有任何问题。

<小时/>

“不兼容类型”检查结果是一个已知问题:目前 Rubberduck 没有看到 Worksheet工作表模块的接口(interface)(也不是 WorkbookThisWorkbook 接口(interface)),这导致文档模块周围出现许多误报。直到橡皮鸭知道 ProcessMaster不仅仅是ProcessMaster对象也是一个Worksheet (我们将在 2.5.x 中对此进行修复),当它提示文档模块和 MSForms 接口(interface)(具有相同的潜在问题)时,忽略该检查可能是安全的。

这种检查背后的想法是,VBA 通常只会在运行时意识到对象类型不兼容,但是(假设它看到所有类型的所有接口(interface))Rubberduck 可以告诉您设计时的问题,远远领先于执行。

<小时/>

至于间歇性错误,我怀疑这是因为您在对象实际可用之前访问了它们。 Initialize你的类的处理程序运行在 New Presenter语句,调用返回并引用分配 pres .

我尝试看看是否将代码从 Initialize 中移出处理程序并进入一些参数化初始化程序可以修复它。

If pres Is Nothing Then
    Set pres = New Presenter
    pres.Initialize ProcessMaster
End If

这在哪里Initialize程序可能如下所示(未经测试):

Public Sub Initialize(ByVal masterSheet As Worksheet)
    Set sheet = masterSheet
    Set buttonHideOwnerToAvailability = masterSheet.Buttons("btnHideAssetOwnerToAvailability")
End Sub

这个想法是,注入(inject)工作表依赖项,而不是将其耦合到演示者类(这是一件非常好的事情!),但主要是让类实例在我们开始访问之前完全初始化自身主机文档(刚刚打开,可能有一些尚未完成的异步初始化...只是在这里大声思考,这可能是也可能不是实际发生的情况)。

<小时/>

1 每个单独检查的严重性级别可以是 configured in the settings .

关于excel - Rubberduck VBA 代码检查 : Member 'x' has a 'VB_VarHelpID' attribute with value '-1' , 但没有相应的注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59323319/

相关文章:

excel - VBA:显示标准运行时错误处理程序

excel - 在“代理”接口(interface)+类中实现工作表的代码后,可以正确处理工作表事件

vba - 橡皮鸭 VBA : What can cause a Resolver Error?

vba - 如何对 VBA 代码进行单元测试? - 两个不同的指针

excel - 当 Evaluate Match 找不到它的条件时显示错误

excel - VBA:更改 Excel 单元格宽度

php - 时间戳 SQL 到 Excel

vba - Excel VBA 宏 - 循环过滤表的列

vba - Excel VBA - 找到第一个空列

VBA 事件仅引发一次(间歇性)