【问题标题】:Can having multiple instances of Excel open cause VBA issues?打开多个 Excel 实例会导致 VBA 问题吗?
【发布时间】:2019-06-26 20:31:15
【问题描述】:

我在工作簿 A 中有代码可以打开并对工作簿 B 执行操作。当工作簿 A 和 B 是唯一打开的 excel 文件(或者如果工作簿 A 是唯一打开的文件)时,代码运行良好。但是,如果我打开任何其他工作簿(称为工作簿 C),宏将无法正确运行。它不会导致错误消息,它只是运行完成而不做任何它应该做的“东西”(这些东西基本上是在工作簿 B 中找到东西并将它们粘贴到工作簿 A 中)。

FWIW,我做了以下简单的实验:

  1. 打开所有 3 个工作簿(A、B 和 C)
  2. 选择工作簿 C,使其处于活动状态并位于前窗口
  3. 运行代码workbookB.sheet1.activate(这不是逐字逐句的,我知道编写的这段代码会失败)

当我进行上述测试时,它甚至没有使工作簿 B 成为活动工作簿。同样,它不会导致 excel 抛出错误消息,它只是运行并将工作簿 C 保留为活动工作簿。

编辑:我已经测试了更多,下面的代码应该更改工作簿 B 中单元格的值,而是将值放入工作簿 C。我很困惑,因为没有以任何方式引用工作簿 C (该模块位于工作簿 A)

Sub test()
    Dim wb As Workbook
    Set wb = Workbooks.Open("U:\workbookB.xlsx")
    wb.Worksheets("ED").Range("Z1").Value = "TEST"
End Sub

编辑 2:当工作簿 A 和 B 已打开几个小时且工作簿 C 最近打开时,就会出现此问题。我关闭了工作簿 B,然后重新运行了代码,它工作正常。这使我相信多个excel打开实例存在某种问题。尽管希望这是低风险的,但我仍然很好奇是否有人可以通过某种方式对其进行编码以作为预防措施?谢谢!

【问题讨论】:

  • 通常不需要Activate。完全限定您正在使用的工作簿和工作表是您所需要的。
  • BigBen - 请参阅更新。我知道“激活”不是必需的,我只是将它用作一种简单的故障排除方法 - 除了“激活”之外,我还可以使用不同的操作来复制问题。在关闭/重新打开并修复它之后,我想知道是否这是打开多个 excel 实例的错误
  • 在“wb”上设置一个监视并检查 FullPath 以确认它确实是您期望的文件。
  • 弗兰克 - 这似乎很有帮助,我究竟如何在变量上“设置手表”?谢谢!
  • end sub之前的代码中输入debug.print wb.path

标签: excel vba


【解决方案1】:

有一个微妙的错误(我不敢这么称呼它,但这就是它的样子)你需要小心。

如果您尝试通过代码打开的工作簿已经打开,那么您偶尔会看到一些意外行为(例如 Workbooks.Open() 的返回值被分配给 ThisWorkbook 而不是您期望的文件)。

例如,下面的代码在“Tester.xlsm”中运行并打开“EmptyTest.xlsx”,但如果该文件已经打开,Workbooks.Open 调用无法正确分配wb 变量,它最终指向“Tester.xlsm”。这可能会导致问题。

复制,

  • 打开 Excel
  • 打开“EmptyTest.xlsx”
  • 打开“Tester.xlsm”
  • 运行“Tester”子

测试代码:

Sub Tester()

    Dim wb As Workbook

    'with "EmptyTest" already open
    Set wb = Workbooks.Open("C:\Tester\EmptyTest.xlsx")
    Debug.Print wb.Name '>> Tester.xlsm  -  oops!

    'close"EmptyTest" before proceeding
    Workbooks("EmptyTest.xlsx").Close False

    'with  "EmptyTest" closed
    Set wb = Workbooks.Open("C:\Tester\EmptyTest.xlsx")
    Debug.Print wb.Name '>>EmptyTest.xlsx - OK

End Sub

在我的系统上完全可重现 (win10/Office 365)

【讨论】:

  • 谢谢蒂姆!所以为了防止我的代码出现问题,我应该添加一个检查 wb 是否已经打开的部分吗?
【解决方案2】:

我认为您的问题是您正在打开工作簿 B。您说,如果您关闭并重新打开它,它就会起作用。

因此,您对工作簿 B 所做的任何更改都将丢失,因为它将重新打开原始工作簿。 (自动保存实际上并不保存工作簿,它保存一个单独的副本。)

您需要检查工作簿是否已经打开,只有在当前未打开时才重新打开。

(非常粗略的代码)

Sub test()
    Dim wb As Workbook
    For Each wb In ThisWorkbook.Application.Workbooks
        If wb.Path & "\" & wb.Name = "U:\workbookB.xlsx" Then Exit For
    Next
    If wb.Path & "\" & wb.Name <> "U:\workbookB.xlsx" Then Set wb = ThisWorkbook.Application.Workbooks.Open("U:\workbookB.xlsx")
    wb.Worksheets("ED").Range("Z1").Value = "TEST"
End Sub

但是(正如其他人所说)您确实应该检查是否没有其他 Excel 实例正在运行并也考虑它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-23
    • 1970-01-01
    • 1970-01-01
    • 2015-07-21
    • 2011-06-22
    • 1970-01-01
    • 2015-09-23
    相关资源
    最近更新 更多