VBA Do (удалить столбец, где find - true), пока Find - false, затем выйти do - PullRequest
0 голосов
/ 25 апреля 2018

У меня есть файл Excel с текстом «Доход от транс», где мне нужно будет удалить весь столбец.

Это мой текущий код в VBA 2010, который работает до тех пор, пока не останется больше ячеек с «Доходом от транс»;Я не могу заставить его выйти из цикла.

Есть идеи почему?

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 голосов
/ 25 апреля 2018

Ваш код Set rng1 = Cells.Find... установит rng1 в качестве объекта диапазона, при условии, что он найдет ваше значение.Далее идет ваш цикл, который в конечном итоге приведет к удалению rng1.Он продолжает цикл, потому что, даже если rng1 удалено, оно все равно было назначено и, следовательно, не Nothing.Он заканчивается сообщением об ошибке времени выполнения 91 , поскольку rng1 было установлено, но удалено.В окне локальных окон View> Locals Window вы можете видеть, что его тип по-прежнему Range\Range, даже если он фактически был удален.

У вас есть неявные ссылки на ячейки из неквалифицированного использования Cells.Это означает, что этот код будет выполняться на любом рабочем листе ActiveSheet.Неявные ссылки могут иметь непреднамеренные побочные эффекты, когда вы этого не понимаете.Лучше полностью их квалифицировать, чтобы не было двусмысленности относительно того, на каком листе они находятся.Я предполагаю, что ActiveCell тоже попадает в эту категорию, так как вы хотите, чтобы он удалялся, пока «Income from Trans» больше не будет найден.

Код .Activate, за которым следует ActiveCell., ненеобходимо и может быть сокращено, удалив оба, так что это заканчивается как SearchFormat:=False).EntireColum....Выбор объекта диапазона обычно не требуется.Объединение этих двух компонентов делает очевидным, что вы делаете.

Ниже вы найдете более простую версию, которая использует .Find в вашем оригинале для поиска первого экземпляра.После этого он использует .FindNext () для продолжения цикла, пока все не будут найдены.Это в конечном итоге завершается, потому что он устанавливает переменную диапазона found после каждого удаления, в конечном итоге оставляя found как Nothing после того, как оно было удалено последним.У RemoveColumns есть параметры, которые позволяют использовать его не только на одном листе.

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
0 голосов
/ 25 апреля 2018

Проверьте результаты поиска также внутри цикла


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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...