【问题标题】:VBA: How to delete rows and keep some rows based on criteria?VBA:如何删除行并根据条件保留一些行?
【发布时间】:2017-06-08 10:47:27
【问题描述】:

我一直在编写这个包含三个步骤的宏。 First 是在 C 列和 Second 之后的行为空的情况下删除行步骤是有标题的行必须保留在工作簿中,例如 Contributions-All OtherProgram Fees-Youth第三步是通过在某些标题后添加空格或空行来格式化行。

这是我的代码,它似乎无法编译,我不确定如何防止行被删除...请帮助。

Sub RemoveRowsAndFormat()  
 Dim WS As Worksheet
 For Each WS In Sheets
 WS.Activate


   Dim n As Long
     Dim nlast As Long
     Dim rw As Range
     Set rw = ActiveWorkbook.ActiveSheet.UsedRange.Rows
     nlast = rw.Count
     For n = nlast To 9 Step -1
      If (rw.Cells(n, 3).Value = "Contributions-All Other" Or rw.Cells(n, 3).Value = "Program Fees - Youth" Or rw.Cells(n, 3).Value = "Financial Assitance" Or rw.Cells(n, 3).Value = "Salaries & Wages" Or rw.Cells(n, 3).Value = "Payroll Taxes" Or rw.Cells(n, 3).Value = "Employee Benefits" Or rw.Cells(n, 3).Value = "Staff Training and Confer." Or rw.Cells(n, 3).Value = "Occupancy" Or rw.Cells(n, 3).Value = "Supplies" Or rw.Cells(n, 3).Value = "Telephone" Or rw.Cells(n, 3).Value = "Postage & Shipping" Or rw.Cells(n, 3).Value = "Promotion and Advertising" Or rw.Cells(n, 3).Value = "Bad Debt" Or rw.Cells(n, 3).Value = "Program Operating Expense" Or rw.Cells(n, 3).Value = "Program Operating Net") Then
      rw.Rows(n).EntireRow.Insert
        ElseIf (rw.Cells(n, 4).Value = "" And rw.Cells(n, 5).Value = "" And rw.Cells(n, 6).Value = "" And rw.Cells(n, 7).Value = "" And rw.Cells(n, 8).Value = "" And rw.Cells(n, 9).Value = "" And rw.Cells(n, 10).Value = "" And rw.Cells(n, 11).Value = "") Then
             rw.Rows(n).Delete


         End If

     Next n
     Next WS
 End Sub

【问题讨论】:

  • 首先,rw.Cells(n, 3).Value = "Contributions-All Other" And rw.Cells(n, 3).Value = "Program Fees - Youth" 将计算为 False - rw.Cells(n, 3).Value 不能等于 "Contributions-All Other" AND 等于 "Program Fees - Youth"。您需要使用Or 而不是And
  • 我建议Set rw = ActiveWorkbook.ActiveSheet.UsedRange.Rows 应该只是Set rw = ActiveWorkbook.ActiveSheet.UsedRange
  • 除了那些 cmets,你能告诉我们你得到了什么错误信息 - 这将使我们能够找到你的编译错误的原因。
  • 在应用这些修复后,代码符合要求,问题不是所有标题都需要间距。第一个if 语句中的那些只需要保留而不被删除,但有些确实需要间距,我如何在标题下插入一行? @YowE3K

标签: vba excel


【解决方案1】:

您(已编辑)问题中的代码似乎正在执行您想要的操作,只是它在您的标题上方而不是下方添加了一行。这可以通过将rw.Rows(n).EntireRow.Insert 更改为rw.Rows(n + 1).EntireRow.Insert 来解决,但由于您定义rw 的方式,这可能会导致问题(如果最后一行存在标题)。

我已重构您的代码以使用 Select Case 语句替换您的 (IMO) 笨拙的 If 语句,并在决定在何处执行插入/删除时参考工作表而不仅仅是某些行。

Sub RemoveRowsAndFormat()  
    Dim WS As Worksheet
    Dim n As Long
    Dim nlast As Long
    Dim rw As Range
    Dim c As Long
    Dim allEmpty As Boolean
    For Each WS In Worksheets
        With WS
            nlast = .UsedRange.Rows(.UsedRange.Rows.Count).Row
            For n = nlast To 9 Step -1
                Select Case .Cells(n, 3).Value 

                    Case "Contributions-All Other", _
                         "Program Fees - Youth", _
                         "Financial Assitance", _
                         "Salaries & Wages", _
                         "Payroll Taxes", _
                         "Employee Benefits", _
                         "Staff Training and Confer.", _
                         "Occupancy", _
                         "Supplies", _
                         "Telephone", _
                         "Postage & Shipping", _
                         "Promotion and Advertising", _
                         "Bad Debt", _
                         "Program Operating Expense", _
                         "Program Operating Net"

                        .Rows(n + 1).EntireRow.Insert

                    Case Else

                        allEmpty = True
                        For c = 4 To 11
                            If .Cells(n, c).Value <> "" Then
                                allEmpty = False
                                Exit For
                            End If
                        Next
                        'The above could be replaced by a "COUNTA", but I like this way
                        If allEmpty Then
                            .Rows(n).Delete
                        End If
                End Select
            Next n
        End With
    Next WS
End Sub

您在最近的评论中说,一个新问题“并非所有标题都需要间距”。如果是这样,Select Case 语句可以很容易地包含该功能,如下所示:

                Select Case .Cells(n, 3).Value 

                    'Do nothing for headings which we just want to leave alone
                    Case "Contributions-All Other", _
                         "Program Fees - Youth", _
                         "Financial Assitance", _
                         "Salaries & Wages", _
                         "Payroll Taxes", _
                         "Employee Benefits", _
                         "Staff Training and Confer.", _
                         "Occupancy", _
                         "Supplies"

                    'Process cases where an additional row needs to be inserted
                    Case "Telephone", _
                         "Postage & Shipping", _
                         "Promotion and Advertising", _
                         "Bad Debt", _
                         "Program Operating Expense", _
                         "Program Operating Net"

                        .Rows(n + 1).EntireRow.Insert

                    'For all the other rows, check whether it needs to be deleted
                    Case Else

                        allEmpty = True
                        '...

(显然,我刚刚编好了哪些标题应该在它们之后插入行,哪些不应该。)

Select Case 语句只是编写以下If 语句的简化(?)方式:

If .Cells(n, 3).Value = "Contributions-All Other" Or _
   .Cells(n, 3).Value = "Program Fees - Youth" Or _
   .Cells(n, 3).Value = "Financial Assitance" Or _
   .Cells(n, 3).Value = "Salaries & Wages" Or _
   .Cells(n, 3).Value = "Payroll Taxes" Or _
   .Cells(n, 3).Value = "Employee Benefits" Or _
   .Cells(n, 3).Value = "Staff Training and Confer." Or _
   .Cells(n, 3).Value = "Occupancy" Or _
   .Cells(n, 3).Value = "Supplies" Then

ElseIf .Cells(n, 3).Value = "Telephone" Or _
       .Cells(n, 3).Value = "Postage & Shipping" Or _
       .Cells(n, 3).Value = "Promotion and Advertising" Or _
       .Cells(n, 3).Value = "Bad Debt" Or _
       .Cells(n, 3).Value = "Program Operating Expense" Or _
       .Cells(n, 3).Value = "Program Operating Net" Then

    .Rows(n + 1).EntireRow.Insert

Else

    allEmpty = True
    '...
End If

附: “财务援助”应该是“财务援助”吗?

【讨论】:

  • 箱子必须按顺序排列吗?
  • @MTBthePRO - “按顺序”是什么意思?它将执行评估为True 的第一个Case 的语句,因此从这个角度来看,它们需要按照您希望检查语句的顺序排列,但是您有三个(?)互斥事件,所以它对你来说并不重要(除了 Case Else 需要排在最后)。
  • 我想通了。其中一个 case 语句缺少逗号。
  • @MTBthePRO - 这是在我的答案中,还是在您编辑的答案版本中? (即,我是否需要编辑答案以免让未来的读者感到困惑?)
  • 不,您很好,先生。感谢您的帮助。 @YowE3K
猜你喜欢
  • 2021-12-21
  • 2023-01-19
  • 1970-01-01
  • 2015-11-05
  • 1970-01-01
  • 2015-07-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-09
相关资源
最近更新 更多