【问题标题】:Cannot remove code modules from a destination workbook through VBA无法通过 VBA 从目标工作簿中删除代码模块
【发布时间】:2015-11-12 23:11:06
【问题描述】:

我正在运行一个 Excel 2010 宏,该宏会打开另一个工作簿并删除一些代码模块(一个表单和一个 BAS 模块)。之后,它将它们重新导入为更新版本。这是代码:

For Each x In destination_wb.VBProject.VBComponents
  If LCase(x.Name) Like LCase("frmCCLogin*") Or _
      LCase(x.Name) Like LCase("modCQ_test*") Then
  destination_wb.VBProject.VBComponents.Remove (x)
Next

我对导入没有任何问题,但删除过程并不总是按预期工作。由于某种原因,BAS (modCQ_test.bas) 模块并不总是被删除。结果,当我重新导入时,会创建一个以“1”结尾的新复制模块(即 modCQ_test1.bas)。 我可以看到很多人都遇到了同样的问题,但是,没有一个建议的解决方案对我有用。不知道为什么会这样? 请指教。

【问题讨论】:

  • 您是否尝试为真/假设置Debug.Print 以输出它找到的每个名称?另外,您可以将LCase(x.Name) Like LCase("frmCCLogin*") 更改为Left(LCase(x.Name), 10) = "frmcclogin"(也用于其他检查)
  • 我将帖子标题更改为更相关。

标签: excel vba


【解决方案1】:

如果您可以使用模块的确切名称,您可以编写如下内容:

Public Sub RemoveComponent(ByVal Book As Workbook, ByVal Name As String)

On Error Resume Next
With Book.VBProject.VBComponents
    Call .Remove(.Item(Name))
End With

End Sub

如果您遇到通配符匹配问题(即 SomeName*),您可以迭代 VBComponents 集合并将名称缓存到集合或数组或其他任何内容中,然后为每个匹配的名称调用上述函数。

此外,如果您希望枚举 VBComponents 集合并像您的代码示例一样删除,我建议您按相反的顺序进行。

比如:

Public Sub RemoveComponent1(ByVal Book As Workbook, ByVal NameSearch As String)

Dim oCompS As VBComponents
Dim oComp As VBComponent
Dim i As Integer

Set oCompS = Book.VBProject.VBComponents
For i = oCompS.Count To 1 Step -1
    Set oComp = oCompS(i)
    If oComp.Name Like NameSearch Then Call oCompS.Remove(oComp)
Next

End Sub

【讨论】:

  • 是的,就是“砍掉你坐的树枝”的问题,有时候可以通过向后迭代来解决。通常,您不能安全地在 Collection 上使用 For Each,然后在循环内修改该 Collection。原因是下一次迭代在 Collection 中看到的元素更少,从而搞砸了内部计数器。这样,您可能会错过后续条目。
  • 谢谢 PaulG 和 Oliver,我听从了您的建议并以相反的顺序进行了迭代。但是问题似乎与使用 LIKE 函数有关,我还修改了代码以查找完全匹配的名称,并且成功了!很奇怪,为什么LIKE + LCASE不能识别模块名?
  • 更新:它偶尔会再次发生。例如,它工作 1-2 次,但第 3 次失败。复制的模块被添加到工作簿中。
  • 试试看能不能捕获任何错误。因此,在 RemoveComponent 函数的底部放置如下内容: If Not Err.Number = 0 then Stop。然后测试那个婴儿,看看你是否能得到一些关于错误的信息。
  • 嗯,这很奇怪。如果您手动删除模块并编译,您会在编译中遇到任何错误吗?即您的代码中的其他任何内容是否依赖于您要删除的模块中的任何函数/例程?此外,您可以尝试保留模块但用新代码替换代码而不是删除模块...
【解决方案2】:

问题已解决。这个隐藏目标工作簿的简单代码行在我的情况下解决了重复问题:

destination_wb.Windows(1).Visible = False

在此之后,您可以删除,然后添加组件。不会发生重复。

【讨论】:

    【解决方案3】:

    我经历过完全相同的现象,它已经让我发疯了好几个星期。 我确实检查了代码模块是否在移除后直接被移除了,虽然它已经从 VBE 的项目视图中消失了,但它仍然存在,因此随后的导入创建了一个名为 xxx1 的代码模块。 从长远来看,给出的任何提示都被证明不可靠,因此只是猜测。由于如上所述的现象是不可预测的,因此您永远无法真正说出其中的窍门。

    【讨论】:

    • 问题已解决。这个隐藏目标工作簿的简单代码行修复了我的情况下的重复问题:destination_wb.Windows(1).Visible = False
    • 如果它也能解决您的问题,请尝试并发表评论。
    猜你喜欢
    • 1970-01-01
    • 2016-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-03
    • 1970-01-01
    • 1970-01-01
    • 2014-03-11
    相关资源
    最近更新 更多