【问题标题】:Trying to delete all sheets in a workbook, then add other sheets in with VBA尝试删除工作簿中的所有工作表,然后使用 VBA 添加其他工作表
【发布时间】:2016-12-22 17:22:05
【问题描述】:

我在尝试删除工作簿中的大多数工作表然后将它们重新添加时一直遇到错误。

我无法删除工作簿中的所有工作表;至少需要一张纸。美好的。所以我首先创建了一个名为TempSheet 的工作表。

targetWorkbook = ActiveWorkbook.Name
'/* ...more code... */
Application.Workbooks(targetWorkbook).Activate
Application.Workbooks(targetWorkbook).Worksheets.Add.Name = "TempSheet"

所以现在,我想删除工作簿中除TempSheet 之外的所有工作表。所以我正在尝试这样做:

For Each ws1 In Application.Workbooks(targetWorkbook).Worksheets
    If ws1.Name <> "TempSheet" Then
        Workbooks(targetWorkbook).Sheets(ws1.Name).Delete '/* Line X. */
    End If
Next

当我单步执行我的代码并到达 Line X 时,我收到错误 Can't enter break mode at this time。我试过用ws1.Delete 替换Line X 上的所有代码,我得到了同样的信息。我想至少单步执行代码,以便看到被删除的工作表。

我的代码的另一部分是,我想从另一个工作簿中取出所有工作表,并将它们放在我从上面删除所有工作表的第一个工作簿中。我的代码如下:

Application.Workbooks("OtherWorkbook").Activate '/* Line Y. */
For Each ws2 In Application.Workbooks(sheetsWorkbook).Worksheets
    ws2.Copy After:=Workbooks(targetWorkbook).Sheets(ws1.Name)
Next

我在Line Y 上设置了一个断点,在收到Can't enter break mode at this time 错误后,我点击了Continue 按钮。我没有在断点处停止,而是收到错误Run-time error '424'. Object required,它没有显示它指的是哪一行,也不允许我调试(按钮是灰色的,我可以选择的唯一按钮是end)。

关于如何实现这一点的任何建议?

【问题讨论】:

  • 您能否尝试用一些禁用事件、警报、屏幕更新和计算来封闭您的删除循环?
  • 什么是ws1?它是 Dimed 作为工作表吗?
  • 既然要删除所有工作表,为什么不从新工作簿开始呢?

标签: excel vba runtime-error


【解决方案1】:

清理你的语法,不需要像例如这样的冗余:

targetWorkbook = ActiveWorkbook.Name
Application.Workbooks(targetWorkbook).Activate

这基本上是在说:ActiveWorkbook.Activate,它不仅不做任何事情(字面意思),而且几乎不需要依赖ActivateSelect 来实现任何东西,假设您使用适当范围的对象变量。

Option Explicit
Sub foo()
Dim tempSheet as Worksheet, ws as Worksheet, wb As Workbook
Set wb = ActiveWorkbook ' Or ThisWorkbook, or Workbooks("filename.xlsx"), etc.
Set tempSheet = wb.Sheets.Add

For Each ws in wb.Worksheets
    Application.DisplayAlerts = False
    If ws.Name <> tempSheet.Name Then
        ws.Delete
    End If
    Application.DisplayAlerts = True
Next

'Now copy the other worksheets:
Workbooks("OtherWorkbook").Worksheets.Copy After:=wb.Worksheets(1)

'Finally, remove tempsheet
tempSheet.Delete

End Sub

应该工作。如果您无法进入中断模式,则说明您的 PC 发生了其他问题。

当我单步执行我的代码并到达第 X 行时,我收到错误“此时无法进入中断模式”。

如果您正在单步执行代码,那么您已经处于中断模式,所以这没有任何意义。看看这些建议是否有助于确定错误的来源:

Can't enter break mode at this time

  1. 从 VBE 调试菜单“编译 VBA 项目”,值得一试。
  2. 完全删除该行。运行代码。然后将行放回并使用断点重试。
  3. Sheets.Add 之后添加DoEvents 语句
  4. 使用MsgBox 而不是Debug.Print 上的断点。显示消息框后,尝试使用 ctrl+fn+End 手动中断。 (此时,“打破”不是必需的,但看看你是否可以这样打破会很有趣)
  5. 改为在Sheets.Add 上设置断点;实际上,如果您可以将断点放在前一行,则没有理由将断点放在 Print 语句上。
  6. 有插件吗?如果是这样,请禁用所有这些,然后一次重新启用一个,测试哪个可能导致错误。

【讨论】:

  • 只是回到这个。此代码不起作用。此代码将删除我所有的常规工作表(如果我跳过带有按钮的工作表的迭代,我发现我的原始代码也会这样做),但是当它到达带有按钮的工作表时,由于某种原因它仍然告诉我@987654333 @。我尝试先删除按钮,但没有奏效。我至少知道问题出在哪里,所以我要玩一会儿。不过感谢您的回复。
  • 您能解释一下删除工作表并复制到新工作簿的原因吗?为什么不直接复制到新工作簿(不删除)?
  • 我要删除的工作簿是一个启用宏的工作簿,多个人可能在任何给定时间打开它。我希望能够在我的机器上进行开发更改,并导出所有更改,包括工作表上的任何 UI 更改,然后让用户“重新加载”他们正在使用的工作簿(一个运行删除所有工作表的宏的按钮并从 xlsx 复制工作表),而无需关闭并重新打开它。这是我无法在工作表上导出图形更改的解决方法。
  • 在一个完美的世界中,如果我更改其中的一些代码以满足我的应用程序的需求并让它在不单步执行的情况下撕裂,那么它可以工作,所以我将接受这个作为答案并且只是把它归结为我身边发生的事情。谢谢。
【解决方案2】:

您已经设置了ws1 sheet 对象,并且在工作簿中循环,您可以直接删除ws1 对象,而不会使语法过于复杂。

Dim ws1 As Worksheet

For Each ws1 In Application.Workbooks(targetWorkbook).Worksheets
    If ws1.Name <> "TempSheet" Then
        ws1.Delete
    End If
Next

您也可以像这样设置工作簿:

Dim wb1 As Workbook

Set wb1 = ActiveWorkbook ' better yet use ThisWorkbook if the workbook is the one with this code in it

For Each ws1 In wb1.Worksheets
    If ws1.Name <> "TempSheet" Then
        ws1.Delete
    End If
Next

完整代码

Sub Add_DeleteWorksheets()

Dim wb1 As Workbook
Dim ws1 As Worksheet
Dim tmpsht As Worksheet

Set wb1 = ActiveWorkbook ' better yet use ThisWorkbook if the workbook is the one with this code in it
Set tmpsht = wb1.Worksheets.Add
tmpsht.Name = "TempSheet"

For Each ws1 In wb1.Worksheets
    If ws1.Name <> tmpsht.Name Then
        ws1.Delete
    End If
Next

End Sub

【讨论】:

  • 嘿。感谢您的回复。我提到我已经尝试过ws1.Delete 并得到了同样的错误。关于如何实现这一点的任何其他想法?
  • @aCarella 是 ws1 定义为 Worksheet ?
  • 我已经实现了以上所有,但仍然收到相同的错误消息。
  • @aCarella 尝试完整代码部分下的代码
【解决方案3】:

我在评论中提出的其他方法,您可以尝试以下两种方法


方法 1 - 首先插入新工作簿,然后删除现有工作簿

这种方法的优点是您不需要任何“临时”工作表,并且在您的活动工作簿同时具有“旧”和“新”工作表的临时阶段达到内存限制的可能缺点

Option Explicit

Sub delsheets1()
    ReDim existingSheets(1 To Worksheets.Count) As String
    Dim isht As Long

    For isht = 1 To Worksheets.Count
         existingSheets(isht) = Worksheets(isht).Name
    Next

    Application.DisplayAlerts = False
    Workbooks("Cartel2").Worksheets.Copy After:=Worksheets(1)
    Worksheets("OtherWorkbook").Delete
    Application.DisplayAlerts = True
End Sub

方法 2 - 首先删除现有的工作簿,然后插入新的工作簿

这与您的方法相同,并且具有插入新“临时”表的(仅逻辑,确实)缺点

可能是“组”删除技术避免了您当前代码遇到的问题

Option Explicit

Sub delsheets2()
    ReDim existingSheets(1 To Worksheets.Count) As String
    Dim isht As Long

    For isht = 1 To Worksheets.Count
         existingSheets(isht) = Worksheets(isht).Name
    Next

    Worksheets.Add.Name = "TempSheet"

    Application.DisplayAlerts = False
    Worksheets(existingSheets).Delete
    Workbooks("OtherWorkbook").Worksheets.Copy After:=Worksheets(1)
    Worksheets("TempSheet").Delete
    Application.DisplayAlerts = True
End Sub

【讨论】:

  • @aCarella,您尝试过其中一种解决方案吗?
【解决方案4】:

这是另一个。当您单击 newsheet 按钮时,此例程会删除除一张以外的所有工作表:

Public Sub Workbook_NewSheet(ByVal Sh As Object)

  Application.EnableEvents = False
  Application.DisplayAlerts = False
  For i = Workbooks(1).Sheets.Count - 1 To 1 Step -1
    Workbooks(1).Sheets(i).Delete
  Next
  Sheets(1).Name = "Sheet1"
  Application.DisplayAlerts = True
  Application.EnableEvents = True
End Sub

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-11
    • 2021-10-03
    • 2017-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多