【问题标题】:Open an Excel file in exclusive mode using VBScript使用 VBScript 以独占模式打开 Excel 文件
【发布时间】:2016-07-01 09:10:35
【问题描述】:

我有一个简单的问题,但我已经搜索过,但找不到任何有用的主题..

我正在开发一个 VBScript,它可以打开一个 Excel 文件并修改其中的一些内容。所以我正在使用以下代码:

    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")

【问题讨论】:

  • 将 Excel 文件临时移动到一个特殊文件夹中,打开它,修改其中的一些内容,然后保存,关闭并移回 :)
  • 我想这样做是一种解决方法,但我想知道是否有直接的方法可以专门打开文件
  • 如果文件被脚本打开,它只会对任何其他打开它的尝试是只读的。你还想限制这个吗?
  • @brettdj 这似乎不正确..当我使用问题中的代码打开 excel 文件(通过脚本)时,我可以双击该文件并正常打开(我可以编辑任何东西并保存)
  • 添加了excel-vba标签以增加受众,并且可以将vba转换为vbs。

标签: excel vbscript com dde vba


【解决方案1】:

我在 Win 7 Excel 2010 上有注册表项 HKEY_CLASSES_ROOT\Excel.Sheet.8\shell\Open\command,默认值为 "C:\Program Files\Microsoft Office\Office14\EXCEL.EXE" /dde。命令行/dde 开关启用 DDE(动态数据交换机制 - 一种古老的 Win 3.0 进程间通信方法),它强制 Excel 在单个实例中启动。我试图删除该开关并打开工作簿,但无济于事。顺便说一句,如果您没有编辑注册表的权限,或者您打算将脚本分发给没有权限的人,那不是一种方法。也尝试过this answer,但它不适用于 Win 7 Office 2010。

我已经在启用 DDE 的情况下测试了 test.xlsm 文件。当用户打开一个文件时,实际上它只是在现有实例中重新打开,使其可见。如果脚本已经进行了任何更改,则 Excel 会发出警报:

无论如何都会为用户提供写访问权限。之后,当脚本保存文件时,会出现另一个警告:

前段时间,我创建了一个适用于 Excel 应用程序的脚本,但在 Win 7 Excel 2010 中遇到了与您描述的相同的问题。我注意到,如果在脚本中使用CreateObject() 创建了多个 Excel 应用程序实例,则用户打开的 Excel 文件总是使用第一个创建的实例。我通过创建两个不可见的 Excel 应用程序实例解决了这个问题,比如说虚拟和目标。脚本的算法大致如下:

  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

尝试打开文件,您将获得所需的输出:

以及脚本结束后的通知:

【讨论】:

  • “虚拟实例”确实是个好主意。这是完美的,这正是我想要的。非常感谢:)
【解决方案2】:

奇怪的是你没有收到如下消息:

一种可能的方法是

  • 要更改代码开头和结尾的文件属性,下面的版本使文件只读隐藏
  • 进行更改
  • 用不同的名称保存文件
  • 改回属性
  • 将更改后的文件重命名为原始名称

代码

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

【讨论】:

  • 由于该文件是只读的,我将无法通过脚本更改其内容(我刚刚测试了它btw)我还尝试设置文件属性= 32 之前 保存文件.. 但不会保存更改!
  • @GeniuSBraiN 已更新,因为您需要更改文件。仍然对默认的只读保护不适用感到惊讶。
  • 这不是我想要的(我不想另存为).. 无论如何我做了一些调试,我想出了一些东西.. 请检查我的问题中的更新
  • 好吧,saveas 只是一个中间步骤——你最终得到了一个文件。将把这个留给其他人来帮助,我已经走得够远了。
  • 我知道这是一个中间步骤。 @omegastripes 已经提出了类似的建议。感谢您的帮助。感谢您的努力 :)
猜你喜欢
  • 1970-01-01
  • 2010-10-15
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多