【问题标题】:Excel VBA: Cannot delete multi columns by using if statement and for loopExcel VBA:无法使用 if 语句和 for 循环删除多列
【发布时间】:2018-04-19 02:14:28
【问题描述】:
  1. 背景和目的。 我想根据特定的列标题删除“sheet1”中的多列。

例如:如果列名 = “First Name”、“Surname”、“DoB”、“Gender”、“Year” 然后删除整个列。

我使用 vba 来做到这一点。

  • “执行”表中的“执行”按钮
  • 数据保存在“Sheet1”中。
  • 点击“执行”按钮,将执行宏并编辑“sheet1”中的数据。

这是我的代码

Sub SPO_EditDocument_BUttonClick()

'Declare constant variable
Dim CellValue As String

'Edit SPO Documents.
'Consider worksheet"SPO"

With Worksheets("Sheet1")

    '1. Loop and delete unnecessary columns
    LastCol = Sheets("Sheet1").Cells.Find(What:="*", After:=[A1], SearchOrder:=xlByColumns, _
              SearchDirection:=xlPrevious).Column

    For i = 1 To LastCol
        On Error Resume Next

        CellValue = Sheets("Sheet1").Cells(1, i)   'Get Column header

        If CellValue = "Firstname" Then
            Sheets("Sheet1").Columns(i).EntireColumn.Delete

        ElseIf CellValue = "Surname" Then
            Sheets("Sheet1").Columns(i).EntireColumn.Delete

        ElseIf CellValue = "DoB" Then
            Sheets("Sheet1").Columns(i).EntireColumn.Delete

        ElseIf CellValue = "Gender" Then
            Sheets("Sheet1").Columns(i).EntireColumn.Delete

        ElseIf CellValue = "Year" Then
            Sheets("Sheet1").Columns(i).EntireColumn.Delete
        End If
    Next i

End With  'End to process Worksheets

Application.ScreenUpdating = True

End Sub

Sample data table in sheet1

  1. 问题:当我通过单击“执行”按钮执行宏时,当时只删除了 1 列。下一步点击→删除下一列(一键删除1列)。
  2. 问题:为什么我的代码不能一键删除所有列? 这种情况有什么问题?

任何帮助将不胜感激。 非常感谢您的关注。

Insert new columns before found cells

【问题讨论】:

    标签: vba excel excel-formula


    【解决方案1】:

    以相反的顺序遍历列。为此,请更改您的线路:

     For i = 1 To LastCol
    

    到:

     For i = LastCol to 1 Step -1
    

    【讨论】:

    【解决方案2】:

    另一种快捷方式

    Option Explicit
    
    Sub SPO_EditDocument_BUttonClick()
        Dim colNames As Variant, colName As Variant, actualColNames As Variant, foundColName As Variant
        Dim colsToDelete As String
    
        colNames = Array("Firstname", "Surname", "DoB", "Gender", "Year") ' build a list of column headers to be deleted
    
        With Worksheets("Sheet1") ' reference data sheet
            actualColNames = Application.Index(.Range("A1", .Cells(1, .Columns.count).End(xlToLeft)).Value, 1, 0) ' collect referenced sheet actual column headers
    
            For Each colName In colNames ' loop through your column headers to be deleted list
                foundColName = Application.Match(colName, actualColNames, 0) ' try finding current header to be deleted in actual headers list
                If Not IsError(foundColName) Then colsToDelete = colsToDelete & Columns(foundColName).Address(False, False) & " " 'if found update columns to be deleted index list
            Next
    
            If colsToDelete <> "" Then .Range(Replace(Trim(colsToDelete), " ", ",")).EntireColumn.Delete ' if columns to be deleted index list not empty, then delete thsoe columns
        End With
    

    【讨论】:

    • 嗨@Shai Rado,删除列的速度比我快。非常感谢您的建议。真的很感激。
    • 它工作得很好,而且很容易进行维护。但是,我还有 1 个问题。你能帮我解决这个问题吗?我想在一些找到的单元格之前插入一些新列并向其中一些单元格添加公式。在这种情况下我该怎么办?有关详细信息,请参阅我的主题中的新附加图片“在找到的单元格之前插入新列”。
    • @Holmes,这值得你提出一个全新的问题。
    • 谢谢。这是我的新帖子。请帮我检查一下。 stackoverflow.com/questions/49951709/…
    【解决方案3】:

    删除多个列的更快方法是使用Range 对象,在我的代码中它是DelRng,它合并所有通过您的删除条件的Columns - 使用Union 函数。所以最后,你只需要使用Delete 函数,这需要很长时间才能处理一次。

    您可以将多个ElseIfs 替换为Select Case

    所有嵌套在With Worksheets("Sheet1") 中的对象都不需要再次使用With Worksheets("Sheet1"),只需使用. 作为所有CellsRange 对象的前缀即可。

    您可以拥有更短、更快的代码版本,如下面的代码:

    修改后的代码

    Sub SPO_EditDocument_BUttonClick()
    
    'Declare constant variable
    Dim CellValue As String
    Dim DelRng As Range
    
    'Edit SPO Documents.
    'Consider worksheet"SPO"
    
    Application.ScreenUpdating = False
    
    With Worksheets("Sheet1")
    
        '1. Loop and delete unnecessary columns
        LastCol = .Cells.Find(What:="*", After:=[A1], SearchOrder:=xlByColumns, SearchDirection:=xlPrevious).Column
    
        For i = 1 To LastCol
            CellValue = .Cells(1, i)   'Get Column header
    
            Select Case CellValue
                Case "Firstname", "Surname", "DoB", "Gender", "Year"
                    If Not DelRng Is Nothing Then
                        Set DelRng = Application.Union(DelRng, .Columns(i))
                    Else
                        Set DelRng = .Columns(i)
                    End If
    
                Case Else
                    ' Do nothing
    
            End Select
        Next i
    
    End With  'End to process Worksheets
    
    ' if there's at least 1 column in DelRng >> delete the entire range (all columns) in 1-shot
    If Not DelRng Is nothign Then DelRng.Delete
    
    Application.ScreenUpdating = True
    
    End Sub
    

    【讨论】:

    • 非常感谢@Shai Rado。使用 Select Case 为我删除列的好示例。
    • 谢谢。是的,你所有的答案都很好,从你的建议中学习非常有用。 ^^
    猜你喜欢
    • 1970-01-01
    • 2013-08-26
    • 2021-11-26
    • 1970-01-01
    • 2015-09-30
    • 2018-04-28
    • 2019-01-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多