如果文件被锁定,如何捕获 wdDialogFileSaveAs 的静默失败?
How to catch silent failure of wdDialogFileSaveAs if file is locked?
我创建了一个包含三个按钮的对话框,其中第三个按钮应将 Word 文档(Office Pro Plus 2013,顺便说一句)保存为 PDF 文件。
Private Sub Button_Dokument_mit_Grafik_als_PDF_speichern_Click()
Dim Grafik As Boolean
Grafik = Options.PrintDrawingObjects
Options.PrintDrawingObjects = True
With Dialogs(wdDialogFileSaveAs)
.Format = wdFormatPDF
' .Format = 17 '17 = PDF
.Show
End With
Options.PrintDrawingObjects = Grafik
End Sub
如果 PDF 存在,我可以选择覆盖它,这在大多数情况下都有效。
如果要覆盖的 PDF 已经打开,例如在 Adobe Reader 中,则文件不会保存,因为它已被锁定。我没有收到任何文件已锁定的通知。
我怎样才能捕捉到这一点并弹出与我在 Word 中手动保存时收到的相同消息?
编辑:
解释为什么我的问题与其他已回答的问题不同:
我不需要检查文件是否已经在 Word 中打开。我将文件保存为 PDF 而不是 Word 文件。
我需要检查文件是否在任何其他应用程序中打开和锁定,例如 Adobe Reader、Edge 或其他应用程序。
此检查已由 Word (and/or OS?) 完成,THIS 是我需要捕获的事件。我完全不明白为什么我需要捕获它,因为检查文件是否存在的结果确实出现了,但是检查文件是否被锁定的结果似乎被忽略了。
VBA 代码的行为就像文件已保存一样,但如果被 Word 以外的任何应用程序锁定,则不会。
我不知道我需要从 Detect whether Excel workbook is already open
中获取哪个代码片段
您可能正在寻找以下内容:
Sub SaveAsPdf()
Dim Grafik As Boolean
Grafik = Options.PrintDrawingObjects
Options.PrintDrawingObjects = True
Dim fDialog As FileDialog
Set fDialog = Application.FileDialog(msoFileDialogSaveAs)
fDialog.Title = "Save a file"
'works only in Word2016 not in word 2013;
'fDialog.InitialFileName = "*.pdf"
'we can use the filterindex property instead
fDialog.FilterIndex = 7
If fDialog.Show = -1 Then
Dim selectedFilePath As String
selectedFilePath = fDialog.SelectedItems(1)
If IsFileInUse(selectedFilePath) Then
MsgBox "The target pdf file you are trying to save is locked or used by other application." & vbCrLf & _
"Please close the pdf file and try again.", vbExclamation
Else
ActiveDocument.SaveAs2 selectedFilePath, wdFormatPDF
End If
End If
Options.PrintDrawingObjects = Grafik
End Sub
Private Function IsFileInUse(ByVal filePath As String) As Boolean
On Error Resume Next
Open filePath For Binary Access Read Lock Read As #1
Close #1
IsFileInUse = IIf(Err.Number > 0, True, False)
On Error GoTo 0
End Function
如果您想使用 wdDialogFileSaveAs 对话框,可以尝试以下代码:
Display 方法将显示对话框而不执行实际功能。您可以验证显示结果以识别单击的按钮并使用 execute 方法执行实际功能。
'Save As Pdf using wdDialogFileSaveAs dialog
'However, it doesn't work as expected.
'The Display method should
Sub SaveAsPdf()
Dim dlg As Dialog
Dim dlgResult As Long
Set dlg = Dialogs(wdDialogFileSaveAs)
With dlg
.Format = wdFormatPDF
dlgResult = .Display
If dlgResult = -1 Then 'user clicks save button;
If .Name <> "" Then
If IsFileInUse(.Name) Then
MsgBox "The target pdf file you are trying to save is locked or used by other application." & vbCrLf & _
"Please close the pdf file and try again.", vbExclamation
Else
.Execute
End If
End If
End If
End With
End Sub
请注意,至少在我的本地环境中,以上代码(wdDialogFileSaveAs 对话框)在 Word 2016 中无法按预期工作。单击保存按钮后,Display 方法将执行实际功能。如果单击“保存”按钮,它也会 returns -2 作为对话框结果。
感谢@CSS 的帮助(见上面的回答和评论),这是当前完整的工作代码(除非我仍然发现任何缺陷):
Private Sub Button_Dokument_mit_Grafik_als_PDF_speichern_Click()
Dim Grafik As Boolean
Grafik = Options.PrintDrawingObjects
Options.PrintDrawingObjects = True
Dim dlg As Dialog
Dim dlgResult As Long
Set dlg = Dialogs(wdDialogFileSaveAs)
With dlg
.Format = wdFormatPDF
dlgResult = .Display
If dlgResult = -1 Then 'user clicked save button
If .Name <> "" Then
If IsFileInUse(.Name) Then
MsgBox "The target PDF file you are trying to save is locked or used by other application." & vbCrLf & _
"Please close the PDF file and try again.", vbExclamation
Else
.Execute
End If
End If
End If
End With
Options.PrintDrawingObjects = Grafik
End Sub
Private Function IsFileInUse(ByVal filePath As String) As Boolean
On Error Resume Next
Open filePath For Binary Access Read Lock Read As #1
Close #1
IsFileInUse = IIf(Err.Number > 0, True, False)
On Error GoTo 0
End Function
再次感谢@CSS。 :)
不过,您可能想要编辑您的答案,以使其确实反映最终的工作代码。我已经给予了适当的感谢。
我创建了一个包含三个按钮的对话框,其中第三个按钮应将 Word 文档(Office Pro Plus 2013,顺便说一句)保存为 PDF 文件。
Private Sub Button_Dokument_mit_Grafik_als_PDF_speichern_Click()
Dim Grafik As Boolean
Grafik = Options.PrintDrawingObjects
Options.PrintDrawingObjects = True
With Dialogs(wdDialogFileSaveAs)
.Format = wdFormatPDF
' .Format = 17 '17 = PDF
.Show
End With
Options.PrintDrawingObjects = Grafik
End Sub
如果 PDF 存在,我可以选择覆盖它,这在大多数情况下都有效。
如果要覆盖的 PDF 已经打开,例如在 Adobe Reader 中,则文件不会保存,因为它已被锁定。我没有收到任何文件已锁定的通知。
我怎样才能捕捉到这一点并弹出与我在 Word 中手动保存时收到的相同消息?
编辑:
解释为什么我的问题与其他已回答的问题不同:
我不需要检查文件是否已经在 Word 中打开。我将文件保存为 PDF 而不是 Word 文件。
我需要检查文件是否在任何其他应用程序中打开和锁定,例如 Adobe Reader、Edge 或其他应用程序。
此检查已由 Word (and/or OS?) 完成,THIS 是我需要捕获的事件。我完全不明白为什么我需要捕获它,因为检查文件是否存在的结果确实出现了,但是检查文件是否被锁定的结果似乎被忽略了。
VBA 代码的行为就像文件已保存一样,但如果被 Word 以外的任何应用程序锁定,则不会。
我不知道我需要从 Detect whether Excel workbook is already open
中获取哪个代码片段您可能正在寻找以下内容:
Sub SaveAsPdf()
Dim Grafik As Boolean
Grafik = Options.PrintDrawingObjects
Options.PrintDrawingObjects = True
Dim fDialog As FileDialog
Set fDialog = Application.FileDialog(msoFileDialogSaveAs)
fDialog.Title = "Save a file"
'works only in Word2016 not in word 2013;
'fDialog.InitialFileName = "*.pdf"
'we can use the filterindex property instead
fDialog.FilterIndex = 7
If fDialog.Show = -1 Then
Dim selectedFilePath As String
selectedFilePath = fDialog.SelectedItems(1)
If IsFileInUse(selectedFilePath) Then
MsgBox "The target pdf file you are trying to save is locked or used by other application." & vbCrLf & _
"Please close the pdf file and try again.", vbExclamation
Else
ActiveDocument.SaveAs2 selectedFilePath, wdFormatPDF
End If
End If
Options.PrintDrawingObjects = Grafik
End Sub
Private Function IsFileInUse(ByVal filePath As String) As Boolean
On Error Resume Next
Open filePath For Binary Access Read Lock Read As #1
Close #1
IsFileInUse = IIf(Err.Number > 0, True, False)
On Error GoTo 0
End Function
如果您想使用 wdDialogFileSaveAs 对话框,可以尝试以下代码:
Display 方法将显示对话框而不执行实际功能。您可以验证显示结果以识别单击的按钮并使用 execute 方法执行实际功能。
'Save As Pdf using wdDialogFileSaveAs dialog
'However, it doesn't work as expected.
'The Display method should
Sub SaveAsPdf()
Dim dlg As Dialog
Dim dlgResult As Long
Set dlg = Dialogs(wdDialogFileSaveAs)
With dlg
.Format = wdFormatPDF
dlgResult = .Display
If dlgResult = -1 Then 'user clicks save button;
If .Name <> "" Then
If IsFileInUse(.Name) Then
MsgBox "The target pdf file you are trying to save is locked or used by other application." & vbCrLf & _
"Please close the pdf file and try again.", vbExclamation
Else
.Execute
End If
End If
End If
End With
End Sub
请注意,至少在我的本地环境中,以上代码(wdDialogFileSaveAs 对话框)在 Word 2016 中无法按预期工作。单击保存按钮后,Display 方法将执行实际功能。如果单击“保存”按钮,它也会 returns -2 作为对话框结果。
感谢@CSS 的帮助(见上面的回答和评论),这是当前完整的工作代码(除非我仍然发现任何缺陷):
Private Sub Button_Dokument_mit_Grafik_als_PDF_speichern_Click()
Dim Grafik As Boolean
Grafik = Options.PrintDrawingObjects
Options.PrintDrawingObjects = True
Dim dlg As Dialog
Dim dlgResult As Long
Set dlg = Dialogs(wdDialogFileSaveAs)
With dlg
.Format = wdFormatPDF
dlgResult = .Display
If dlgResult = -1 Then 'user clicked save button
If .Name <> "" Then
If IsFileInUse(.Name) Then
MsgBox "The target PDF file you are trying to save is locked or used by other application." & vbCrLf & _
"Please close the PDF file and try again.", vbExclamation
Else
.Execute
End If
End If
End If
End With
Options.PrintDrawingObjects = Grafik
End Sub
Private Function IsFileInUse(ByVal filePath As String) As Boolean
On Error Resume Next
Open filePath For Binary Access Read Lock Read As #1
Close #1
IsFileInUse = IIf(Err.Number > 0, True, False)
On Error GoTo 0
End Function
再次感谢@CSS。 :)
不过,您可能想要编辑您的答案,以使其确实反映最终的工作代码。我已经给予了适当的感谢。