Vba 在visual basic中打开两个工作簿时,工作簿变量分配不正确

Vba 在visual basic中打开两个工作簿时,工作簿变量分配不正确,vba,excel,Vba,Excel,运行下面的代码时,我会根据打开的工作簿得到不同的结果。子模块位于与Master Sheet.xlsm关联的模块中 如果仅打开Master Sheet.xlsm,则代码将正确运行,即消息框显示(其中逗号分隔第一个和第二个消息框):Master Sheet,已转移案例03-09-18 如果Master Sheet.xlsm和transferred cases 03-09-18.xlsx打开,但transferred cases 03-09-18.xlsx第二次打开,则消息框显示:transferre

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

  • 如果仅打开
    Master Sheet.xlsm
    ,则代码将正确运行,即消息框显示(其中逗号分隔第一个和第二个消息框):Master Sheet,已转移案例03-09-18

  • 如果
    Master Sheet.xlsm
    transferred cases 03-09-18.xlsx
    打开,但
    transferred cases 03-09-18.xlsx
    第二次打开,则消息框显示:transferred cases 03-09-18,transferred cases 03-09-18

  • 如果
    Master Sheet.xlsm
    transfered cases 03-09-18.xlsx
    都打开,但
    Master Sheet.xlsm
    第二次打开,则消息框显示:Master Sheet,Master Sheet



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

    请注意,您可以使用传递工作簿名称的类似函数检查工作簿是否已打开

    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
    ,则在使用
    Workbooks.Open()
    工作簿
    变量赋值时,可以
    设置x=Workbooks(“您的工作簿名称”)
    ,这意味着要打开的工作簿已关闭。否则,如果所有工作簿都已打开,则它将使用上次打开的带有
    工作簿.Open()
    的工作簿或代码所在的工作簿

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

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


    另一个更快的选项是显式分配变量,如所述,更快,因为您不会关闭已打开的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,“\”))
    通过
    \
    工作簿获取拆分数组的最后一个元素。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
    

    这就是你的全部代码吗?我无法复制此文件。在运行代码之前,不应打开任何工作簿。Workbooks.Open始终返回上次打开的文件(即使它不是传入参数的文件)@VincentG-这很奇怪。你能用一些代码来证明吗?或文件。我在这里阅读-@Vityata我阅读了与您相同的文档。我认为这要么是一个bug,要么是糟糕的文档。尝试:运行操作代码一次,然后手动打开一个文件并重新运行代码:显示的名称将是手动打开的文件。与此完全相同-我发现此方法的问题是,它只对文件名有效,而不对文件路径有效-向其传递一个文件路径和名称,它会说它已关闭,只给它一个名字,它会说一个同名的文件是打开的,但它的路径也正确吗?SiddharthRout在@Vityata链接中的回答是覆盖所有基础的最佳方法。@ScottHoltzman你是指他回答中的链接中的那个,我认为是-
    openfullfilepath For Input Lock Read as#ff
    回答。@DarrenBartrup Cook-是的
    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