VbComponents.Remove并不总是删除模块

sig*_*gil 9 excel vba excel-vba

我正在尝试使用Chip Pearson的代码来覆盖现有的VBA代码模块,并从另一个项目导入.原始代码在这里.

我正在看的特定部分是:

With ToVBProject.VBComponents
    .Remove .Item(ModuleName)
End With
Run Code Online (Sandbox Code Playgroud)

但是这个VBComponents.Remove调用有时只有在VBA执行停止后才会生效 - 也就是说,删除操作在所有语句完成之后才会生效,或者如果代码遇到断点然后我停止调试.这是一个问题,因为以下代码用于导入新模块或用新模块替换现有模块的代码:

    Set VBComp = Nothing
    Set VBComp = ToVBProject.VBComponents(CompName)

    If VBComp Is Nothing Then
        ToVBProject.VBComponents.import filename:=FName
    Else
        If VBComp.Type = vbext_ct_Document Then
            'delete the module's code,
            'import a temp module,
            'copy over the temp module code,
            'delete the temp module
        End If
    End If
Run Code Online (Sandbox Code Playgroud)

模块删除尚未生效,所以VBComp不是Nothing,只要调试器知道.所以.import不会被召唤.

即使我注释掉if VBComp.Type = vbext_ct_document then并且end if新模块的代码将覆盖现有的代码,无论VBComp.Type它是什么,一旦代码完成执行,模块仍将最终被删除,并且不会导致替换它.

奇怪的是,所有模块都不会发生这种情况; 一些实际上在VBComponents.Remove通话后被实时删除.

我在各种论坛上看过几篇不同的帖子,并没有令人满意的解决方案.目前我正在使用将.Remove调用更改为:

    With ToVBProject.VBComponents
        .Item(ModuleName).name = ModuleName & "_remove"
        .Remove .Item(ModuleName & "_remove")
    End With
Run Code Online (Sandbox Code Playgroud)

因此,通过更改名称,ModuleName似乎不再存在,因此.import将发生呼叫.当然,这假设没有名称ModuleName & "_remove"实际存在的模块.

有更好的解决方案吗?

小智 6

我尝试重命名,发现它导致了表模块和ThisWorkbook的问题.所以我稍微修改了它,只重命名非文档模块.这看起来干净利落.

        If .Item(ModuleName).Type <> vbext_ct_Document Then
            .Item(ModuleName).Name = ModuleName & "_OLD"
            .Remove .Item(ModuleName & "_OLD")
        Else
            .Remove .Item(ModuleName)
        End If
Run Code Online (Sandbox Code Playgroud)


小智 1

我以前也遇到过这样的事情。“DoEvents”命令通常会有所帮助。你尝试过吗?

其他时候,我将命令放在 do while 循环中,并使用布尔值来不断检查相关命令是否成功。有时需要在循环中包含 DoEvents 命令。

只要记住在循环中放入一些东西,这样经过这么多次循环它就会放弃。陷入无限循环可能会很烦人。