【问题标题】:How to check if a workbook is open and use it如何检查工作簿是否打开并使用它
【发布时间】:2016-03-01 22:44:30
【问题描述】:

我制作了一个宏来打开两个工作簿并用它们做一些事情。此宏从第三个工作簿运行,该工作簿调用任何其他两个用户选择的工作簿,在打开它们之前,我不知道它们的名字。 所以!我知道 Excel 2010 没有内置函数来检查工作簿是否打开,所以我一直在尝试将工作簿与 Nothing 进行比较,但它不起作用,而且我在不同站点中找到的每种解决方法都倾向于使用工作簿的名称。
还有另一种方法吗?
这个想法是用两个用户定义的工作簿运行一个宏,然后,也许,在同一个工作簿中重新运行它,但 Excel 让我放弃了更改。
也许一种解决方法可能是在提示重新打开时告诉 excel,而不是重新打开并处理该错误以仅使用相同的工作簿,至少我知道部分或名称将是多少。
例如,一个里面会有文本“cluster”,另一个是“translation”,所以,也许在像
下一个这样的循环中,我可以找到并使用我需要的工作簿,但如果我已经检查过它是否打开.或者,这种方式是否可以查看是否已经打开?

 For each wbk in Application.Workbooks
    If wbk.Name Like "*cluster*" Then
       WorkingWorkbook = wbk.Name
    End If
 next

我的代码如下:

 Sub structure()
    Application.ScreenUpdating = False
    Dim translationWorkbook As Worksheet
    Dim clusterWorkbook As Workbook

    If Not clusterWorkbook Is Nothing Then
      Set clusterWorkbook = Application.Workbooks.Open(ThisWorkbook.Sheets(1).Range("E5").Value2)
    Else
      Set clusterWorkbook = Application.Workbooks(parseFilePath(ThisWorkbook.Sheets(1).Range("E5")))
    End If
      Set translationWorkbook = Application.Workbooks.Open(ThisWorkbook.Sheets(1).Range("E6").Value2).Worksheets("String_IDs_Cluster") 'Translation table target for completing
 End Sub

传递给Workbooks.Open 的参数是我的下一个函数在工作表中写入的参数:

 Private Sub MS_Select_Click()
    Dim File As Variant
    Dim Filt As String

    Filt = "Excel 97-2003 File(*.xls), *.xls," & "Excel File(*.xlsx),*.xlsx," & "Excel Macro File (*.xlsm),*.xlsm"
    File = Application.GetOpenFilename(FileFilter:=Filt, FilterIndex:=2, Title:="Select Menu Structure File")
    If File = False Or File = "" Then
        MsgBox "No File Selected"
        Exit Sub
    End If
    ThisWorkbook.ActiveSheet.Range("E5").Value2 = File
 End Sub

translationWorkbook 相同,但位于不同的单元格中Application.Workbooks(file) 的 xls 扩展名向我发送“下标范围错误”。
为什么会这样?
基本上我的问题是:

  • 如何检查并使用打开的工作簿?要么通过处理 excel 提示错误或未尝试重新打开同一个文件。
  • 为什么尝试使用Application.Workbooks() 打开工作簿并返回我的函数会失败?在这里,我的问题分为两部分......首先:使用我的函数,如果我给出一个字符串作为参数,它不会起作用吗?或者,在将它作为参数传递之前,我需要将函数的结果分配给一个变量?
  • 第二:如果我尝试打开像 Application.Workbooks("clusterworkbook") 这样的工作簿,它会向我发送另一个“下标错误”,但是,在我使用文件对话框提示之前,我这样做了并且工作正常。

我们将不胜感激。

编辑

函数 ParseFilePath 添加:

 Function parseFilePath(fullpath As Range) As String
    Dim found As Boolean
    Dim contStart As Integer
    Dim contEnd As Integer
    contEnd = InStr(fullpath, ".") - 1
    contStart = contEnd
    found = False
    Do While found = False
        If fullpath.Characters(contStart, 1).Text = "\" Then
            found = True
        Else
            contStart = contStart - 1
        End If
    Loop
    parseFilePath = fullpath.Characters(contStart + 1, (contEnd - contStart)).Text
 End Function

【问题讨论】:

    标签: vba excel


    【解决方案1】:

    我一直在使用下面的代码来识别 Excel 工作簿是否打开。如果是,那么我激活它并做一些事情。如果没有,我打开它并做一些事情。

    sub test()
        Dim Ret
    
            Ret = IsWorkBookOpen("Your excel workbook full path")
    
            If Ret = False Then
            Workbooks.Open FileName:="Your excel workbook full path", UpdateLinks:=False
            Else
            Workbooks("Workbook name").Activate
            End If
    end sub
        Function IsWorkBookOpen(FileName As String)
            Dim ff As Long, ErrNo As Long
    
            On Error Resume Next
            ff = FreeFile()
            Open FileName For Input Lock Read As #ff
            Close ff
            ErrNo = Err
            On Error GoTo 0
    
            Select Case ErrNo
            Case 0:    IsWorkBookOpen = False
            Case 70:   IsWorkBookOpen = True
            Case Else: Error ErrNo
            End Select
        End Function
    

    【讨论】:

    • 也尝试了您的解决方案并且工作正常,但是在这种情况下我不能使用激活,因为我在其他情况下使用它。谢谢
    【解决方案2】:
    1. 如何检查并使用打开的工作簿?通过处理 excel 提示的错误或不尝试重新打开同一个文件。

    对您的程序structure 做了一些小的修改。与您尝试测试工作簿变量的内容类似,只是您必须首先尝试设置变量,您这样做的方式将始终返回空,因为您之前没有尝试设置它。我还测试了翻译工作簿,因为它也可能无法打开。

    我假设E5E6 中的值包含工作簿的FullName(即路径+文件名),并且parseFilePath 是从FullName 中提取文件名的函数。

    Sub structure()
        Application.ScreenUpdating = False
        Dim clusterWorkbook As Workbook
        Dim translationWorkbook As Workbook
        Dim translationWorksheet As Worksheet
    
        With ThisWorkbook.Sheets(1)
    
            On Error Resume Next
            Set clusterWorkbook = Application.Workbooks(parseFilePath(.Range("E5").Value2))
            On Error GoTo 0
            If clusterWorkbook Is Nothing Then Set clusterWorkbook = Application.Workbooks.Open(.Range("E5").Value2)
    
            'Set Translation table target for completing
            On Error Resume Next
            Set translationWorkbook = Application.Workbooks(parseFilePath(.Range("E6").Value2))
            On Error GoTo 0
            If translationWorkbook Is Nothing Then
                Set translationWorksheet = Application.Workbooks.Open(.Range("E6").Value2).Sheets("String_IDs_Cluster")
            Else
                Set translationWorksheet = translationWorkbook.Sheets("String_IDs_Cluster")
            End If
    
        End With
    
    End Sub
    
    1. 为什么尝试使用 Application.Workbooks() 打开工作簿 我的函数返回失败?在这里,我的问题分为两部分...... 第一:使用我的函数,如果我将字符串作为 争论?或者,在将它作为参数传递之前,我需要分配 我的函数的结果到一个变量?

    不知道为什么它不起作用,请按照指示更改程序。

    我使用这个函数测试了上面的过程,从Fullname中提取Filename,它成功了:

    Function parseFilePath(sFullName As String) As String
        parseFilePath = Right(sFullName, Len(sFullName) - InStrRev(sFullName, "\"))
    End Function
    
    1. 第二:如果我尝试打开像 Application.Workbooks("clusterworkbook") 这样的工作簿,它会向我发送另一个 “下标错误”,但是,在我使用文件对话框提示之前,我做到了 这种方式效果很好。

    请记住,您并没有单独使用该行,它很可能具有以下内容:

    set Workbook = Application.Workbooks("clusterworkbook")
    

    所以命令是设置一个变量,而不是打开工作簿,因此唯一可行的情况是工作簿已经打开,因此设置了变量。失败的时间是工作簿未打开并且您尝试设置变量时出现错误。

    建议访问这些页面 Excel Objects, On Error Statement

    【讨论】:

    • 很好的假设。我应该澄清一下并将我的 parseFilePath 函数放在这里。我将编辑我的问题以显示它并尝试您的代码。只是一条评论,如果我首先使用Set clusterWorkbook = Application.Workbooks(parseFilePath(.Range("E5").Value2)) 设置clusterWorkbook,那么不会因为没有打开工作簿而表现出色吗?因为,在那个阶段,只有运行宏的文件被打开。
    • 如果工作簿未打开,则 excel 会给出一个错误,由于命令 On Error ... 而未显示,因此变量保持初始值 Nothing,这是为了验证文件是否已完成的检查已经打开了。请访问建议的页面...
    • 一切正常,非常感谢,实际上部分问题是,在我的函数中,我正在删除文件扩展名
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多