如何避免使用IsWorkBookOpen进行自我引用

时间:2015-12-17 18:59:33

标签: excel vba excel-vba

我想在服务器上使用共享的excel工作簿,这些工作簿可以彼此不同地连接。

我花了很多天才发现它有很多问题要处理,因为共享工作簿不支持很多功能。

  • 我希望宏检查打开文件以确定该文件是否被其他人打开,如果“是”,它会告诉该人稍后再回来。
  • 不幸的是,我现在正在引用自己,这会创建一个循环。
  • 我打开文件,它会检查自己是否已经打开,然后在消息关闭之后。

你能不能帮助我逃避循环,以便它符合目的?

我认为只有代码的上半部分与我的问题有关,所以我不会完全发布:

Option Explicit
Private Sub Workbook_Open()

    Dim Ret

    Ret = IsWorkBookOpen(ThisWorkbook.FullName)

    If Ret = True Then
        MsgBox "Come back later."
    ThisWorkbook.Close savechanges:=False
    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

3 个答案:

答案 0 :(得分:1)

我认为你不需要为了你的目的使用这个功能 您可以使用以下方法实际检查文件的状态:

ThisWorkbook.ReadOnly

返回一个布尔值;如果文件是只读文件,则为true。

现在,在打开文件之前,你真的无法抑制弹出询问是否要将其打开为只读。但是,您仍然可以尝试使用此代码,该代码将在用户以只读方式打开文件时触发。

Private Sub Workbook_Open()
    If ThisWorkbook.ReadOnly Then
        MsgBox "Comeback some other time. File in use"
        ThisWorkbook.Close False
    End If
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
    Application.Quit
End Sub

答案 1 :(得分:1)

IsWorkBookOpen测试相比,ReadOnly方法的优点是与通过网络打开工作簿相比的速度。

我建议您更改从vbs或单独的Excel文件加载支票的方法 - 因为这是最好的方法。

  1. 以下代码可以作为vbs保存在网络驱动器的NotePad中,例如 check.vbs 。代码检查文件是否打开,如果没有,则在新的Excel实例中启动该文件。如果是,则提供消息。
  2. vbs代码

    Dim objExcel
    FileName = "C:\temp\file.xlsm"
    If Not IsWorkBookOpen(FileName) Then
        Set objExcel = CreateObject("Excel.Application")
        Set ojbWb = objExcel.Workbooks.Open(FileName)
        objExcel.Visible = True
    Else
        wscript.echo FileName & " already opened"
    End If
    
    Function IsWorkBookOpen(FileName)
    Set oFSO = CreateObject("Scripting.FileSystemObject")
    On Error Resume Next
    Set objFile = oFSO.OpenTextFile(filename, 8, False)
    ErrNo = Err   
    ObjFile.Close
    On Error GoTo 0
    
    Select Case ErrNo
    Case 0:    IsWorkBookOpen = False
    Case 70:   IsWorkBookOpen = True
    Case Else: Error ErrNo
    End Select
    set objFSO = Nothing
    End Function
    
    1. 如果您想从实际文件中运行检查,则需要更改为ReadOnly测试

      代码

    2. Private Sub Workbook_Open()
      If Me.ReadOnly Then MsgBox "file already opened", vbCritical
      End Sub

答案 2 :(得分:0)

我发布这个,因为我在其他论坛上也看到了这个问题没有答案。

我想在服务器上使用许多共享的excel工作簿,这些工作簿可以彼此不同地连接。

我想使用所谓的共享工作簿,以便每个人都可以访问它,特别是因为它会跟踪(用户,时间......)内的更改

我希望宏检查打开文件以确定该文件是否由其他人打开,如果"是",它会告诉该人稍后再回来。

这里建议的回复无能为力,我相信没有机会为文件本身的路径创建一个宏,以便IsWorkBookOpen(ThisWorkbook.FullName)  可以像我尝试的那样使用。

我决定编写宏来跟踪工作簿中的更改,就好像它已经共享了#34;。通过这种方式,我能够"取消共享"它并使用此处讨论的ReadOnly方法。