Vba 打开工作簿如果尚未打开,如果已经打开,则获取该引用

Vba 打开工作簿如果尚未打开,如果已经打开,则获取该引用,vba,excel,Vba,Excel,我想在另一个工作簿路径的工作簿中进行一些更改。但问题是我需要检查工作簿是否已经打开。如果没有,我需要将打开的实例转换为工作簿变量 这是我用来检查工作簿是否打开的代码,然后是打开的代码 Function IsFileOpen(fileFullName As String) Dim FileNumber As Integer Dim errorNum As Integer On Error Resume Next FileNumber = FreeFile()

我想在另一个工作簿路径的工作簿中进行一些更改。但问题是我需要检查工作簿是否已经打开。如果没有,我需要将打开的实例转换为工作簿变量

这是我用来检查工作簿是否打开的代码,然后是打开的代码

Function IsFileOpen(fileFullName As String)
    Dim FileNumber As Integer
    Dim errorNum As Integer

    On Error Resume Next
    FileNumber = FreeFile()   ' Assign a free file number.
    ' Attempt to open the file and lock it.
    Open fileFullName For Input Lock Read As #FileNumber
    Close FileNumber       ' Close the file.
    errorNum = Err         ' Assign the Error Number which occured
    On Error GoTo 0        ' Turn error checking on.
    ' Now Check and see which error occurred and based
    ' on that you can decide whether file is already
    ' open
    Select Case errorNum
        ' No error occurred so ErroNum is Zero (0)
        ' File is NOT already open by another user.
        Case 0
         IsFileOpen = False

        ' Error number for "Permission Denied." is 70
        ' File is already opened by another user.
        Case 70
            IsFileOpen = True

        ' For any other Error occurred
        Case Else
            Error errorNum
    End Select

End Function
Public Function getConsolidatedDataFile() As Workbook
    Dim p As String
    p = ActiveWorkbook.Path
    Dim cf As String
    cf = printf("{0}\ConsolidatedData.xlsx", p)
    Dim wb As Workbook
    Dim fo As Boolean
    fo = IsFileOpen(cf)
    If fo = False Then wb = Workbooks.Open(filename:=cf)
    ''I need to get the code for this place of fo is true
    getConsolidatedDataFile wb

End Function

因此,如果文件打开,我需要将工作簿放入wb变量。

要将工作簿引用到工作簿集合,应该打开它-

工作簿对象是工作簿集合的成员。工作簿集合包含当前在Microsoft Excel中打开的所有工作簿对象

因此,如果工作簿位于同一Excel实例中,请尝试以下操作:

Public Sub TestMe()        
    Dim wb As Workbook
    Set wb = Workbooks("12.xlsx")    
End Sub
如果它不在同一个实例中,那么
GetObject
应该可以工作:

Public Sub TestMe()        
    Dim wb As Workbook
    Set wb = GetObject("C:\path\12.xlsx")    
    Debug.Print wb.Worksheets(1).Name
End Sub


这是同一实例中3个工作簿的外观:

这是两个工作簿在两个不同实例中的外观:

使用多个实例()的优缺点:

专业人士

  • 如果您有32位Excel,每个实例最多可以使用3 GB内存。如果您有一台功能强大的计算机、非常繁重的文件和32位Excel,则每个Excel实例都可以使用3 GB。例如,对于2个Excel.exe实例,您可以说Excel的总内存可以使用三倍。(请注意,64位Excel不需要这样做,因为它不受每个实例3 GB内存的限制)

  • 如果希望有一个单独的撤消链,以便每次撤消只撤消当前活动工作簿中的撤消,那么单独的实例确实可以实现这一点

缺点

  • 如果希望所有打开的文件共享一个公共撤消链,那么使用多个实例将无法实现这一点

  • 如果您希望能够(例如)按Ctrl+F6在打开的文件之间快速跳转,则使用多个实例无法实现这一点

  • “特殊粘贴”在实例之间不起作用。有关更多信息,请参见此

  • 无法通过单击在单独运行实例中的两个文件之间建立工作簿链接,并且不会实时更新


代码看起来正常,只需使用
Set
关键字:

If fo = False Then set wb = Workbooks.Open(filename:=cf)
我希望这有帮助

Dim dict As Dictionary

Function OpenFile(fileFullName As String) As Workbook


If (dict.Exists(fileFullName)) Then

OpenFile = dict.Item(fileFullName)

End If

dict.Add "fileFullName", Workbooks.Open(Filename:=fileFullName)

OpenFile = dict.Item(fileFullName)

End Function

Application.ActiveWorkbook = OpenFile(fileFullName)
我有个解决办法

If fo = False Then
    Set wb = Workbooks.Open(filename:=cf)
Else
    Dim w As Workbook
    For Each w In Workbooks
        If w.FullName = cf Then
            Set wb = w
        End If
    Next
End If

这里是循环,它遍历所有工作簿,如果它在那里,则获取该引用。

这里有一个快速函数,它将在工作簿尚未打开时打开工作簿:

Function GetWorkBook(ByVal sFullName As String, Optional ReadOnly As Boolean) As Workbook
    Dim sFile As String: sFile = Dir(sFullName)
    On Error Resume Next
        Set GetWorkBook = Workbooks(sFile)
        If GetWorkBook Is Nothing Then Set GetWorkBook = Workbooks.Open(sFullName, ReadOnly:=ReadOnly)
    On Error GoTo 0
End Function

您需要保留打开的所有工作簿及其路径的引用,然后如果在使用
Application.ActiveWorkbook=TheWorkBook
激活它之前打开它,请比较路径,如果您喜欢我可以添加的示例it@Tarek.Eladly我当然想要一个。。唯一的事情是在已经打开时获取已打开工作簿的实例什么是
printf
?它是自定义函数吗?你的代码能编译吗?@Vityata是的。。这是我的自定义函数,类似于C#或VB.net中的String.format。我的实际问题是fo是否为真?在这种情况下,我需要将打开的实例放入工作表variableOk。。“如果打开然后关闭并重新打开”的问题是,想象一下,如果VBA应用程序已经对该工作簿进行了一些更改,我们就不能直接关闭它。。所以打开它真是太好了instance@SandeepThomas-看看这里-,有一些工作解决方案可以获取打开的实例。@SandeepThomas-或者使用
GetObject
Hi我在那里做了一个解决方案,幸运的是它工作得很好。。分享答案对不起。。我猜你误解了这个问题。。我们需要的是将该工作簿的已打开实例引用到工作簿对象中。这将只遍历同一Excel实例中的工作簿。看看我最新的答案,不错@SandeepThomas@SandeepThomas-你知道什么是Excel实例吗?对不起,我只是个VBA新手。。来自C#
如果fo=False,那么
也可以写成
如果不是fo,那么
。这是一个品味的问题,但是对于变量名,比如
WorkbookIsOpen
我发现
如果不是WorkbookIsOpen,那么
更容易阅读。