【问题标题】:I don't understand how the code read (VBA)我不明白代码是如何读取的(VBA)
【发布时间】:2021-09-02 01:43:53
【问题描述】:

Delete Excel worksheets if not in array

下面的代码用于删除不在数组中的工作表。虽然下面的代码可以成功运行,但我的理解存在问题。

由于有一个布尔“Matched”声明为默认为 False(根级别),因此如果 wsName = ws.Name,那么它将被分配 Matched = True(父级别)。那么,对于那些不是 wsName = ws.Name 的,应该是 False 吧?

当那些不匹配并退出循环并运行下一行时,它们应该是 False 并匹配父级 False,但我不明白为什么下一行说“如果不匹配.. " 和我的逻辑思维很矛盾。

我是 VBA 新手,希望有人能帮助我。

Sub DeleteNewSheets()

Dim ws As Worksheet
Dim ArrayOne() As Variant
Dim wsName As Variant
Dim Matched As Boolean

ArrayOne = Array("SheetA", "SheetB", "SheetC", "Sheet_n")

Application.DisplayAlerts = False

For Each ws In ThisWorkbook.Worksheets
    Matched = False
    For Each wsName In ArrayOne
        If wsName = ws.Name Then
            Matched = True
            Exit For
        End If
    Next
    If Not Matched Then
        ws.Delete
    End If
Next ws

Application.DisplayAlerts = True

结束子

【问题讨论】:

  • 因此,对于工作簿中的每个工作表,我们执行以下操作:将 Matched 设置为 False,然后检查整个数组以查看工作簿名称是否在数组中。如果它在数组中 Matched 设置为 True 并且我们停止检查数组。当循环结束时,如果 Matched 为 True 那么我们知道它在数组中,如果 Matched 为 False 那么它不在数组中。如果 Matched 为 False,我们删除工作表,然后继续下一张工作表:将 Matched 设置为 False 并检查整个数组,等等。
  • 我认为您需要关注的部分是,对于每张纸,Matched 设置为 False,我们检查数组。如果我们找到它,我们将 Matched 设置为 True,但如果我们没有找到它,我们什么也不做。因此,在检查 Matched 是否为 True 之后,我们需要检查 Matched 的值以确定我们是否删除工作表 - 这就是 If Not Matched Then 正在做的事情:If Not Matched Then 与 @987654325 相同@ - 它正在检查 Matched 的值,看它是 False 还是 True。
  • 嗨,杰瑞,首先我要感谢您的解释。那么,你的意思是对于那些不在数组中的名字,它们会被退出循环,而不是任何与True / False相关的值>
  • 那么,这就是为什么那些不匹配的人有资格获得“如果匹配真那么”?
  • 那些不在数组中的名字可以是False值吗?或者简单地说,它们根本不是 True / False 值。

标签: excel vba


【解决方案1】:

删除有例外的工作表

  • 以下(不同的)方法说明了如何处理建议代码中的一些问题:
    • 区分大小写,即"SheetA" <> "sheetA"
      • 使用StrComp 进行有效处理,例如
        If StrComp("SheetA", "sheetA". vbTextCompare) = 0 Then
      • 在此代码中,使用Application.Match 处理。
    • 工作表的可见性
      • 必须至少留下一张可见的工作表 (xlSheetVisible)。
      • 您无法删除非常隐藏的工作表 (xlSheetVeryHidden),但可以删除隐藏的工作表 (xlSheetHidden)。
    • 工作簿保护(主要错误处理程序)
Option Explicit

Sub DeleteSheetsTEST()
    Dim wb As Workbook: Set wb = ThisWorkbook
    Dim Exceptions As Variant
    Exceptions = Array("SheetA", "SheetB", "SheetC", "Sheet_n")
    DeleteSheets wb, Exceptions
End Sub

Sub DeleteSheets( _
        ByVal wb As Workbook, _
        ByVal Exceptions As Variant)
    Const ProcName As String = "DeleteSheets"
    On Error GoTo ClearError
    
    Const Title As String = "Delete Sheets"
    
    Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary")
    
    Dim sh As Object
    For Each sh In wb.Sheets
        dict(sh.Name) = Empty
    Next sh
    
    Dim dictDel As Object: Set dictDel = CreateObject("Scripting.Dictionary")
    Dim dictKeep As Object: Set dictKeep = CreateObject("Scripting.Dictionary")
    
    Dim Key As Variant
    For Each Key In dict.Keys
        If IsNumeric(Application.Match(Key, Exceptions, 0)) Then
            dictKeep(Key) = Empty
        Else
            dictDel(Key) = Empty
        End If
    Next Key
    
    If dictDel.Count = 0 Then
        MsgBox "Nothing to delete. No action taken.", vbExclamation, Title
        Exit Sub
    End If
    
    If dictKeep.Count = 0 Then
        MsgBox "No sheets to keep. No action taken.", vbCritical, Title
        Exit Sub
    End If
    
    Dim FoundKeeper As Boolean
    For Each Key In dictKeep.Keys
        If wb.Sheets(Key).Visible = xlSheetVisible Then
            FoundKeeper = True
            Exit For
        End If
    Next Key
    
    If Not FoundKeeper Then
        MsgBox "No visible sheets to keep. No action taken.", vbCritical, Title
        Exit Sub
    End If
    
    For Each Key In dictDel.Keys
        If wb.Sheets(Key).Visible = xlSheetVeryHidden Then
            wb.Sheets(Key).Visible = xlSheetVisible
        End If
    Next Key
    
    Application.DisplayAlerts = False
    wb.Sheets(dictDel.Keys).Delete
    Application.DisplayAlerts = True
    
    MsgBox "Successfully deleted the following sheets:" & vbLf & vbLf _
        & Join(dictDel.Keys, vbLf), vbInformation, Title
    
ProcExit:
    Exit Sub
ClearError:
    MsgBox "'" & ProcName & "': Unexpected Error!" & vbLf _
              & "    " & "Run-time error '" & Err.Number & "':" & vbLf _
              & "        " & Err.Description, vbCritical
    Resume ProcExit
End Sub

【讨论】:

  • 谢谢VBasic2008,方法对我来说非常先进,但我会尝试阅读你写的代码。
  • 你是 VBA 大师!
  • @RyanYeung 见Someone answers
猜你喜欢
  • 2021-11-03
  • 2019-11-23
  • 2020-01-04
  • 1970-01-01
  • 2012-09-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-02
  • 2017-06-14
相关资源
最近更新 更多