如何在自动覆盖的情况下使用workbook.saveas

77

在这段代码的部分,Excel总是会提示:"文件已经存在,是否要覆盖?"

Application.DisplayAlerts = False
Set xls = CreateObject("Excel.Application")
Set wb = xls.Workbooks.Add
fullFilePath = importFolderPath & "\" & "A.xlsx"

wb.SaveAs fullFilePath, AccessMode:=xlExclusive, ConflictResolution:=True   

wb.Close(True)

如果我将DisplayAlerts = False,为什么db.SaveAs总是提示我覆盖现有文件?

4个回答

102

要隐藏提示,请设置xls.DisplayAlerts = False

ConflictResolution不是truefalse属性,应该是xlLocalSessionChanges

请注意,这与显示覆盖提示无关!

Set xls = CreateObject("Excel.Application")    
xls.DisplayAlerts = False
Set wb = xls.Workbooks.Add
fullFilePath = importFolderPath & "\" & "A.xlsx"

wb.SaveAs fullFilePath, AccessMode:=xlExclusive,ConflictResolution:=Excel.XlSaveConflictResolution.xlLocalSessionChanges    
wb.Close (True)

4
你需要告诉你正在使用的工作簿不要显示警报。我已经更新了上面的代码......只需查看"Application.DisplayAlerts",应该是 "wb.Application.DisplayAlerts". - Sorceri
4
按照原文所述,你是正确的 - DisplayAlerts=False 这一行应当在设置了 Workbook 对象之后。然而,你也可以通过使用 Application.DisplayAlerts 来全局设置它。并且,在阻止弹出警告结束后,你可能应该将其改回 True。 - Kevin Pope
4
首先,ConflictResolution与SaveAs覆盖提示无关。请参阅此处以了解详细信息 - 它涉及共享Excel文件中多个编辑器之间的冲突。其次,Application.DisplayAlerts是Application对象的成员,而不是Workbook对象。因此,在创建新的Excel应用程序实例后,请使用此命令:xls.DisplayAlerts = False。(这就是为什么OP的代码无法正常工作的真正原因。) - vacip
1
在你的代码中,wb.application.displayalertsxls.displayalerts 会得到相同的结果。有关 ApplicationWorkbook.Application 的详细信息,请参见此处。因此,尽管 wb.application 在技术上是正确的,但在我看来这是具有误导性的(正如一些评论者建议使用 Application.Displayalerts 一样...)。但无论你使用哪种方式,请将代码移动到正确的位置,即在创建对象本身之后。现在你的代码会产生一个错误。 - vacip
4
在这个具体的问题中,提问者创建了一个新的Excel实例(虽然这没有什么用,而且是一个坏主意,但无论如何他这样做了)。因此,您需要像这样为新的Excel实例设置DisplayAlerts属性:在Set xls = CreateObject("Excel.Application")这一行之后立即写入xls.DisplayAlerts = False,而不是在之前。感谢您的耐心和开放!这很重要,因为您的答案在许多搜索的第一页上。 :) - vacip
显示剩余6条评论

27

在执行SaveAs之前,建议先删除该文件(如果存在)。

If Dir("f:ull\path\with\filename.xls") <> "" Then
    Kill "f:ull\path\with\filename.xls"
End If

这比设置DisplayAlerts的开启和关闭更容易,而且如果DisplayAlerts因为代码崩溃而保持关闭状态,在同一会话中使用Excel可能会导致问题。


请注意,如果文件正在另一个进程中打开,它将抛出异常。 - Mustafa
1
在代码中使用某种错误处理方式,以确保在出现意外终止的情况下 DisplayAlerts 能够被重新打开,例如使用 On Error Goto Cleanup 或者其他可用于错误处理的方式。 - Bence Szalai
C#版本:if (File.Exists(@“C:\test.txt”)){ File.Delete(@“C:\test.txt”); } - Dominic Isaia

12

为了分歧的妥协,

我更倾向于:

   xls.DisplayAlerts = False    
   wb.SaveAs fullFilePath, AccessMode:=xlExclusive, ConflictResolution:=xlLocalSessionChanges
   xls.DisplayAlerts = True

1
ConflictResolution 不是一个真/假属性。https://learn.microsoft.com/en-us/office/vba/api/excel.xlsaveconflictresolution - Marcucciboy2
3
用CreateObject创建的xls文件是Excel的一个不同实例......因此,Application.DisplayAlerts在原始实例中设置,而wb则保存在第二个实例中。这个答案展示了如何在第二个实例中设置DisplayAlerts,这应该可以工作。 - Mike

-1

终于搞定了,之前的东西都太混乱了。

    Sub SaveAndClose()
    Dim wb1 As String
    
    Application.Calculation = xlCalculationAutomatic
    
    'this only works if the following equation is in C43 in sheet "data"
    '=LEFT(MID(CELL("filename",C41),SEARCH("[",CELL("filename",C41))+1, SEARCH("]",CELL("filename",C41))-SEARCH("[",CELL("filename",C41))-1),75)
    'the vba equation has double quotes everywhere that is how you use a formula in vba.
'vba code recreates this incase it gets deleted by accident. 
    
    ThisWorkbook.Sheets("Data").Range("C43").ClearContents
    ThisWorkbook.Sheets("Data").Range("C43").Formula2R1C1 = _
            "=LEFT(MID(CELL(""filename"",R[-2]C),SEARCH(""["",CELL(""filename"",R[-2]C))+1, SEARCH(""]"",CELL(""filename"",R[-2]C))-SEARCH(""["",CELL(""filename"",R[-2]C))-1),75)"
        'https://techcommunity.microsoft.com/t5/excel/cell-reference-containing-file-name-changes-when-opening-second/m-p/2417030
    
    wb1 = ThisWorkbook.Sheets("Data").Range("C43").Text
    If ThisWorkbook.Name = wb1 Then
    'MsgBox (wb1)
    Workbooks(wb1).Close SaveChanges:=True
    End If
    
    End Sub

这将允许电子表格确定自己的名称,然后才能对该名称运行某些操作。这样,当您有多个运行重复表但具有不同名称的工作表时,您不会意外关闭错误的工作表。在我的书中,这是一个巨大的胜利。

这也将绕过覆盖消息,您可以在另一个工作簿中自动在后台运行代码,而您在不同的工作簿中工作时不会受到影响。


这不是对问题的回答,看起来毫无关联。 - undefined
@user10186832 这非常相关,因为您可以同时打开多个具有不同名称的电子表格,并且您希望关闭并保存当前的工作簿。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接