Страницы: 1
RSS
Выделение не связанных диапазонов (строки) - VBA
 
Как выделить по условию (удалить разом) несколько тысяч строк не связанных между собой.
Ребят столкнулся с одной интересной особенностью.
Код
Sub ВыделитьСтроки2() 'не работает
Dim строка, строки
     For строка = 52 To 1 Step -1 'если For строка = 51 To 1 Step -1  - работает
        If Cells(строка, 1) <> "Баранова О.В." Then
               If строки = "" Then строки = строки & строка & ":" & строка Else строки = строки & "," & строка & ":" & строка
        End If
     Next строка
     
Debug.Print строки
Range(строки).Select
End Sub

Если For строка = 52 To 1 Step -1-не работает 'если  строка = 51 To 1 Step -1  - работает.
Видимо есть ограничение в коли-ве не связанных диапазонов? Хотя если делать через фильтр, и выделение через видимые ячейки - диапазонов по-моему да же больше.
Возникает вопрос - как без фильтра (выделения видимых ячеек), сортировки, программно выделить все строки по условию, когда строк более тысячи?
Немного гуглил, но мало чего нашел, решил может не только мне интересно, пусть будет на Планете.
От меня всем, кто заинтересовался + в карму и большое спасибо за разъяснение :)
Изменено: bedvit - 11.09.2015 15:43:11
«Бритва Оккама» или «Принцип Калашникова»?
 
bedvit, строка-аргумент Range обрезается до 256 символов. Об'единяйте сами диапазоны, а не их адреса: поищите по форуму Union.
Или комбинируйте: копите строку, пока ее длина не превысит, скажем, 240, и добавляйте диапазон с этим адресом, очищайте строку и т.д.
Изменено: Казанский - 11.09.2015 13:02:12
 
У меня оба модуля отработали.
Ну и опять же, какова цель такого выделения? Может есть другое решение?
 
StepanWolkoff, а поставьте, например "строка = 100", отрабатывает? Цель провести одни действия сразу со всем массивом. т.к. нужно удалить эти строки, а данных много и построчно удаляются дольше, чем одним разом (удаляется вся строка, а не данные со строки).
«Бритва Оккама» или «Принцип Калашникова»?
 
Казанский, хороший совет, сейчас попробую через Union.
«Бритва Оккама» или «Принцип Калашникова»?
 
Почитайте http://www.planetaexcel.ru/forum/index.php?PAGE_NAME=message&FID=1&TID=69336&TITLE_SEO=69336-skryt-s...
На днях возникал такой же вопрос. В последнем посте реализовано как набрать большое количество не смежных строк для удаления с книги.
 
TSN, я так понял по вашей сылке, там как раз реализуется принцип, о котором писал Казанский. в циклах - обрезается по 240 символов в строке. Как вариант неплох, но хочу попробовать и через Union. У меня строки не скрываются, а удаляются, а это очень долго :), все же хотелось разом удалить.
Изменено: bedvit - 11.09.2015 14:48:53
«Бритва Оккама» или «Принцип Калашникова»?
 
bedvit, если строки удаляются, то в доп. столбце поставьте им признак удаления, например, символ "-" или 0, отсортируйте по нему так, чтобы удаляемое было внизу таб. и удаляйте одним массивом строк без разрывов.

Формула массива (ФМ) вводится Ctrl+Shift+Enter
Memento mori
 
Цитата
bedvit написал: обрезается по 240 символов в строке
Нет не обрезается по 240 символов, набирается Range из несвязанных строк, а 240 - это контроль Range до 256 символов для Ексель 2010  т.к. при переполнении более 256 символов возникает ошибка 1004. Удалить, вырезать, скрыть строки не имеет значения. Вариант рабочий достаточно понять принцип формирования  Range и доработать под свои нужды.
Если реализуете через Union выложите решение, интересно посмотреть.
Цитата
Немного гуглил, но мало чего нашел
Я Вам показал готовое решение (которое нужно всеголишь доработать под себя) и Вы его не увидили, поэтому в дебрях инета ничего и не нашли.  ;)
Изменено: TSN - 11.09.2015 15:01:03
 
TSN, ваше решение прочитал, вполне хороший вариант- спасибо! Много полезного узнал.
Вот допилил свой вариант, покороче - через Union, представляю на ваш, так сказать, суд.
Код
Sub ВыделитьСтроки3() 'выделить все строки не содержащие значение "Баранова О.В." с 1 по 3000
Dim строка As LongPtr
Dim строки As Range
Dim строки2 As Range

     For строка = 3000 To 1 Step -1
        If Cells(строка, 1) <> "Баранова О.В." Then Set строки = Range(Cells(строка, 1), Cells(строка, Columns.Count))
            If строки2 Is Nothing Then Set строки2 = строки Else Set строки2 = Union(строки2, строки)
     Next строка
     
Debug.Print строки2.Address
строки2.Select
End Sub
Изменено: bedvit - 11.09.2015 15:13:36
«Бритва Оккама» или «Принцип Калашникова»?
 
JayBhagavan, к сожалению сортировать не могу, там условное форматирование, примечания, формулы и т.д. короче гемор. Только через удалением со сдвигом вверх выходит корректнее всего.
«Бритва Оккама» или «Принцип Калашникова»?
 
Все работает на Вашем примере отлично. Заменил последнюю строку кода на строки2.Delete отработало удаление строк без проблем. Только Debug.Print строки2.Address  закомментируйте будет пошустрей работать.
Изменено: TSN - 11.09.2015 15:19:07
 
TSN, да, это я специально вывел, для отслеживания адресов (для участников форума). В рабочем варианте задокументировано. Спасибо)
Для удаления я последнюю строку поменял на
Код
строки2.Delete Shift:=xlUp '(со свигом вверх)
Изменено: bedvit - 11.09.2015 15:26:15
«Бритва Оккама» или «Принцип Калашникова»?
 
Я бы проверку добавил:
Код
If Not строки2 Is Nothing Then строки2.Delete
и вот это:
Код
Set строки = Range(Cells(строка, 1), Cells(строка, Columns.Count))
можно записать проще:
Код
Set строки = Cells(строка, 1).EntireRow
или
Код
Set строки = Rows(строка)
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
The_Prist, дельные замечания. Единственное если нужно выделять\удалять не всю строку, а например 10 первых столбцов можно оставить
Код
Set строки = Range(Cells(строка, 1), Cells(строка, 10))
Добавил проверку на пустые строки в условия отбора Range (здесь каждый решает сам, нужны ли ему пустые строки/диапазоны)
Если построчно, то вот вариант через Union, с советами от The_Prist,
Код
Sub ВыделитьСтроки() 'выделить/удалить все НЕ пустые строки не содержащие значение "Баранова О.В."
Dim строка As LongPtr
Dim строки As Range
Dim строки2 As Range

     For строка = 3000 To 1 Step -1
        If Cells(строка, 1) <> "Баранова О.В." And Cells(строка, 1) <> "" Then Set строки = Rows(строка)
            If строки2 Is Nothing Then Set строки2 = строки Else Set строки2 = Union(строки2, строки)
     Next строка
 
'Debug.Print строки2.Address 'посмотреть диапазоны адресов
If Not строки2 Is Nothing Then строки2.Select 'выделить
'If Not строки2 Is Nothing Then строки2.Delete Shift:=xlUp 'удалить со свигом вверх
End Sub
Изменено: bedvit - 11.09.2015 16:05:03
«Бритва Оккама» или «Принцип Калашникова»?
 
Цитата
bedvit написал:
с советами от The_Prist
с советом. Более важная часть как раз про Is Nothing. Т.к. если не будет ни одного соответствия условию и строки2 будет пустым - получите ошибку.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
The_Prist, понял, не обратил сразу внимания. Это в случаях, когда например, пустой столбец с условиями. Так бывает редко, но все равно добавил проверку. Спасибо! см.выше.
Изменено: bedvit - 11.09.2015 16:44:28
«Бритва Оккама» или «Принцип Калашникова»?
Страницы: 1
Наверх