如何处理“否”或“取消”Workbook.SaveAs覆盖确认?

我希望在VBA脚本开始修改内容之前提示用户保存工作簿。 当SaveAs对话框出现时,如果用户单击取消,则引发自定义错误并停止脚本。 如果他们点击保存并且文件名已经存在,我希望他们被问到是否覆盖。

这是我的代码:

Function SaveCurrentWorkbook(wkbSource As Workbook, strNewFileName As String) As Variant If Not bolDebug Then On Error GoTo errHandler Dim varSaveName As Variant SaveAsDialog: varSaveName = Application.GetSaveAsFilename(InitialFileName:=strNewFileName, FileFilter:="Excel Files (*.xls), *.xls") If varSaveName <> False Then wkbSource.SaveAs Filename:=varSaveName, ConflictResolution:=True, Addtomru:=True Set SaveCurrentWorkbook = wkbSource Else SaveCurrentWorkbook = False Err.Raise 11111, , "Save Canceled" End If exitProc: Exit Function errHandler: Select Case Err.Number Case 1004 'Clicked "No" or "Cancel" - can't differentiate Resume SaveAsDialog Case esle MsgBox "File not saved. Stopping script.", vbOKOnly, Err.Description Resume exitProc End select End Function 

如果他们点击“是”,则会覆盖它。 如果他们点击“否”,我想SaveAs对话框出现,所以他们可以select一个新的文件名,但相反,我得到一个错误。 如果他们点击“取消”,我想要发生一个错误,脚本停止。 问题是我无法区分“否”和“取消”之间触发的错误。

任何build议如何处理这个? (请原谅任何error handling – 这是一段时间)。

PS此function由另一个程序调用,所以如果用户在SaveAs对话框或ResolveConflict对话框上单击“取消”,我也希望调用程序也停止。 我想我可以通过检查SaveCurrentWorkbook返回(Workbook对象或False)来做到这一点。

你可以简单地创build自己的“覆盖?” – 这样的问题:

 Function SaveCurrentWorkbook(wkbSource As Workbook, strNewFileName As String) As Variant If Not bolDebug Then On Error GoTo errHandler Dim varSaveName As Variant SaveAsDialog: varSaveName = Application.GetSaveAsFilename(InitialFileName:=strNewFileName, FileFilter:="Excel Files (*.xls), *.xls") If varSaveName <> False Then If Len(Dir(varSaveName)) Then 'checks if the file already exists Select Case MsgBox("A file named '" & varSaveName & "' already exists at this location. Do you want to replace it?", vbYesNoCancel + vbInformation) Case vbYes 'want to overwrite Application.DisplayAlerts = False wkbSource.SaveAs varSaveName, ConflictResolution:=2, Addtomru:=True Application.DisplayAlerts = True Set SaveCurrentWorkbook = wkbSource Case vbNo GoTo SaveAsDialog Case vbCancel SaveCurrentWorkbook = False Err.Raise 11111, , "Save Canceled" End Select Else wkbSource.SaveAs varSaveName, ConflictResolution:=True, Addtomru:=True Set SaveCurrentWorkbook = wkbSource End If Else SaveCurrentWorkbook = False Err.Raise 11111, , "Save Canceled" End If exitProc: Exit Function errHandler: Select Case Err.Number Case 1004 'Clicked "No" or "Cancel" - can't differentiate Resume SaveAsDialog Case Else MsgBox "File not saved. Stopping script.", vbOKOnly, Err.Description Resume exitProc End Select End Function 

正如你已经注意到,“否”和“取消”(对于应用程序,因为它不会停止保存本身)没有区别。 Excel只是谎言自己说:“我不能保存在这里”和两种情况popup相同的错误…所以唯一真正的解决办法是创build自己的msgbox 🙁

我会使SaveCurrentWorkbook返回True或False,并使用Msgboxes处理保存为strNewFileName。

然后在调用SaveCurrentWorkbook的脚本中,您可以执行简单的布尔评估。

    如果SaveCurrentWorkbook(wkbSource,“C:\ ... \ SomeFile.xls”)那么
        '做一点事
    其他
        “做别的事
    万一
 Function SaveCurrentWorkbook(wkbSource As Workbook, strNewFileName As String) As Boolean Dim iResult As VbMsgBoxResult Dim varSaveName As Variant If Dir(strNewFileName) <> "" Then iResult = MsgBox("Press [Yes] to overwite " & strNewFileName & " or [No] to choose a new filename.", vbInformation + vbYesNo, "Save File") Else iResult = MsgBox("Press [Yes] to save as " & strNewFileName & " or [No] to choose a new filename.", vbInformation + vbYesNo, "Save File") End If If iResult = vbYes Then SaveCurrentWorkbook = True Else varSaveName = Application.GetSaveAsFilename(FileFilter:="Excel Files (*.xls), *.xls") If CStr(varSaveName) <> "False" Then wkbSource.SaveAs Filename:=varSaveName, ConflictResolution:=True, Addtomru:=True SaveCurrentWorkbook = True End If End If End Function 

使用SaveAs时不需要设置参考,因为您的原稿已closures(不保存),而且您的参考会自动更新为新文件。 如果您使用的是SaveCopyA,那么您的原始文件保持打开状态,并创build当前文件的副本(包括任何未保存的数据)。

注意在下面的testing中,当我们使用SaveAs时,refernce被更新为SaveAs名称。 当我们使用SaveCopAs时,名称不会更改,因为原始文件仍处于打开状态。

在这里输入图像说明