9

如何判断 Excel 2007 电子表格是否已打开以及谁使用 VBScript 将其打开?

我试图确定 Excel 工作簿当前是否由另一个用户打开并返回该用户在我的脚本中的身份。

我已经弄清楚谁来确定工作簿当前是否打开。这是一种解决方法,但我基本上打开工作簿并检查它是否是只读的。效果很好;我已经测试过了。

我知道这是可能的,因为如果您通过浏览器打开文件,Excel 会为您提供打开文件的用户。

这是我的代码(isWorkbookOpen.vbs):

Set objExcelTestWorkbook = CreateObject("Excel.Application")
objExcelTestWorkbook.DisplayAlerts = False 'doesn't display overwrite alert
testWorkbookFile = "I:\test_workbook.xlsx"
Set objBook = objExcelTestWorkbook.Workbooks.open(testWorkbookFile)

If objBook.ReadOnly Then
    Wscript.echo "The file is read only"
    Call EndScript
Else
    Wscript.echo "The file is available"
    Call EndScript
End If

Function EndScript
    objExcelTestWorkbook.Workbooks.close
    objExcelTestWorkbook.Quit
    WScript.Echo "Closed " & testWorkbookFile
    WScript.Quit
End Function

另外,我从命令行运行它:

cscript isWorkbookOpen.vbs
4

2 回答 2

13

我的天才同事提醒我 Excel 的“锁定”文件。打开 excel 时,您会创建一个隐藏的系统文件,其中包含打开文件的人员姓名。锁定文件在电子表格名称前以“~$”开头。例子:

如果您有一个电子表格testWorkbook.xlsx,它的锁定文件将~$testWorkbook.xlsx位于同一目录中。

这也是检查文件是否打开的一种更快、更简单的方法,因为您实际上并没有像我以前那样打开文件。现在我只是检查锁定文件是否存在,如果存在,我检查谁是锁定文件的“所有者”,这将是当前打开电子表格的人。希望这将有助于将来的人!

这是我完美运行的代码:

testWorkbookLockFile = "I:\~$test_workbook.xlsx"
Set objFSO = CreateObject("Scripting.FileSystemObject")

If objFSO.FileExists(testWorkbookLockFile) Then
    WScript.Echo "The file is locked by " & GetFileOwner(testWorkbookLockFile)
Else
    WScript.Echo "The file is available"
End If

Function GetFileOwner(strFileName)
    'http://www.vbsedit.com/scripts/security/ownership/scr_1386.asp
    Set objWMIService = GetObject("winmgmts:")
    Set objFileSecuritySettings = _
    objWMIService.Get("Win32_LogicalFileSecuritySetting='" & strFileName & "'")
    intRetVal = objFileSecuritySettings.GetSecurityDescriptor(objSD)

    If intRetVal = 0 Then
       GetFileOwner = objSD.Owner.Name
    Else
       GetFileOwner = "Unknown"
    End If
End Function

我想指出我没有编写 GetFileOwner 函数的胆量。我链接到我在函数中获得该代码的网站。

此外,如果您没有将位置映射到电子表格并且它位于网络上,则 UNC 路径将不起作用,您必须映射驱动器。这可以使用以下 2 行代码来完成:

Set objNetwork = WScript.CreateObject("WScript.Network")
objNetwork.MapNetworkDrive "Z:", "\\Server1\Share1"

希望有人会从中受益。我知道网上没有太多关于如何做到这一点的信息,因为我一直在寻找它!

于 2013-03-22T21:26:07.860 回答
1

您是否尝试过 Workbook.UserStatus 属性?这是 Excel VBA 帮助中的代码片段引用:

users = ActiveWorkbook.UserStatus
With Workbooks.Add.Sheets(1)
    For row = 1 To UBound(users, 1)
    .users = ActiveWorkbook.UserStatus
With Workbooks.Add.Sheets(1)
    For row = 1 To UBound(users, 1)
    .Cells(row, 1) = users(row, 1)
    .Cells(row, 2) = users(row, 2)
    Select Case users(row, 3)
        Case 1
            .Cells(row, 3).Value = "Exclusive"
        Case 2
            .Cells(row, 3).Value = "Shared"
    End Select
Next
End With 
于 2013-03-22T13:52:39.947 回答