VBA Do(删除列,其中find为true)直到Find为False,然后退出do

时间:2018-04-25 20:14:34

标签: vba loops

我有一个excel文件,其中包含“收入来自Trans”文本,我需要删除整个列。

这是我目前在VBA 2010中的代码,直到没有更多的单元格来自“Trans from Trans”;我不能让它摆脱循环。

知道为什么吗?

Dim rng1 As Range
Dim target1 As String

target1 = "Income From    Trans"
Set rng1 = Cells.Find(What:=target1, _
After:=ActiveCell, _
LookIn:=xlFormulas, _
LookAt:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)

Do Until rng1 Is Nothing
    Cells.Find(What:=target1, After:=ActiveCell, _
        LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, 
SearchDirection _
         :=xlNext, MatchCase:=False, SearchFormat:=False).Activate
ActiveCell.EntireColumn.Delete
Loop

2 个答案:

答案 0 :(得分:0)

检查循环内的搜索结果

Dim rng1 As Range, target1 As String, firstFound As String

target1 = "Income From    Trans"

Set rng1 = Cells.Find(What:=target1, After:=ActiveCell, LookIn:=xlFormulas, _
                      LookAt:=xlPart, SearchOrder:=xlByRows, _
                      SearchDirection:=xlNext, MatchCase:=False)

If Not rng1 Is Nothing Then

    Do

        firstFound = rng1.Address

        Set rng1 = Cells.Find(What:=target1, After:=ActiveCell, LookIn:=xlValues, _
                              LookAt:=xlPart, SearchOrder:=xlByRows, _
                              SearchDirection:=xlNext, MatchCase:=False, _
                              SearchFormat:=False)

        If Not rng1 Is Nothing Then rng1.EntireColumn.Delete

    Loop While Not rng1 Is Nothing And rng1.Address <> firstFound

End If

答案 1 :(得分:0)

您的代码Set rng1 = Cells.Find...会将rng1设置为范围对象,假设它找到您的值。接下来是您的循环,最终会导致rng1被删除。它继续循环,因为即使rng1被删除,它仍然被分配,因此不是Nothing。它以run time error message of 91结尾,因为rng1已设置但已删除。您可以在本地窗口中查看&gt;本地窗口,其类型仍然是Range\Range,即使它实际上已被删除。

您有来自非限定Cells用法的隐式单元格引用。这意味着此代码将在任何工作表恰好是ActiveSheet上运行。当您没有意识到这一点时,隐式引用会产生意想不到的副作用。最好对它们进行完全限定,以便它们所处的工作表没有歧义。我假设ActiveCell属于这个类别,因为你希望它包装删除,直到找不到“Trans from Trans”。

不需要代码.Activate,后跟ActiveCell.,可以通过删除两者来缩短代码,因此它最终为SearchFormat:=False).EntireColum...。通常不需要选择范围对象。加入这两个使你明白你正在做什么。

下面你会发现一个更简单的版本,使用.Find在你的原文中找到第一个实例。之后,它使用.FindNext()继续循环,直到找到所有内容。这最终会退出,因为它在每次删除后设置范围变量found,最后在found删除后删除NothingRemoveColumns包含的参数允许您在不止一张纸上使用此功能。

Sub Test()
    RemoveColumns Sheet1, "Income From    Trans"
End Sub

Sub RemoveColumns(ByVal sheetToSearch As Worksheet, ByVal value As String)
    Dim found As Range
    Set found = sheetToSearch.Cells.Find(What:=value, After:=sheetToSearch.Range("A1"), LookIn:=xlFormulas, _
                                LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
                                MatchCase:=False)
    Do Until found Is Nothing
        found.EntireColumn.Delete
        Set found = sheetToSearch.Cells.FindNext
    Loop
End Sub