【问题标题】:Open workbook if not already open, if already, then get that reference如果尚未打开,则打开工作簿,如果已经打开,则获取该参考
【发布时间】:2018-03-12 12:02:42
【问题描述】:

我有一个场景可以在另一个工作簿路径中的工作簿中进行一些更改。但问题是我需要检查工作簿是否已经打开。如果不是,我需要将打开的实例添加到工作簿变量中。

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

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 变量中。

【问题讨论】:

  • 您需要保留您打开的所有工作簿及其路径的参考,然后在使用Application.ActiveWorkbook = TheWorkBook激活它之前比较打开它的路径
  • 如果你喜欢一个例子我可以添加它
  • @Tarek.Eladly 当然我喜欢有一个..唯一的事情就是在已经打开的时候获取打开的工作簿的实例
  • 什么是printf?是自定义函数吗?你的代码编译了吗?
  • @Vityata Yea.. 这是我的自定义函数,类似于 C# 或 VB.NET 中的 String.format

标签: vba excel


【解决方案1】:

我有办法

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

在循环中,它遍历所有工作簿,如果它在那里获取该引用..

【讨论】:

  • 这只会遍历同一 Excel 实例中的工作簿。看看我更新的答案。
  • 不错的@SandeepThomas
  • @SandeepThomas - 你知道什么是 Excel 实例吗?
  • 对不起,我只是一个 VBA 的新手。来自 C#
  • If fo = False Then 也可以写成IF NOT fo THEN。这是一个口味问题,但对于变量名称,例如WorkbookIsOpen,我发现IF NOT WorkbookIsOpen THEN 更易于阅读。
【解决方案2】:

希望对你有帮助

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)

【讨论】:

  • 对不起..我猜你误解了这个问题..我们需要的是将该工作簿的打开实例引用到工作簿对象中
【解决方案3】:

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

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

MSDN Wrokbook Object

因此,如果您的工作簿位于同一个 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

GetObject MSDN


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

这是 2 个工作簿在 2 个不同实例中的样子:

使用多个实例的优缺点 (Source answers.microsoft.com):

优点

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

  • 如果你想有一个单独的 Undo 链,让每个 Undo 只在当前活动的工作簿中撤消,那么单独的实例确实可以实现这一点。

缺点

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

  • 如果您希望能够例如按 Ctrl+F6 在打开的文件之间快速跳转,然后使用多个实例将无法实现。

  • Paste Special 在实例之间不起作用。有关详细信息,请参阅此内容。

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


代码看起来没问题,只需使用Set 关键字:

If fo = False Then set wb = Workbooks.Open(filename:=cf)

【讨论】:

  • 抱歉,我的实际问题是 fo 是否为真?在那种情况下,我需要将打开的实例放入工作表变量
  • 好的。如果打开然后关闭它并重新打开的问题是,想象一下如果 VBA 应用程序已经对该工作簿进行了一些更改,我们不能只是关闭它。所以很高兴得到它打开的实例
  • @SandeepThomas - 看看这里 - stackoverflow.com/questions/2971473/…,有一些可行的解决方案可以获取打开的实例。
  • @SandeepThomas - 或使用GetObject
  • 嗨,我在那里做了一个解决方案,幸运的是它运行良好。分享了答案
【解决方案4】:

这是一个快速功能,如果工作簿尚未打开,它将打开它:

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

【讨论】:

    猜你喜欢
    • 2013-10-26
    • 1970-01-01
    • 1970-01-01
    • 2013-02-03
    • 1970-01-01
    • 2014-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多