【问题标题】:Delete cells in customized groups instead of entire rows or columns删除自定义组中的单元格,而不是整行或整列
【发布时间】:2015-08-24 17:35:39
【问题描述】:

我有这个代码可以删除整列的单元格。最初我认为它会很好用,后来我意识到如果我这样做,同一列上的有用数据也会被删除。因此,我需要一个代码,它允许我在自己方便的时候删除任何范围的单元格,无论是行还是列

Sub TestDatabase()

Dim rng As range, rngError As range, delRange As range
Dim i As Long, j As Long, k As Long
Dim wks As Worksheet

On Error Resume Next

Set rng = Application.InputBox("Select cells To be deleted", Type:=8)

On Error GoTo 0

If rng Is Nothing Then Exit Sub Else rng.delete

For k = 1 To ThisWorkbook.Worksheets.Count 'runs through all worksheets

  Set wks = ThisWorkbook.Worksheets(k)

  With wks

    For i = 1 To 7 '<~~ Loop trough columns A to G

        '~~> Check if that column has any errors
        On Error Resume Next

        Set rngError = .Columns(i).SpecialCells(xlCellTypeFormulas, xlErrors)

        On Error GoTo 0

        If Not rngError Is Nothing Then
            For j = 1 To 100 '<~~ Loop Through rows 1 to 100
                If .Cells(j, i).Text = "#REF!" Then
                    '~~> Store The range to be deleted
                    If delRange Is Nothing Then
                        Set delRange = .Columns(i)
                        Exit For
                    Else
                        Set delRange = Union(delRange, .Columns(i))
                    End If
                End If
             Next j
         End If

     Next i

  End With

Next k

'~~> Delete the range in one go
If Not delRange Is Nothing Then delRange.delete

End Sub

【问题讨论】:

  • 看起来您的代码删除了给定单元格范围内的值(在单个工作表上),然后检查工作簿中的所有工作表(包括已删除范围的工作表)是否有任何 #REF!错误。如果发现任何错误,也会删除错误单元格中的值/公式。这是正确的和你的意图吗?
  • 是的,除了您提到的部分,它将检查工作簿中的所有参考错误。它实际上循环遍历工作表以同时删除范围和参考错误,而不是一张单张。 @PeterT
  • 您要求能够“在我方便的时候删除任何范围的单元格,无论是行还是列”。您上面的 VBA 代码是否满足您的需求?如果不是,为什么不呢?老实说,我没有看到您声明的目标与您发布的代码之间的联系。
  • 它不允许我只删除行列。那是我的问题。我希望它能够删除任何行或列,而不仅仅是仅列或仅行@PeterT
  • 好的,您可以为您的输入和输出示例发布任何图片。所以,我们可以多想。

标签: vba excel


【解决方案1】:

我认为为了满足您的需求,您只需删除 .Columns() 方法即可。这反过来又带来了新的问题——当你删除一个单元格时,Excel应该以哪种方式移动剩余的单元格?

你可以试试这样的:

If .Cells(j, i).Text = "#REF!" Then
    '~~> Store The range to be deleted
    If delRange Is Nothing Then
        Set delRange = .Cells(j, i)
        '// Exit For <~~ This stops your code adding any more cells to delRange
    Else
        Set delRange = Union(delRange, .Cells(j, i))
    End If
End If

然后当你删除时:

'// Could use xlUp, xlDown, xlToRight or xlToLeft
delRange.delete shift:=xlUp

值得注意的是,由于delRange现在指向一组单元格,可以删除:

  • 仅单元格,使用上述方法。
  • 属于这些单元格的行使用delRange.EntireRow.Delete shift:=xlUp
  • 或属于这些单元格的列,使用delRange.EntireColumn.Delete shift:=xlToLeft

【讨论】:

  • 它工作得很好,但只有一行或只有一列。有什么方法可以删除多行或多列?例如范围 D1 到 E13。因为当我删除该范围时,它又给了我参考错误:/
  • 您的意思是要删除不在delRange 中的其他行或列?
  • 在范围内!我刚刚意识到该程序不会删除列并且给了我很多参考错误。
  • 对,我想我知道你的问题是 - 当你运行此代码时,它是否只删除 一个 行或列,而不是删除范围内的所有行或列?
  • 它成功删除了行,但没有删除列或任何单元格组。相反,它为我选择删除的整个列或组提供了引用错误
【解决方案2】:

虽然我仍然不清楚您的最终目的,但删除任何大小或形状范围都相当简单。就像清除(或删除)所有 #REF! 错误一样。

我建议您选择Peter Thornton's GetInputRange function,它可以解决您使用InputBox 从用户那里获取范围时可能遇到的任何潜在问题。

Option Explicit

Sub Test()
    Dim targetArea As Range
    Dim success As Boolean

    '--- clears only the contents from the currently selected area
    Set targetArea = Application.Selection
    targetArea.ClearContents
    '--- optionally delete the area, but this shifts all the other data into the area
    'targetArea.Delete Shift:=xlShiftUp
    ClearAllRefErrors

    '--- asks for the area to be cleared
    '    uses Peter Thornton's GetInputRange method (http://www.jkp-ads.com/Articles/SelectARange.asp)
    success = GetInputRange(targetArea, "Enter the range to delete:", "Delete Range", _
                           Application.Selection.Address)
    If success Then
        targetArea.ClearContents
        '--- optionally delete the area, but this shifts all the other data into the area
        'targetArea.Delete Shift:=xlShiftUp
        ClearAllRefErrors
    End If
End Sub

Sub ClearAllRefErrors()
    Dim ws As Worksheet
    Dim rangeInUse As Range
    Dim rangeCell As Range

    For Each ws In ThisWorkbook.Sheets
        Set rangeInUse = Application.ActiveSheet.usedRange
        For Each rangeCell In rangeInUse
            If rangeCell = CVErr(xlErrRef) Then
                rangeCell.ClearContents
                '--- optionally delete the cell, but this shifts all the other data
                'rangeCell.Delete Shift:=xlShiftUp
            End If
        Next rangeCell
    Next ws
End Sub

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多