【问题标题】:Excel VBA Creating/overwriting a new workbook and using the cancel buttonExcel VBA 创建/覆盖新工作簿并使用取消按钮
【发布时间】:2015-06-17 02:50:44
【问题描述】:

我编写了一个宏,它从一个工作簿中获取一个范围并复制到一个新工作簿中,然后将新创建的工作簿(并为其命名)保存到相同的文件夹路径中。当此工作簿已存在时(覆盖工作簿),会弹出默认窗口对话框询问您是否要覆盖,并选择是否取消按钮。按下取消按钮时,将创建一个新工作簿。如何编辑此代码,以便在按下取消时不会创建新工作簿?我在下面粘贴了宏:

Sub ExportNewBook()
Application.ScreenUpdating = False
Dim ThisWB As Workbook
Set ThisWB = ActiveWorkbook
Set NewBook = Workbooks.Add
On Error Resume Next
  ThisWorkbook.Worksheets("Summary").Range("A1:I100").Copy
  NewBook.Worksheets("Sheet1").Range("A1").PasteSpecial (xlPasteValues)
  NewBook.Worksheets("Sheet1").Range("A1").PasteSpecial (xlPasteFormats)
  NewBook.Worksheets("Sheet1").Range("A:J").Columns.AutoFit
  NewBook.SaveAs Filename:=ThisWB.Path & "\" & NewBook.Worksheets("Sheet1").Range("A4").Value & "_Summary"
  NewBook.ActiveSheet.Range("A1").Select
Application.ScreenUpdating = True
End Sub

编辑:如下所示的工作代码

Sub ExportNewBook()
Application.ScreenUpdating = False
Dim ThisWB As Workbook
Dim fname As String
Set ThisWB = ActiveWorkbook
Set Newbook = Workbooks.Add

  ThisWorkbook.Worksheets("Summary").Range("A1:I100").Copy
  Newbook.Worksheets("Sheet1").Range("A1").PasteSpecial (xlPasteValues)
  Newbook.Worksheets("Sheet1").Range("A1").PasteSpecial (xlPasteFormats)
  Newbook.Worksheets("Sheet1").Range("A:J").Columns.AutoFit

fname = ThisWB.Path & "\" & ThisWB.Worksheets("Summary").Range("A4").Value & "_Summary.xls"
If Dir(fname) <> "" Then
    If MsgBox("Summary output already exists, are you sure you want to overwrite?", vbOKCancel) = vbCancel Then Newbook.Close False: Application.CutCopyMode = False: Exit Sub
End If

Application.DisplayAlerts = False
Newbook.SaveAs Filename:=fname
Application.DisplayAlerts = True
ThisWB.Activate
ActiveWorkbook.Worksheets("Summary").Range("A1").Select
Newbook.Activate
ActiveWorkbook.ActiveSheet.Range("A1").Select
Application.CutCopyMode = False
Application.ScreenUpdating = True

End Sub

谢谢!

【问题讨论】:

    标签: vba excel


    【解决方案1】:

    在错误恢复下一个很少是一个好主意。如果用户选择否或取消,则会触发错误。更好地处理该错误以删除不需要的工作簿(尽管另一个想法是在创建之前测试具有目标名称的工作簿是否存在,如果存在,则使用 msgbox 询问用户是否要覆盖文件,如果所以,只有创建工作簿,禁用警报,然后才进行保存)。

    一个问题似乎是您需要一个文件名才能杀死工作簿。在您的情况下,工作簿还没有文件名。一种解决方案是创建一个安全的文件名,其唯一目的是杀死不需要的工作簿,使用此名称再次执行另存为,然后将其杀死。像这样的:

    Sub Test()
        On Error GoTo err_handler
        Dim wb As Workbook
        Dim fname As String
        Dim tempname As String
        fname = "C:\Programs\testbook.xlsx"
        Set wb = Workbooks.Add
        wb.Sheets(1).Range("A1").Value = Now 'for testing purposes
        wb.SaveAs fname
        Exit Sub
    err_handler:
        tempname = "C:\Programs\name_i_will_never_use.xlsx"
        wb.SaveAs tempname
        wb.Close
        Kill tempname
    End Sub
    

    【讨论】:

      【解决方案2】:

      这是一种可能的方法:

      Sub ExportNewBook()
      Application.ScreenUpdating = False
      Dim ThisWB As Workbook, Newbook As Workbook
      Dim fname As String
      Set ThisWB = ActiveWorkbook
      
      fname = ThisWB.Path & "\" & ThisWB.Sheets("Sheet1").Range("A4").Value & "_Summary"
      If Dir(fname) <> "" Then
          If MsgBox("Are you sure you want to overwrite?", vbOKCancel) = vbCancel Then Exit Sub
      End If
      
      Set Newbook = Workbooks.Add
        ThisWB.Worksheets("Summary").Range("A1:I100").Copy
        Newbook.Worksheets("Sheet1").Range("A1").PasteSpecial (xlPasteValues)
        Newbook.Worksheets("Sheet1").Range("A1").PasteSpecial (xlPasteFormats)
        Newbook.Worksheets("Sheet1").Range("A:J").Columns.AutoFit
      
      'This code should be faster since it bypasses the copy-paste buffer
      'With Newbook.Sheets(1)
      '    ThisWB.Sheets("Summary").Range("A1:I100").Copy .Range("A1")
      '    .Range("A1:I100").Value = .Range("A1:I100").Value
      '    .Columns.AutoFit
      'End With
      
      Application.DisplayAlerts = False
      Newbook.SaveAs Filename:=fname
      Application.DisplayAlerts = True
      Application.ScreenUpdating = True
      End Sub
      

      【讨论】:

      • 我认为这是要走的路——没有理由创建一个工作簿只是为了把它扔掉。您的代码有 2 个潜在问题。 1) fname 中缺少文件扩展名可能会导致 Dir() 函数出现问题。也许 OP 应该添加一个显式扩展。 2) 如果用户确实想要覆盖该文件,您的代码仍会显示警告。也许 NewBook.SaveAs 可以包装在 Application.DisplayAlerts = False 和 Application.DisplayAlerts = True 之间
      • 好主意,约翰!我已经编辑了我的代码来实现#2。我将把 #1 留给 OP,这样他们就可以选择合适的扩展名。
      • 我很欣赏代码。除了无法正确命名文件这一事实之外,它似乎还有效。新书保存为“_Summary”并忽略 A4 中的值(这是因为值粘贴在保存文件名的代码行之后)。我正在努力解决这个问题。另外,点击取消时,有没有办法阻止代码打开一个新的空白工作簿?
      • 那是因为您的代码说要添加一个新工作簿并从中取出 A4(这显然是空白的)。我已经编辑了我的回复以修复它。
      • 卡列夫,很好的回应。我已经完全按照您修复的方式修复了代码。目前,当我按“是”覆盖时,它会打开一本具有通用名称的新书(例如“Book12”)并且实际上并没有覆盖。我现在正在解决这个问题。感谢您的帮助!
      【解决方案3】:

      这是完整的代码

      1. 检查文件是否已经存在
      2. 如果存在关闭新书并询问您是否会打开已存在的文件
      3. 关闭新书
      4. 如果出现错误,请在扩展文件前使用(错误)后缀保存新书
      Sub ExportNewBook()
      Application.ScreenUpdating = False
      Dim ThisWB As Workbook
      Dim NewName As String
      Set ThisWB = ActiveWorkbook
      Set NewBook = Workbooks.Add
      On Error GoTo err_handler
          ThisWB.Worksheets("Summary").Range("A1:I100").Copy
          NewBook.Worksheets("Foglio1").Range("A1").PasteSpecial (xlPasteValues)
          NewBook.Worksheets("Foglio1").Range("A1").PasteSpecial (xlPasteFormats)
          NewBook.Worksheets("Foglio1").Range("A:J").Columns.AutoFit
          NewName = ThisWB.Path & "\" & NewBook.Worksheets("Foglio1").Range("A4").Value & "_Summary.xls"
            If Dir(NewName)  "" Then
                If MsgBox("A file named '" & NewName & " already exists." & vbCr & vbCr & _
                    MeaName & " will now open??", vbYesNo) = vbYes Then
                    Workbooks.Open NewName
                End If
                NewBook.Close False
                Exit Sub
            End If
          NewBook.SaveAs Filename:=NewName
          NewBook.ActiveSheet.Range("A1").Select
          NewBook.Close
          Application.ScreenUpdating = True
      err_handler:
          NewName = ThisWB.Path & "\" & NewBook.Worksheets("Foglio1").Range("A4").Value & "_Summary(error).xls"
          NewBook.SaveAs Filename:=NewName
          NewBook.ActiveSheet.Range("A1").Select
          NewBook.Close
          Application.ScreenUpdating = True
      End Sub
      

      【讨论】:

      • 此代码无效。我收到一个错误,点击否,以及取消,然后在自定义 msgbox 打开后,所有按钮也出现错误,即使文件不存在也会弹出
      • 代码运行,但我缺少退出子。对不起。在 err_handler 之前放:ExitHandler:Exit Sub 并在 err_handler 末尾:(在 end sub 之前)放:Resume ExitHandler
      猜你喜欢
      • 2018-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-28
      • 1970-01-01
      • 2015-07-30
      • 2015-11-30
      • 1970-01-01
      相关资源
      最近更新 更多