web-dev-qa-db-ja.com

VBScriptを使用して排他モードでExcelファイルを開く

簡単な質問がありますが、これを検索したところ、役立つトピックが見つかりませんでした。

私はExcelファイルを開いてその中のいくつかのものを変更するVBScriptに取り組んでいるので、次のコードを使用しています。

_    Set objXLApp = CreateObject("Excel.Application")

    objXLApp.Visible = False
    objXLApp.DisplayAlerts = False

    Set objXLWb = objXLApp.Workbooks.Open(FilePath)
_

さて、私がやりたいのは、ファイルをロックし、スクリプトで開いている間(閉じるまで)ユーザーがファイルを開かないようにする方法を使用してExcelファイルを開くことです。

更新:

問題は何らかの形でExcelインスタンスに関連していると思いますが、次のことを試みました(ファイルがスクリプトで開かれている間)。

  • 私が手動でファイルを開くと(スクリプトで開いている間)、両方とも単一のインスタンスになります。
  • 他のExcelファイルを開くと、両方ともまた単一のインスタンスになります!!!そして、元のファイル(スクリプトによって開かれた)が表示されます!

CreateObject("Excel.Application")ではなくGetObject(, "Excel.Application")を使用しているため、これは奇妙です。

6

Win 7 Excel 2010には、デフォルト値_HKEY_CLASSES_ROOT\Excel.Sheet.8\Shell\Open\command_のレジストリキー_"C:\Program Files\Microsoft Office\Office14\Excel.EXE" /dde_があります。コマンドライン_/dde_スイッチは、Excelを単一のインスタンスで起動するように強制するDDE(動的データ交換メカニズム-古いWin 3.0プロセス間通信方式)を有効にします。そのスイッチを削除してブックを開こうとしましたが、役に立ちませんでした。ところで、レジストリを編集する権限がない場合、またはそうでない人にスクリプトを配布する場合は、それは方法ではありません。また、 この回答 を試しましたが、Win 7 Office2010では機能しません。

DDEを有効にして_test.xlsm_ファイルをテストしました。ユーザーがファイルを開くと、実際には既存のインスタンスで再度開かれるだけで、ファイルが表示されます。スクリプトによってすでに変更が加えられている場合、Excelは次のように警告します。

changes to be discarded

とにかく、書き込みアクセスはユーザーに与えられます。その後、スクリプトがファイルを保存すると、別のアラートが表示されます。

file already exists

少し前に、Excelアプリケーションで動作するスクリプトを作成しましたが、Win 7 Excel2010で説明しているのと同じ問題が発生しました。スクリプト内でCreateObject()を使用して作成されたExcelアプリケーションインスタンスが複数ある場合、ユーザーが開いたExcelファイルは常に最初に作成されたインスタンスを正確に使用することに気付きました。 Excelアプリケーションの2つの非表示のインスタンス、たとえばダミーとターゲットを作成することで問題を解決しました。スクリプトのアルゴリズムの概要は次のとおりです。

  1. 最初にダミーインスタンスを作成します。ワークブックを追加する必要はありません。その後、ダミーインスタンスは、その中のユーザーが開くExcelファイルに公開されます。
  2. ターゲットインスタンスを作成します。
  3. ダミーインスタンスを終了します。
  4. ターゲットワークブックを開き、変更して保存します。
  5. ターゲットインスタンスを終了します。

必要なものを実装するための可能な方法を示す以下のコードを検討してください。

_' target file path
sPath = "C:\Users\Dell\Desktop\test.xlsm"
' create dummy instance
Set oExcelAppDummy = CreateObject("Excel.Application")
' create target instance
Set oExcelApp = CreateObject("Excel.Application")
' quit dummy instance
oExcelAppDummy.Quit
' open target workbook
With oExcelApp
    .Visible = False
    .DisplayAlerts = False
    Set oWB = .Workbooks.Open(sPath)
End With
' make some changes and save
Set oWS = oWB.Sheets(1)
oWS.Cells(1, 1).Value = Now()
oWB.Save
' give additional time for test
MsgBox "Try to open test.xlsm, OK to end the script"
' close target workbook
oWB.Close
' quit target instance
oExcelApp.Quit
_

ファイルを開こうとすると、目的の出力が得られます。

open read-only and notify

そして、スクリプト終了後の通知:

open read-write

2
omegastripes

以下のようなメッセージが表示されないのは不思議です。

enter image description here

考えられる方法の1つは

  • コードの最初と最後でファイル属性を変更するには、以下のバージョンでファイルを読み取り専用および非表示にします
  • 変更を加える
  • 別の名前でファイルを保存します
  • 属性を元に戻す
  • 変更したファイルの名前を元の名前に変更します

コード

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objXLApp = CreateObject("Excel.Application")

filePath = "C:\Temp\MyFile.xlsm"
filePath2 = "C:\Temp\MyFile1.xlsm"

set objFile = objFSO.GetFile(filePath)
objFile.Attributes = 3

objXLApp.Visible = False
objXLApp.DisplayAlerts = False

Set objxlWB = objXLApp.Workbooks.Open(filePath)
'do stuff
objxlWB.saveas filePath2
objxlWB.Close
objXLApp.Quit
set objXLApp = Nothing

objFile.Attributes = 32
objFile.Delete
objFSO.MoveFile filePath2, filePath
2
brettdj