【问题标题】:Excel Vba Macro to Delete Entire Row Based on Column HeaderExcel Vba宏根据列标题删除整行
【发布时间】:2017-03-15 22:09:54
【问题描述】:

下面的代码可以修改成

  1. 根据列标题和单元格值删除多行,并且
  2. 对多列行组合执行此操作?

示例:列“状态”值“完成” 循环浏览所有工作表并查找任何标有状态的标题并删除其中状态包含完整的所有行?

Sub Delete_Rows_Based_On_Header_and_Value ()
'
' Delete_Rows_Based_On_Header_and_Value Macro
'
' Declaration
Dim a as long
Dim w as long
Dim vDELCOLs as variant
Dim vCOLNDX as variant
Dim vDELROWs as variant
Dim vROWNDX as variant

vDELCOLs = array("status","Status Name","Status Processes")
vDELROWs = array("Complete","Completed","Done")

with Activeworkbook
    for w=1 to .worksheets.count
        with worksheets(w)
' I know this part is to delete columns based on the column name and I am not sure how to modify it to just check column name then delete row based on the value on that column only.
            for a=lbound(vdelcols) to ubound(vdelcols)
                vcolndx=application.match(vdelcols(a), .rows(1), 0)
                if not iserror(vcolndx) then
                    .columns(vcolndx).entirecolumn.delete
                end if
            next a
        end with
    next w
end with

【问题讨论】:

  • 在编写更多代码之前,您需要决定是否要删除一行,如果 (a) 状态列包含“完成”或状态名称列包含“完成”或状态流程列包含“完成”,或 (b) 状态列包含“完成”且状态名称列包含“已完成”且状态流程列包含“完成”。
  • 因此,对 1 个列名和 1 个单元格值执行此操作会更容易,即:状态和完成,然后是状态名称和完成的另一行,状态过程的第三行并完成对吗?这样可以简化代码和流程?
  • 对于一个值稍微会更简单 - 它可以省去考虑是要所有值匹配还是要匹配任何值。但是,如果您愿意只检查一列的值,那么您可能已经决定要在 any 值匹配时删除该行。
  • 它可以是 1 列的多个值?所以状态我想删除 Complete 和 Pending - 然后一旦所有这些都被删除,我可以选择 Status Name 和 Completed 和 Pending 等,所以在这种情况下,我只需要它来查找某个列,然后查找一个数组如果这些值中的任何一个存在,则删除整行? - 也可以编辑我的帖子,如果不够清楚,请见谅!

标签: vba excel


【解决方案1】:

以下代码将数组数组作为vDELROWS,如果任何值与对应列中的值匹配,则删除一行。

Sub Delete_Rows_Based_On_Header_and_Value()
    '
    ' Delete_Rows_Based_On_Header_and_Value Macro
    '
    ' Declaration
    Dim a As Long
    Dim w As Long
    Dim vDELCOLs As Variant
    Dim vCOLNDX As Variant
    Dim vDELROWs As Variant
    Dim vROWNDX As Variant
    Dim r As Long
    Dim v As Long

    vDELCOLs = Array("status", "Status Name", "Status Processes")
    vDELROWs = Array(Array("Complete", "Pending"), Array("Completed", "Pending"), Array("Done"))

    With ActiveWorkbook
        For w = 1 To .Worksheets.Count
            With Worksheets(w)
                For a = LBound(vDELCOLs) To UBound(vDELCOLs)
                    vCOLNDX = Application.Match(vDELCOLs(a), .Rows(1), 0)
                    If Not IsError(vCOLNDX) Then
                        For r = .Cells(.Rows.Count, vCOLNDX).End(xlUp).Row To 1 Step -1
                            For v = LBound(vDELROWs(a)) To UBound(vDELROWs(a))
                                If .Cells(r, vCOLNDX).Value = vDELROWs(a)(v) Then
                                    .Rows(r).EntireRow.Delete
                                    Exit For
                                End If
                            Next
                        Next
                    End If
                Next a
            End With
        Next w
    End With
End Sub

【讨论】:

  • 你好,为了确保我理解,因为这远远高于我现在..所以你的意思是这将删除 "status -Complete" "status - Pending" "status 的任何组合- 已完成” “状态 - 完成” AND “状态名称 - 完成” “状态名称 - 待定” “状态名称 - 已完成” “状态 - 完成” AND “状态流程 - 完成” “状态流程 - 待定” “状态流程 - 已完成" "状态流程 - 完成" 对吗?
  • 不,它将首先处理“状态”列并删除任何包含“完成”或“待定”的行(由于Array("Complete", "Pending")),然后它将通过“状态名称” " 列并删除任何包含“已完成”或“待处理”的行(由于Array("Completed", "Pending")),然后它将通过“状态进程”列并删除任何包含已完成的行(由于Array("Done"))。所以vDELROWS 数组中的每个Array(...) 对应于vDELCOLS 数组中的等效列。
  • 有道理!它是完美的,太棒了
【解决方案2】:

自动过滤比循环更有效

Sub DeleteRows()
    Sheet1.Range("a1:c35").AutoFilter Field:=2, Criteria1:="Completed"
    Sheet1.UsedRange.Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Delete
Sheet1.UsedRange.AutoFilter
'repeat for each value
End Sub

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-10
    • 2014-11-09
    • 1970-01-01
    • 1970-01-01
    • 2022-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多