如果更改列中的单元格为空,请删除行

时间:2015-08-19 20:43:10

标签: excel vba excel-vba

这是Windows 7上的Excel 2010。

我收到的电子表格中有一列名为“已批准”。此列填充x和空格。我想删除该列中包含空格的所有行。这是一个简单的问题,但有两个混淆问题:

  1. Approved列的位置发生变化,因此我不能只进行Columns(“R”)。SpecialCells(xlBlanks).EntireRow.Delete。我试图通过在A1:Z5(因为总是少于26行)中搜索“Approve”来解决这个问题,并选择找到它的列。
  2. 大部分数据来自上个月的文档,因此一些“空白”单元格中填充了vlookup。我试着通过首先选择所有数据并粘贴为值来解决这个问题。
  3. 以下是当前代码:

    Sub DeleteCol()
    Range("A1").Select
    Range(Selection, Selection.SpecialCells(xlLastCell)).Select
    Selection.Copy
        Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
            :=False, Transpose:=False
    
      Dim rngApprove As Range
      Set rngApprove = Range("A1:Z5").Find("Approve")
      If rngApprove Is Nothing Then
        MsgBox "Approved column was not found."
        Exit Sub
      End If
      Dim approved_column As Range
      Set approved_column = rngApprove.EntireColumn
      approved_column.SpecialCells(xlBlanks).EntireRow.Delete
    End Sub
    

    复制+粘贴值按预期工作。但是,行删除仅删除行1-4并且仅将行5中的所有内容都留下,即使其中一些单元格为空。如果我用

    替换最后一行
    approved_column.select
    

    它应该选择整个列。这让我相信问题在于我的删除方法。

2 个答案:

答案 0 :(得分:1)

试试这个(基于delete rows optimization解决方案)

Option Explicit

Sub deleteRowsWithBlanks()
    Const KEY_STRING As String = "Approve"
    Dim oldWs As Worksheet, newWs As Worksheet, rowHeights() As Long
    Dim wsName As String, rng As Range, filterCol As Long

    Set oldWs = ActiveSheet
    wsName = oldWs.Name
    Set rng = oldWs.Range("A1:Z5")
    filterCol = getHeaderColumn(rng, KEY_STRING, True)

    If filterCol > 0 Then
        FastWB True
        If rng.Rows.Count > 1 Then
            Set newWs = Sheets.Add(After:=oldWs)
            With oldWs.UsedRange
                .AutoFilter Field:=filterCol, Criteria1:="<>"
                .Copy
            End With
            With newWs.Cells
                .PasteSpecial xlPasteColumnWidths
                .PasteSpecial xlPasteAll
                .Cells(1, 1).Select
                .Cells(1, 1).Copy
            End With
            oldWs.Delete
            newWs.Name = wsName
        End If
        FastWB False
    End If
End Sub

助手功能:

Public Function getHeaderColumn(ByVal rng As Range, ByVal headerName As String, _
                                Optional matchLtrCase As Boolean = True) As Long
    Dim found As Range, foundCol As Long

    If Not rng Is Nothing Then
        headerName = Trim(headerName)
        If Len(headerName) > 0 Then
            Set found = rng.Find(What:=headerName, MatchCase:=matchLtrCase, _
                                 LookIn:=xlFormulas, LookAt:=xlWhole)
            If Not found Is Nothing Then foundCol = found.Column
        End If
    End If
    getHeaderColumn = foundCol
End Function
Public Sub FastWB(Optional ByVal opt As Boolean = True)
    With Application
        .Calculation = IIf(opt, xlCalculationManual, xlCalculationAutomatic)
        .DisplayAlerts = Not opt
        .DisplayStatusBar = Not opt
        .EnableAnimations = Not opt
        .EnableEvents = Not opt
        .ScreenUpdating = Not opt
    End With
    FastWS , opt
End Sub

Public Sub FastWS(Optional ByVal ws As Worksheet = Nothing, _
                  Optional ByVal opt As Boolean = True)
    If ws Is Nothing Then
        For Each ws In Application.ActiveWorkbook.Sheets
            EnableWS ws, opt
        Next
    Else
        EnableWS ws, opt
    End If
End Sub
Private Sub EnableWS(ByVal ws As Worksheet, ByVal opt As Boolean)
    With ws
        .DisplayPageBreaks = False
        .EnableCalculation = Not opt
        .EnableFormatConditionsCalculation = Not opt
        .EnablePivotTable = Not opt
    End With
End Sub

答案 1 :(得分:0)

如果公式返回零长度字符串,则将公式结果还原为其值是不够的。您需要使用Range.TextToColumns method快速扫描列,使用固定宽度并将列的值返回到其原始单元格,以使单元格真正空白。

Sub DeleteCol()
    Dim iCOL As Long, sFND As String

    With ActiveSheet
        With .Range(.Cells(1, 1), .Cells(1, 1).SpecialCells(xlLastCell))
            .Value = .Value
        End With
        sFND = "Approve"

        If CBool(Application.CountIf(.Rows(1), sFND)) Then
            iCOL = Application.Match(sFND, .Rows(1), 0)
            If CBool(Application.CountBlank(.Columns(iCOL))) Then
                With .Columns(iCOL)
                    .TextToColumns Destination:=.Cells(1), DataType:=xlFixedWidth, _
                                   FieldInfo:=Array(0, 1)
                    .SpecialCells(xlCellTypeBlanks).EntireRow.Delete
                End With
            End If
        End If
    End With

End Sub

工作表的COUNTBLANK function将在其空白计数中计算零长度字符串,以便我们可以在继续之前确定是否有空白单元格。使用COUNTIF function同样可以确保列标题为&#39;批准&#39;在第一行。