在Visual Basic中打开两个工作簿时,工作簿变量未正确分配

时间:2018-09-04 14:20:52

标签: excel vba excel-vba

运行下面的代码时,根据打开的工作簿,我得到不同的结果。子程序位于与Master Sheet.xlsm

相关的模块中
  1. 如果仅打开Master Sheet.xlsm,则代码将正确运行,即消息框显示(逗号分隔第一和第二个消息框):母版纸,已转移案件03-09-18

  2. 如果Master Sheet.xlsmtransferred cases 03-09-18.xlsx都打开了,但是transferred cases 03-09-18.xlsx处于第二打开状态,则消息框显示:已转移案例03-09-18,已转移案例03-09- 18

  3. 如果Master Sheet.xlsmtransferred cases 03-09-18.xlsx都打开了,但Master Sheet.xlsm处于第二打开状态,则消息框显示:“母版纸,母版纸”


Sub foo()
    Dim x As Workbook
    Dim y As Workbook

   '## Open both workbooks first:
   Set x = Workbooks.Open("C:\Users\owner\Documents\ExelatecOutput\Master Sheet.xlsm")
   Set y = Workbooks.Open("C:\Users\owner\Documents\ExelatecOutput\transferred cases 03-09-18.xlsx")

   'Now, copy what you want from x:
   MsgBox x.Name
   MsgBox y.Name

End Sub

为什么变量x和y分配不正确。

3 个答案:

答案 0 :(得分:3)

仅需注意,您可以通过传递工作簿名称的功能来检查工作簿是否已经打开。

Public Function BookOpen(strBookName As String) As Boolean

    Dim oBk As Workbook
    On Error Resume Next
    Set oBk = Workbooks(strBookName)
    On Error GoTo 0
    If oBk Is Nothing Then
        BookOpen = False
    Else
        BookOpen = True
    End If

End Function

如果返回true,则可以set x = Workbooks("your workbook name")

答案 1 :(得分:3)

Workbooks.Open始终返回上一个打开的文件(即使它不是传入的参数)。这可能是错误的文档,也可能是Excel IMO中的错误。

您不需要检查文件是否已打开,因为打开已经打开的文件不会引发错误,但是您稍后需要设置变量:

Workbooks.Open "C:\Users\owner\Documents\ExelatecOutput\Master Sheet.xlsm": Set x = Workbooks("Master Sheet.xlsm") ' or Set x = ActiveWorkbook since Open will activate it
Workbooks.Open "C:\Users\owner\Documents\ExelatecOutput\transferred cases 03-09-18.xlsx": Set y = Workbooks("transferred cases 03-09-18.xlsx") ' or Set y = ActiveWorkbook since Open will activate it

答案 2 :(得分:2)

使用Workbook分配给Workbooks.Open()变量时,意味着要打开的工作簿已关闭。否则,如果所有工作簿都已打开,则它将使用最后打开的Workbooks.Open()工作簿或代码所在的工作簿。

因此,请确保在尝试打开工作簿之前先将它们关闭。打开之前,您需要执行以下两个操作:

如果有打开的工作簿,则将其关闭:


另一个更快的选项是显式分配变量,如Vincent G所述,更快,因为您不会关闭已打开的变量Excel文件:

Sub TestMe()

    Dim x As Workbook
    Dim y As Workbook
    Dim xPath As String: xPath = "C:\Book1.xlsx"
    Dim yPath As String: yPath = "C:\Book2.xlsx"

    Workbooks.Open xPath
    Set x = Workbooks(Split(xPath, "\")(UBound(Split(xPath, "\"))))
    Workbooks.Open yPath
    Set y = Workbooks(Split(yPath, "\")(UBound(Split(yPath, "\"))))

    Debug.Print x.Name
    Debug.Print y.Name

End Sub

代码Split(xPath, "\")(UBound(Split(xPath, "\")))的一部分采用\分割数组的最后一个元素。