Rubberduck VBA 代码检查:成员“x”具有值为“-1”的“VB_VarHelpID”属性,但没有相应的注释

Yas*_*nov 4 excel vba rubberduck

我正在使用“工作表抽象\工作表代理”技术开发 Excel VBA 项目,在没有工作表文章和我的问题here中的后续问题中进行了描述。我的 VBA 代码是按照 MVP 设计模式构建的,并且我编写了尽可能多的 OOP 代码。Rubberduck 的“代码检查”功能在此过程中提供了很大帮助,但是在最近的版本中(我认为从 v2.4.1.4*** 开始,但我无法准确指出确切版本)我开始始终如一地得到一些我不太理解的“Rubberduck Opportunities”和“Code Quality Issues”警告。

正如标题中提到的,第一个是Member 'x' has a 'VB_VarHelpID' attribute with value '-1', but no corresponding annotationRubberduck Opportunity。每当我在“WorksheetProxy”类中声明事件公开工作表(或其他事件公开对象,即命令按钮)时,我都会得到这个。以下代码中的两行都会触发此错误:

' This code sits in my ProcessMasterProxy class
Private WithEvents sheet As Worksheet
Private WithEvents buttonHideOwnerToAvailability As CommandButton
Run Code Online (Sandbox Code Playgroud)

然后,每当我声明一个事件公开“SheetProxy”类的实例或一个事件公开用户表单时,我都会在“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
Run Code Online (Sandbox Code Playgroud)

Rubberduck 的代码检查为我提供了针对此类错误的两种操作: 1.“添加属性注释”,'@MemberAttribute VB_VarHelpID, -1在声明上方插入行和 2​​.“删除属性”似乎什么都不做,单击它后错误仍然存​​在。

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

同样,我担心在“代码质量问题”部分中出现的相关错误:To the variable 'sheet' of declared type 'EXCEL.EXE:Excel.Worksheet' a value is set assigned with the incompatible declared type '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
Run Code Online (Sandbox Code Playgroud)

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

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

Private pres As Presenter
If pres Is Nothing Then
    Set pres = New Presenter
End If
Run Code Online (Sandbox Code Playgroud)

这个问题是否与上述两个代码检查建议/错误中的任何一个有关?

Mat*_*don 5

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

“缺少成员注释”的检查结果

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

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

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

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


“不兼容类型”检查结果是一个已知问题:目前,Rubberduck 没有看到Worksheet工作表模块的Workbook界面(也没有看到 的界面ThisWorkbook),这导致了文档模块周围的一些误报。在Rubberduck 可以分辨出ProcessMaster它不仅是一个ProcessMaster对象而且还是一个Worksheet(我们将在2.5.x 中对此进行修复)之前,当它抱怨文档模块和MSForms 接口(它们具有相同的底层)时,忽略该检查可能是安全的问题)。

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


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

我会尝试看看是否将代码从Initialize处理程序移动到一些参数化的初始化程序中会解决它。

If pres Is Nothing Then
    Set pres = New Presenter
    pres.Initialize ProcessMaster
End If
Run Code Online (Sandbox Code Playgroud)

Initialize过程可能如下所示(未经测试):

Public Sub Initialize(ByVal masterSheet As Worksheet)
    Set sheet = masterSheet
    Set buttonHideOwnerToAvailability = masterSheet.Buttons("btnHideAssetOwnerToAvailability")
End Sub
Run Code Online (Sandbox Code Playgroud)

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


1可以在设置中配置每个单独检查的严重程度。