【问题标题】:Vba code works at times, and at times fails miserablyVba 代码有时可以工作,有时会惨遭失败
【发布时间】:2021-07-29 06:42:35
【问题描述】:

我编写了一个非常精细的代码,将 2 小时的工作自动化到不到 1 分钟。它可以在大多数日子里工作,就像今天这样的日子,代码不起作用,或者部分代码不起作用。 它是代码中最简单的部分不起作用。 这让我很沮丧。 要让代码正常工作,我要做的就是重新启动系统。

请理解,我根本不会更改代码。在错误发生之前或之后。

是发生错误的代码。

Range("Table1_2[[#Headers],[Bag No]:[Batch Making]]").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy

On Error Resume Next
Application.DisplayAlerts = False
Worksheets("Batch Making").Delete
Sheets.Add(After:=Sheets("Sheet1")).Name = "Batch Making"

Range("A1").Select
ActiveSheet.Paste
Cells.Select
Cells.EntireColumn.AutoFit

今天的错误是它不会粘贴代码选择的内容。 请注意:

  1. 它选择了行和列的集合
  2. 它创建了新工作表并选择了第一个单元格
  3. 它也尝试粘贴该值,但没有任何反应。

重启系统后,代码如梦似幻。

为什么会这样??有什么线索吗??

编辑:最大的问题是复制错误,正如我在某些日子里提到的,代码会崩溃,否则它会顺利运行。

每天都会向程序提供新数据,并对其进行清理以确保仅将程序可以获取的数据提供给它,这包括删除#N/A、#VALUE 和#Ref(今天也这样做了,崩溃后我仔细检查了数据)

但有时它会失败。

我将删除错误处理程序并使用单独的代码来检查工作表的可用性,以防错误再次弹出,然后我会在这里更新。

【问题讨论】:

  • 1) 您将从阅读此How to avoid using Select 中受益。 2)“不工作”不是一个有用的描述,它怎么不工作?有错误吗?如果是这样,哪条线? 3) 强烈建议始终完全限定您的范围引用,以避免引用错误的工作簿/工作表。 4) 删除 On Error Resume Next 除非你知道你在用它做什么,否则它会隐藏所有可能导致它不起作用的错误。
  • 好吧,我们有一个复杂的宏,我们有一个宏标记为完成的步骤列表。这意味着我们可以看到它失败的地方 - 使错误检查更加容易......
  • @RaymondWu 嗨,感谢您的评论。代码将运行,它选择表格的一部分,创建一个新工作表,然后将所选组件粘贴到工作表的第一个单元格中,现在粘贴部分不起作用。错误部分是如果代码尝试删除工作表并且工作表不存在,那么它不应该失败
  • @Allwyn 在您使用On Error Resume Next 作为测试/预防崩溃的情况下,您应该在测试后立即设置On Error Goto 0,以便帮助您继续拾取错误。 (所以在您的情况下,您将在 Worksheets("Batch Making").Delete 之后添加该行)

标签: excel vba


【解决方案1】:

你可以试试下面的代码。在 99% 的时间里,使用 select 并不是最好的主意。此外,在引用单元格时,最好准确地告诉 VBA 使用哪个工作表。

我建议替换 on error resume next 子句 - 它会禁用代码中的所有错误,如果出现问题,您将不会收到通知。在这种情况下,您可以编写更多代码来检查特定工作表是否存在,然后删除/添加它。

Sub copytable()
        
        Dim ws As Worksheet
        Set ws = ThisWorkbook.Worksheets("worksheet_with_table_you_want_to_copy")
        
        On Error Resume Next
        Application.DisplayAlerts = False
        ThisWorkbook.Worksheets("Batch Making").Delete
        ThisWorkbook.Sheets.Add(After:=Sheets("Sheet1")).Name = "Batch Making"
        Application.DisplayAlerts = True

        ws.ListObjects(1).Range.Copy
        With ThisWorkbook.Worksheets("Batch Making")
            .Range("a1").PasteSpecial xlPasteAll
            .Cells.EntireColumn.AutoFit
        End With
    End Sub

编辑:没有on error但检查wheather工作表“批处理”存在的代码,如果它是真的,删除它

Sub copytable()
        
    Dim wsTable As Worksheet
    Set wsTable = ThisWorkbook.Worksheets("worksheet_with_table_you_want_to_copy")
    Dim ws As Worksheet
    
    Application.DisplayAlerts = False
    For Each ws In ThisWorkbook.Worksheets
        If ws.Name = "Batch Making" Then ThisWorkbook.Worksheets("Batch Making").Delete
    Next ws
    Application.DisplayAlerts = True
    ThisWorkbook.Sheets.Add(After:=Sheets("Sheet1")).Name = "Batch Making"
    ws.ListObjects(1).Range.Copy
    With ThisWorkbook.Worksheets("Batch Making")
        .Range("a1").PasteSpecial xlPasteAll
        .Cells.EntireColumn.AutoFit
    End With
End Sub

【讨论】:

  • 如果要删除的工作表不存在,则需要On Error Resume Next 以防止崩溃。
  • 这就是为什么我建议编写额外的代码来检查它是否存在并删除如果它是真的。错误处理提供的 Allwyn 不是他的代码中最好的部分,因为它影响子句下面的所有行 - 如果任何其他代码行不正确,则不会弹出错误信息。
  • @Gonso 你说得对.. 我没有那样想.. 感谢您的建议,我将删除错误处理程序并再次运行代码。也许真正的问题现在会出现。
  • @AllwynP 鉴于你说你已经运行了 10 次没有失败,也许你应该接受它,因为它显然比你自己的代码更稳定......
  • @Gonso 代码现在更稳定了,直到现在没有崩溃。如果有任何新的开发,我会更新
【解决方案2】:

不幸的是,您没有说明您的代码应该做什么,但您似乎有一个模板并尝试使用该模板创建一个包含表格的新工作表。

问题是来源不合格。您的代码从未指定的源工作表复制“Table_2”,然后删除“批处理”选项卡,使用该名称创建一个新工作表并将剪贴板粘贴到这个新工作表。这个过程有点不合逻辑,因为如果来源是一张名为“Batch Making”的工作表,那么在副本安全到位之前删除原件需要很大的信心。但我认为你有一个模板。因此没有丢失数据的危险,但问题是为什么在需要之前制作副本。无论哪种方式,如果在删除和插入工作表时剪贴板上的副本丢失,“什么都不会发生”,就像你说的那样。

但是应该发生什么?我假设您只是获得了模板的新副本,这意味着您保留了表格的结构。因此,我下面的代码采用了完全不同的方法。它不会删除工作表(其中包含表格),也不会创建新工作表。相反,它只是删除现有工作表中表格的内容。

Sub Snippet()
    ' 295

    Const WsName    As String = "Batch Making"

    Dim Ws          As Worksheet            ' Sheets(WsName)
    Dim Tbl         As ListObject
    
    On Error Resume Next
    Set Ws = Worksheets(WsName)
    If Err Then
        MsgBox "Sorry, there is no tab """ & WsName & """ in this workbook.", _
               vbInformation, "Missing worksheet"
    Else
        Set Tbl = Ws.ListObjects(1)
        If Err Then
            MsgBox "Sorry, there is no table on the specified worksheet.", _
                   vbInformation, "Missing table"
        Else
            Tbl.DataBodyRange.ClearContents
        End If
    End If
End Sub

这是由一行代码完成的,即Tbl.DataBodyRange.ClearContents。那时你可以采取更多或不同的行动。例如,您可以删除不需要的行或添加默认单元格内容。如果有很多这样的默认值,您可能会从模板中获取这些数据(或公式)。否则只需将其添加到代码中。标题和总计不会被删除。表的结构保持不变。

在此之前,在上面的代码中,工作表是合格的,表格是合格的。代替错误消息,您可以插入代码来创建选项卡和/或创建表格。

请注意代码顶部的工作表名称。您可以将该字符串更改为任何其他名称。该代码未指定表的名称。相反,它假定该工作表上只有一个表并清除该表。

【讨论】:

    猜你喜欢
    • 2018-04-25
    • 1970-01-01
    • 2017-01-28
    • 1970-01-01
    • 2020-05-11
    • 1970-01-01
    • 1970-01-01
    • 2016-02-27
    • 1970-01-01
    相关资源
    最近更新 更多