【问题标题】:Deleting Sheet with VBA crashes Excel使用 VBA 删除工作表会使 Excel 崩溃
【发布时间】:2013-04-09 07:56:17
【问题描述】:

当用户单击 Excel 中的图像(按钮)时,我试图删除工作表。但是,这会使 excel 崩溃并重新启动,忘记任何未保存的进度。

这是我的潜艇:

Sub DeletePlan()

Application.Calculation = xlCalculationManual
Application.DisplayAlerts = False
Dim SheetNamesToCopy As String

SheetNamesToCopy = ActiveSheet.Name



' Check what addon sheets exists for the media, then add existing ones to string
If CheckSheet("periodeplan", True) = True Then
    ThisWorkbook.SheetS(SheetNamesToCopy & " - periodeplan").Delete
End If

If CheckSheet("ukesplan", True) = True Then
    ThisWorkbook.SheetS(SheetNamesToCopy & " - ukesplan").Delete
End If

If CheckSheet("Input", True) = True Then
    ThisWorkbook.SheetS(SheetNamesToCopy & " - Input").Delete
End If

SheetS("Totalplan").Select
ThisWorkbook.SheetS(SheetNamesToCopy).Delete

Application.DisplayAlerts = True
Application.Calculation = xlCalculationAutomatic

End Sub

应用程序在大多数情况下都会崩溃。但并非总是如此......有什么想法可能是错的吗? (我已经测试并确认删除功能会导致崩溃,但它并不总是同一张)。

编辑:此功能不会删除工作簿中的最后一张工作表。还有20张。我也使用Application.Calculation = xlCalculationAutomatic,因为有很多公式,我不希望excel在所有连接的工作表被删除之前计算更改。

任何提示或答案表示赞赏:)

【问题讨论】:

  • 在哪一行崩溃?
  • 如果您暂时关闭该行会不会崩溃:Application.DisplayAlerts = False
  • @Olle 它在​​删除工作表的行上崩溃,但并非每次都崩溃。然而,它最常在最后一个删除命令时崩溃。
  • 您正在使用什么 Office 和系统?您是否在使用debug.print SheetNameToCopy 删除工作表名称之前对其进行了调试?你试过把On Error GoTo...
  • 好的,我已经缩小了范围!当我从要删除的工作表内的按钮运行宏时发生崩溃。我想我必须在其他工作表上制作一个按钮来管理工作表......

标签: vba excel excel-2010


【解决方案1】:

当启动宏的按钮位于要删除的工作表之一上时,会发生错误。

所以答案是:不要创建一个按钮(或链接到宏的图像)来删除它所在的工作表。

如果有人可以在此答案中添加此错误的原因,请这样做;)

【讨论】:

  • 没错,我猜这会崩溃,因为我删除了一个被认为是该宏的某种父对象的对象。因为它启动了宏。可能是原因;)
  • 谢谢奥莱。这让我发疯了。在我拥有之前(text_box 是我的文本框对象)。 text_box.OnAction = " user_done_click " 现在我改为设置 text_box.OnAction = "button_click" 并添加了这个子 Private Sub button_click() Application.OnTime Now() + TimeSerial(0, 0, 1), "user_done_click" End Sub
【解决方案2】:

我自己也遇到了这个问题!我将听从更有经验的设计师改进这项技术的方法,但作为一般概念,我确实有一个可行的解决方案:

如果您允许宏运行,然后删除工作表,它不会崩溃。像这样的:

Sub Delete_This_Sheet()

    Application.OnTime Now + TimeValue("00:00:02"), "Watergate"
    Sheets("Sheet with a death sentence").Visible = False
    
End Sub

Sub Watergate() 'To make things go away

    Application.DisplayAlerts = False
    Sheets("Sheet with a death sentence").Delete
    Application.DisplayAlerts = True

End Sub

【讨论】:

    【解决方案3】:

    因为我有同样的问题并想分享解决方案,所以恢复这个帖子。

    我有一个非常简单的子来删除工作表:

    Sub deletetraindoc()
    Dim ws As Worksheet
    
    Application.ScreenUpdating = False
    
    For Each ws In ThisWorkbook.Sheets
    
        'This if statement looks for any worksheet that contains the term "Form" 
        'Any worksheet that contains that string will be deleted
        If InStr(ws.Name, "Form") > 0 Then
                Application.DisplayAlerts = False 'Deactivates the standard deletion confirmation
                ws.Activate
                ws.Delete 'Deletes the worksheet
                Application.DisplayAlerts = True 'Reactivates display alerts
        End If
    Next
    Application.ScreenUpdating = True
    
    End Sub
    

    直到我添加“ws.Activate”行以在删除之前激活每个工作表之前,这一直导致崩溃,这似乎已经解决了问题。在对工作表执行操作的许多其他情况下,我都遇到过这个问题,但它通常会导致对象错误而不是完全崩溃。

    【讨论】:

      【解决方案4】:

      我发现在 Office 2013 中,您不能放置与该宏更改的单元格重叠的按钮。有趣的是,如果更改本质上是数字,则不会发生这种情况,但如果是字母数字,当您尝试删除该选项卡时,它会炸毁 excel。事实证明,当尝试手动删除选项卡(通过鼠标单击)或宏尝试删除选项卡时,它会炸毁它。因此,我从该线程中吸取的教训并将其应用于我的具体情况是永远不要在它更改的单元格上放置一个开发按钮(在我的情况下,它只是一个提供宏正在执行的状态的单元格)。 Excel 2013 不喜欢这种情况,而 Excel 2010 根本不在乎。

      【讨论】:

      • 这个“答案”实际上是一个新问题和该问题的答案的组合。您应该将其中的一部分作为新问题发布,将其他部分作为该问题的答案发布。 (是的,您可以回答自己的问题)。这是有用的信息。我希望你真的把它变成一个问答。
      【解决方案5】:

      我相信您是对的,解决此问题的唯一方法是确保此宏位于总体计划工作表上。此外,您还做了一些不必要的步骤,选择工作表应该是激活并选择一个单元格。

      Sub DeletePlan()    
      Application.Calculation = xlCalculationManual
      Application.DisplayAlerts = False
      Dim SheetNamesToCopy As String
      
      SheetNamesToCopy = ActiveSheet.Name
      
      'dont delete total plan
      If sheetnames = "Totalplan" then exit sub      
      
      SheetS("Totalplan").Activate
      Activesheet.Cells(1,1).select  
      
      'Turn off errors if sheet doesn't exist 
      On error resume next 
      ThisWorkbook.SheetS(SheetNamesToCopy & " - periodeplan").Delete
      ThisWorkbook.SheetS(SheetNamesToCopy & " - ukesplan").Delete
      ThisWorkbook.SheetS(SheetNamesToCopy & " - Input").Delete
      ThisWorkbook.SheetS(SheetNamesToCopy).Delete
      On error goto 0
      
      Application.DisplayAlerts = True
      Application.Calculation = xlCalculationAutomatic
      
      End Sub
      

      【讨论】:

      • 我不完全同意你的看法。我创建了函数 CheckSheet 来检查工作表是否存在(因为它通常不存在),我认为忽略错误以使代码工作是不好的做法。另外为什么我需要在“Totalplan”中选择一个单元格?这有什么改变吗?该错误是因为启动宏的按钮位于在此宏中删除的最后一张工作表上。宏本身位于一个模块中,因此它独立于工作表本身。
      • 这些实例非常常见,并且非常容易接受不要忽略它,而是预测错误并让它滑动,但要确保错误 0 被恢复。选择一个单元格可确保工作表具有 stage。并且由于该按钮在工作表上 并且仍在运行宏,无论位置如何,当您删除它时,您会杀死它恢复正常。你有其他方法来启动宏吗?
      • 是的,我在表单中添加了一个按钮,用于创建工作表(及其相关工作表)的副本。所以我现在开始工作了:) 选择一个单元格是有意义的。我补充一下,谢谢:)
      • 乐于帮助并创造更多的想法,即使它没有完全同意;)
      【解决方案6】:

      可以从活动工作表上的按钮(或图像)删除活动工作表。你只需要解决它。

      ActiveSheet.Move before:=Worksheets(1)
      Worksheets(2).Activate
      Worksheets(1).Delete
      

      【讨论】:

        【解决方案7】:

        我有一个类似但不相同的问题。我有一个使用以下命令删除所有图表的宏,但尽管它运行正确,但 Excel 2013 在我尝试保存文件时注定会失败,并且会通过恢复到以前保存的情况来“恢复”,丢弃任何后续工作:

        哦,它运行良好,直到我从 Excel 2010 迁移到 2013,同时切换到 Windows 10。 厄运的命令是:

        ThisWorkbook.Charts.Delete
        

        感谢上述答案的一些启发,我首先在删除操作之前插入了一个保存,然后按如下方式更改了删除(事实证明,保存毕竟不是必需的,但我喜欢将它们放在那里,即使我将它们注释掉):

        Dim graphSheet As Chart
        ActiveWorkbook.Save
        For Each graphSheet in this Workbook.Charts
        graphSheet.Delete
        ActiveWorkbook.Save
        Next graphSheet
        

        我还应该提到,在 for 循环之前有一个 Application.DisplayAlerts = False,当然在 Next... 语句之后有一个 Application.DisplayAlerts = True 来删除不需要的

        你确定要做这种类型的问题吗?

        再次感谢您的贡献者的启发。

        【讨论】:

          【解决方案8】:

          我想要一个可以删除工作表的按钮,因为工作簿受到保护并且可以“导出”结果但不能删除不需要的结果。

          我的简单解决方法是让宏隐藏工作表,然后删除最后一个隐藏工作表,这样文件就不会变得很大,有几十个隐藏工作表。

          我在名为“DeleteSheet”的隐藏工作表中创建了一个范围,用于存储隐藏工作表的名称。


          Sub Delete_Sheet()
          
          ActiveWorkbook.Unprotect Password:="Patrick2017"
          
          ActiveSheet.Unprotect Password:="Patrick2017"
          
          On Error Resume Next
          
          ' (In event there is no hidden sheet or the sheet is already deleted, resume next)
          
          'The below finds the name of the previously hidden sheet to delete, and stores it.
          
          Dim DeleteSheet As String
          DeleteSheet = Range("DeleteSheet")
          
          'The below is to avoid the main sheet being deleted
          
          If ActiveSheet.Name = "POAL Calculator" Then     
          Exit Sub                                        
          End If
          
          ' The below stores the current sheets name before hiding, for deleting next time the 
          ' macro is run
          
          Range("DeleteSheet") = ActiveSheet.Name          
          ActiveWindow.SelectedSheets.Visible = False 
          
          ' The below deletes the sheet previously hidden
          
          Application.DisplayAlerts = False 
          Sheets(DeleteSheet).Delete
          
          
          ActiveWorkbook.Protect Password:="Patrick2017"
          Application.DisplayAlerts = True
          
          End Sub
          

          【讨论】:

          • 如果您要发布代码,请将其放在代码块中,以便于阅读,谢谢
          【解决方案9】:

          将按钮代码移到模块中怎么样?

          我在 Excel 2016 中遇到了一个问题,如果代码在模块中,选项显式不起作用,但如果代码在模块中,那么您“应该”能够删除按钮是。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-09-04
            • 1970-01-01
            • 2017-12-03
            相关资源
            最近更新 更多