#excel #vba #loops #find
#excel #vba #циклы #Найти
Вопрос:
Я работаю над макрокомандой для просмотра биржевых данных. Когда на заданную дату данные недоступны, в этих строках отображаются «-«. Мне нужно удалить эти строки. Я придумал макрос, который удаляет первую найденную строку. Мне нужно продолжать, пока все строки с «-» не будут удалены.
Как я могу сделать это с помощью цикла Do Until?
Sub removejank()
'
' removejank Macro
Cells.Find(What:="-", After:=ActiveCell, LookIn:=xlFormulas2, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=False).Activate
If ActiveCell.Value = "-" Then
Rows(ActiveCell.Row).Delete
End If
End Sub
Комментарии:
1. Каково форматирование ячеек, содержащих
-
? Итак, это фактический текст-
или это результат формата учета или валюты, где ввод a0
будет отображаться как-
?2. И в каких столбцах будут эти ячейки? Редактировать: я вижу, что, по сути, это целая строка данных. Итак, если бы вы только посмотрели, например, на столбец A, этого было бы достаточно? (Мы можем выполнить поиск по всем столбцам, но ограничение до 1 может немного ускорить ваш код).
3. «-» — это фактический текст, за ним нет формул или вычислений. Данные структурированы так, чтобы иметь отдельные столбцы для даты, открытия, максимума, минимума, закрытия, объема конкретной акции. Если какая-либо информация отсутствует, все столбцы от B до G будут содержать этот знак «-«. Итак, да, если бы мы проверили только любой отдельный столбец от B до G, этого было бы достаточно, чтобы определить, что строка должна быть удалена.
Ответ №1:
Существует множество возможных способов перебора и удаления строк.
В вашем примере использование Activate
значительно замедляет время выполнения при циклической обработке данных. .Activate
почти полностью можно избежать практически при любых обстоятельствах. Очевидно, я вижу, что то, что вы сделали, было сделано с помощью записи макросов, поэтому понятно, что это там.
В любом случае, попробуйте следующий код. Это просматривается только в столбце A. Если вам нужно посмотреть в другом столбце, то измените «1» в этой строке:
If .Cells(r, 1).Value = "-" Then
К столбцу #, в который вы хотите заглянуть. Кроме того, вам, вероятно, потребуется изменить имя листа в этой строке:
With ThisWorkbook.Worksheets("Sheet3")
чтобы соответствовать имени листа, в котором вы хотите запустить код.
Итак, способ, которым работает этот метод из многих существующих методов, заключается в том, что вы будете перебирать каждую строку в столбце A с помощью For r = 1 ...
. На каждой итерации цикла вы просматриваете значение ячейки. Если оно равно -
, то оператор If имеет значение true и продолжает добавлять ячейку в наш специальный диапазон, который мы назвали delRng
. На самом деле вы пока не удаляете строку, а только отслеживаете их в этом диапазоне.
После завершения вы возьмете все отдельные ячейки в delRng
и, используя .EntireRow
свойство, удалите их все сразу. Как правило, это быстрее, чем удалять строки по одной за раз.
Public Sub RemoveJunk()
Dim delRng As Range, r As Long
With ThisWorkbook.Worksheets("Sheet3")
For r = 1 To .Cells(.Rows.Count, 1).End(xlUp).Row
If .Cells(r, 1).Value = "-" Then
If delRng Is Nothing Then
Set delRng = .Cells(r, 1)
Else
Set delRng = Union(delRng, .Cells(r, 1))
End If
End If
Next r
End With
If Not delRng Is Nothing Then delRng.EntireRow.Delete
End Sub
Комментарии:
1. большое вам спасибо за это потрясающее объяснение. Я немедленно попробую это!
2. единственное, что мне нужно было изменить, это первый отступ If для ссылок на ячейки (r, 2), потому что знаки «-» будут отображаться только в столбцах от B до G. В остальном все работает отлично. Я пытался решить это с помощью какого-то цикла поиска, когда оказывается, что то, как вы это сделали, намного проще! Я действительно следую вашей логике, просто я не видел некоторые методы и другие тонкости, такие как Объединение, например, но я все еще учусь. Мы высоко ценим вашу помощь