web-dev-qa-db-ja.com

Excel 2007スプレッドシートが開いており、WHOがVBScriptを使用して開いているかどうかを確認する方法

Excel 2007スプレッドシートが開いていて、WHOが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
9
Steven

優秀な同僚から、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関数の根幹を記述しなかったことを指摘しておきます。関数でそのコードを取得したWebサイトにリンクしました。

また、場所がスプレッドシートにマップされておらず、それがネットワーク上にある場合、UNCパスは機能せず、ドライブをマップする必要があります。これは、次の2行のコードを使用して実行できます。

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

うまくいけば、誰かがこれから利益を得るでしょう。私はそれを永遠に探し求めてきたので、これをウェブ上で行う方法についての情報があまりないことを知っています!

13
Steven

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 
1
Eric