【问题标题】:VBA - Automated PowerPoint won't open .pptx file that is being used by another UserVBA - 自动 PowerPoint 不会打开其他用户正在使用的 .pptx 文件
【发布时间】:2014-05-15 04:28:15
【问题描述】:

我正在创建一个脚本,将幻灯片从其他各种 .pptx 文件复制到主 PowerPoint 中,但如果其中一个文件在宏执行的同时被另一个用户打开,我会收到 80004005 错误。我的脚本如下:

Public Sub Update()

Dim PPTApp As Object
Dim PPT As Object
Dim MasterPPT As Presentation
Dim Total As Integer
Dim FSO As New Scripting.FileSystemObject
Dim Folder As Scripting.Folder
Dim SubFolder As Scripting.Folder
Dim File As Scripting.File

Set MasterPPT = Presentations("Combined Staff Agenda Template.pptm")
Total = MasterPPT.Slides.Count

Set PPTApp = CreateObject("PowerPoint.Application")

' Sets the first ComboBox destination folder
Set Folder = FSO.GetFolder("O:\org\acle\Common\PE_SHARE\Technical Staff Meeting Agendas\Individual Slides\" & Order_UserForm.comboFirst.Value)

For Each SubFolder In Folder.SubFolders
    For Each File In SubFolder.Files

    ' Copies and pastes all slides for each file
    Set PPT = PPTApp.Presentations.Open(File.Path, ReadOnly:=msoTrue, WithWindow:=msoFalse)
    PPT.Slides.Range.Copy
    MasterPPT.Slides.Paste (Total)

    PPT.Close

    Total = MasterPPT.Slides.Count

    Next File
Next SubFolder

For Each 循环对另外两个文件夹重复两次,然后子例程结束。文件夹系统组织如下:父目录(“技术人员会议议程”)>“个人幻灯片”> 三 (3) 个部门文件夹 > 个人用户文件夹,每个文件夹中都有一个 .pptx 文件。如果 File.Path 已经打开,有什么解决方法可以访问它?

【问题讨论】:

  • 大概您在Presentations.Open 方法上收到错误消息,对吧?错误编号/说明是什么?

标签: vba object powerpoint


【解决方案1】:

完全未经测试,但让我们尝试这样的事情(假设您在 Presentations.Open 上遇到错误。我在此方法调用周围添加了一个错误处理块,并根据文档 (here) 它看起来像.Open 方法的 Untitled 参数相当于创建文件的副本。

如果这不起作用,请告诉我。我可以修改为显式创建并打开文件的副本并打开它。

更新 由于Untitled 属性不起作用,让我们尝试显式创建文件的副本。我没有包含任何“清理”代码来删除复制的版本。

Public Sub Update()

Dim PPTApp As Object
Dim PPT As Object
Dim MasterPPT As Presentation
Dim Total As Integer
Dim FSO As New Scripting.FileSystemObject
Dim Folder As Scripting.Folder
Dim SubFolder As Scripting.Folder
Dim File As Scripting.File

Set MasterPPT = Presentations("Combined Staff Agenda Template.pptm")
Total = MasterPPT.Slides.Count

Set PPTApp = CreateObject("PowerPoint.Application")

' Sets the first ComboBox destination folder
Set Folder = FSO.GetFolder("O:\org\acle\Common\PE_SHARE\Technical Staff Meeting Agendas\Individual Slides\" & Order_UserForm.comboFirst.Value)

For Each SubFolder In Folder.SubFolders
    For Each File In SubFolder.Files

    ' Copies and pastes all slides for each file
    On Error GoTo FileInUseError
    Set PPT = PPTApp.Presentations.Open(File.Path, ReadOnly:=msoTrue, WithWindow:=msoFalse)
    On Error GoTo 0
    PPT.Slides.Range.Copy
    MasterPPT.Slides.Paste (Total)

    PPT.Close

    Total = MasterPPT.Slides.Count

    Next File
Next SubFolder

'## It's important to put this before your error-handling block:
Exit Sub

'## Error handling:
Err.Clear

'## First attempt, did not work as expected
'Set PPT = PPTApp.Presentations.Open(File.Path, ReadOnly:=msoTrue, Untitled:=msoTrue, WithWindow:=msoFalse)

 '## Second attempt. You will need to add some logic to remove these files or do it manually.
Dim copyPath as String
copyPath = Replace(File.Path, File.Name, "Copy of " & File.Name)
FSO.CopyFile File.Path, copyPath, True
Set PPT = PPTApp.Presentations.Open(copyPath)


Resume Next

End Sub

更新 2

您可以尝试的其他方法(不太可能有效,但无论如何您都应该尝试):

我注意到这段代码是在 PowerPoint 中执行的,所以没有意义的一件事是:Set PPTApp = CreateObject("PowerPoint.Application")。您已经在运行一个 PPT 实例,并且只运行一个 PPT 实例(不像 Excel 可以有多个实例)。所以完全摆脱那条线。

'Set PPTApp = CreateObject("PowerPoint.Application")

然后你也可以去掉变量PPTApp。我注意到您对 PowerPoint 对象变量使用了早期绑定和后期绑定的组合。这没有任何意义,虽然我不认为这会导致任何错误,但你永远不会知道。

'Dim PPTApp as Object 'PowerPoint.Application  '## This is unnecessary!!
Dim PPT as Presentation
Dim MasterPPT as Presentation

如果一切都失败了,请打开新文件 WithWindow=msoTrue 并使用 F8 逐行执行代码...

更新 3

虽然我无法测试 另一个 用户锁定/正在使用的文件,但我能够测试如果我有一个 正在使用的文件会发生什么我自己。我使用以下代码并确定Files 迭代最终会遇到文件的lock/tmp 版本,以“~”波浪字符开头。这些通常是隐藏文件,但无论如何 FSO 都会在迭代中拾取它们。

除此之外,如果文件不是有效的 PPT 文件类型(PPT、PPTX、PPTM、XML 等),我也会遇到类似的错误。如果有错误,我使用以下代码在即时窗口中打印错误日志(并通过 MsgBox 提示通知您)。

Sub Test()
Dim MasterPPT As Presentation
Dim PPT As Presentation
Dim Total As Integer
Dim FSO As Object
Dim Folder As Object
Dim SubFolder As Object
Dim File As Object
Dim errMsg$
Dim copyPath$

Set MasterPPT = ActivePresentation '## Modify as needed.

Total = MasterPPT.Slides.Count

Set FSO = CreateObject("Scripting.FileSystemObject")

' Sets the first ComboBox destination folder // MODIFY AS NEEDED
Set Folder = FSO.GetFolder("C:\Users\david_zemens\Desktop\CHARTING STANDARDS")

For Each SubFolder In Folder.SubFolders
    For Each File In SubFolder.Files
        ' Copies and pastes all slides for each file
        On Error GoTo FileInUseError:
        ' Make sure it's a PPT file:
        If File.Type Like "Microsoft PowerPoint*" Then
10:
            Set PPT = Presentations.Open(File.Path, ReadOnly:=msoTrue, WithWindow:=msoFalse)
20:
           PPT.Slides.Range.Copy
30:
            MasterPPT.Slides.Paste (Total)

            PPT.Close

        End If
        On Error GoTo 0

    Total = MasterPPT.Slides.Count
NextFile:
    Next File
Next SubFolder

'## It's important to put this before your error-handling block:
Set FSO = Nothing
Set Folder = Nothing
Set SubFolder = Nothing
Set File = Nothing

Exit Sub

FileInUseError:
'## Error handling:
'## Display information about the error
errMsg = "Error No.: " & Err.Number & vbCrLf
errMsg = errMsg & "Description: " & Err.Description & vbCrLf
errMsg = errMsg & "At line #: " & Erl & vbCrLf
errMsg = errMsg & "File.Name: " & File.Name
Debug.Print errMsg & vbCrLf
MsgBox errMsg, vbInformation, "Error!"
Err.Clear
Resume NextFile

End Sub

【讨论】:

  • 大卫,我之前确实尝试过Untitled 方法,但它似乎不起作用。我会试试你的脚本,看看它是否改变了什么!你知道FileInUseError 引用了什么吗?此外,我在Presentations.Open 收到的错误是:“运行时错误 '-2147467259 (80004005)';PowerPoint 无法打开文件。”奇怪的是,脚本仍然从源演示文稿中复制和粘贴幻灯片,但随后因出现此错误而停止。
  • 嗯,这听起来很奇怪。好吧,如果这仍然不起作用,让我们看看上面的修订是否有帮助。
  • David,我收到 .CopyFile 的预期函数/变量错误,即使它在我输入该函数时识别该函数。有什么建议?再次感谢您的帮助!
  • 嗯,让我们尝试另一个版本。见上文。
  • 大卫,非常感谢!您的脚本按预期工作,得知我们发现了问题,我松了一口气!在我的情况下,我对三个不同的目录有三个相同的复制循环,所以我可能不得不找到一个解决方法 NextFile: 因为会有三个实例。另外,请问10:20:30:是干什么用的?
猜你喜欢
  • 1970-01-01
  • 2012-09-15
  • 2020-11-04
  • 2014-12-27
  • 2017-07-26
  • 1970-01-01
  • 2015-07-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多