Удаление ячеек в найденном диапазоне со значением 0,00% - PullRequest
0 голосов
/ 05 февраля 2020

У меня проблема. Я написал код, чтобы найти и выбрать второй столбец в таблице сразу под заголовком «Ассоциация». Однако следующим шагом будет go через выбранные ячейки / диапазон, выделите все строки со значением 0,00% и затем удалите их.

Для этого я написал следующее:


'Setting Variables

    Dim cell As Range
    Dim rngData As Range

'Selecting Range to go through and re-formatting

    Sheets("Allocations").Select
    Columns("A:A").Select
    Selection.Find(What:="Association", After:=ActiveCell, LookIn:=xlFormulas _
        , LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
        MatchCase:=False, SearchFormat:=False).Activate
    Range("A19").Select
    Range(Selection, Selection.End(xlDown)).Select
    Selection.EntireRow.Hidden = False
    ActiveCell.Offset(0, 1).Range("A1").Select
    Range(Selection, Selection.End(xlDown)).Select
    Selection.Style = "Percent"
    Selection.NumberFormat = "0.0%"
    Selection.NumberFormat = "0.00%"

'Attempting to delete just cells within current selection with a value of Zero

    Set rngData = Selection
    For Each cell In rngData
        If cell.Value = 0 Then
        Rows.Delete
        End If
    Next cell

End Sub

Прямо сейчас он просто удаляет все из рабочей книги, что ... не идеально, ха-ха.

Ценю любую помощь, которую я могу получить по этому поводу, я много гуглил и сейчас тяну мои волосы!

Спасибо

1 Ответ

1 голос
/ 05 февраля 2020

Хорошей практикой является явная квалификация объекта, с которым вы работаете. Это причудливый способ сказать "определить объект"

Возможно, вы уже читали что-то подобное раньше, и я уверен, что вы будете читать что-то подобное снова и снова. Проблема с вашим кодом оказывается отличным примером того, почему это хорошая практика.

Рассмотрим фразу: «это хорошая практика».

Что такое Я говорю или, что более важно, на что я намекаю?

Я не говорю прямо, что вы обязаны квалифицировать объект; на самом деле, я неявно говорю, что у вас есть выбор, что это не требование.

Это именно то, что вы сделали с этой строкой: Rows.Delete

Rows является свойством объекта рабочего листа, и свойства не существуют в вакууме, они всегда сопровождают объект, которому они принадлежат. Вы не указали явно объект рабочего листа, скорее, вы неявно разрешили VBA использовать объект рабочего листа по умолчанию.

Итак, вы неявно написали следующее: ActiveSheet.Rows.Delete

И это именно то, что ваш макрос делает, он удаляет строки активного листа.

Я рекомендую запустить код после замены его на эту строку: cell.EntireRow.Delete

Если вы сделаете это, вы должны заметить что-то смешное , Если раньше вы последовательно удаляли каждую строку на рабочем листе, то теперь вы непоследовательно удаляете всего 50% строк, которые хотите удалить.

Почему? Мы исправили это, что случилось?

Удаление элементов из индексированного списка - распространенная проблема для новых программистов. Использовать настольную игру в качестве аналогии. Вы запланировали всю игру. Вы делаете один ход, затем другой и так далее. Но вы полностью пренебрегли своим противником. Они тоже по очереди!

Позвольте мне спросить вас, если вы удалите первую строку на рабочем листе, с какого номера строки начнется рабочий лист?

Итак, что происходит, вы удаляете строку, и Excel сразу же сдвигает строки вверх со строки 2, становясь строкой 1. Поэтому, когда вы переходите к строке 2, вы фактически пропускаете строку 2 и приземляетесь в 3.

Хорошая новость заключается в том, что эту проблему легко решить. Просто go назад. В случае таблицы это означает запуск с последней строки и переход к первой строке.

Это можно сделать с помощью For l oop, используя необязательный параметр Step со значением из -1.

Например (половина каламбура предназначена):

For I = objTable.Listrows.Count to 1 Step -1

К сожалению, вы должны использовать итератор индексации. For Each не работает Step.

Теперь ваш код должен работать, как и ожидалось.

Но прежде чем класс закрывается, давайте поговорим о Select.

В слово: «Не»

Как и в «Вы не макро-рекордер, поэтому не пишите такой код». Это сделает ваш код медленным. Это по-прежнему делает ваш код более подверженным ошибкам и ошибкам.

Так что у вас есть. Ваша домашняя работа состоит в том, чтобы научиться явно квалифицировать объекты, чтобы избежать неявного использования ActiveSheet. Как использовать Step в For l oop. И как избежать использования Select

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...