Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Microsoft Office и VBA программирование > Microsoft Office Excel
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 29.09.2010, 18:33   #1
willy
 
Регистрация: 29.09.2010
Сообщений: 4
По умолчанию Отображение строк, где есть хотя бы один пробел

Есть таблица 40000-50000 строк и 10 столбцов.
В ней могут пустые ячейки. Задача в том, чтобы их обнаружить. До этого делали автофильтром по каждому столбцу. Долго и не удобно. Я изучаю VBA всего 4 дня, но нашел способ, что-то типа:

Sub EmptyRows()
Dim oEnd As Integer

Range("A1").Select
oEnd = Selection.End(xlDown).Row

For colIndex = 6 To 6
For rwIndex = 1 To oEnd

With ActiveSheet.Cells(rwIndex, colIndex)
If .Value <> 0 Then
Rows(rwIndex).Hidden = True
End If
End With
Next rwIndex
Next colIndex

End Sub

Но с такой большой таблицей - этот метод работает еще дольше чем автофильтр.

Я знаю есть более быстрые варианты типа ActiveSheet.UsedRange.SpecialCells( xlCellTypeBlanks).Select

но не знаю как показать только те строки, где есть хотя бы одна пустая ячейка
willy вне форума Ответить с цитированием
Старый 29.09.2010, 18:52   #2
nilem
Форумчанин
 
Регистрация: 25.04.2010
Сообщений: 616
По умолчанию

Например, так:
Код:
Dim rng As Range
Application.ScreenUpdating = False
Set rng = Range("A1:A" & Cells(Rows.Count, 1).End(xlUp).Row).Resize(, 10)
With rng
    .EntireRow.Hidden = True
    .SpecialCells(xlCellTypeBlanks).EntireRow.Hidden = False
End With
Application.ScreenUpdating = True
nilem вне форума Ответить с цитированием
Старый 29.09.2010, 20:32   #3
willy
 
Регистрация: 29.09.2010
Сообщений: 4
По умолчанию

Спасибо огромное, добрый человек. Пошел учить матчасть :-)
willy вне форума Ответить с цитированием
Старый 30.09.2010, 07:19   #4
SAS888
Старожил
 
Аватар для SAS888
 
Регистрация: 05.12.2007
Сообщений: 4,180
По умолчанию

С позволения nilem, отмечу, что строка кода, определяющая диапазон
Код:
Set rng = Range("A1:A" & Cells(Rows.Count, 1).End(xlUp).Row).Resize(, 10)
будет некорректна, в случае, если в каком-либо столбце строк больше, чем в столбце "A". Предлагаю в качестве диапазона rng использовать ActiveSheet.UsedRange. Если же таблицу требуется ограничить 10-ю столбцами, то можно использовать
Код:
Set rng = Intersect(ActiveSheet.UsedRange, [A:J])
Чем шире угол зрения, тем он тупее.
SAS888 вне форума Ответить с цитированием
Старый 30.09.2010, 07:54   #5
nilem
Форумчанин
 
Регистрация: 25.04.2010
Сообщений: 616
По умолчанию

Код:
Set rng = Intersect(ActiveSheet.UsedRange, [A:J])
Согласен, так более универсально.
...хотя вчера ведь думал об этом. "Если в каком-либо столбце строк больше, чем в столбце "A"", то, значит, соответствующие ячейки в ст. А пустые, а их нужно оставить открытыми. И тогда
Set rng = Range("A1:A" & Cells(Rows.Count, 1).End(xlUp).Row).Resize(, 10)
будет даже эффективнее.

Последний раз редактировалось nilem; 30.09.2010 в 08:21.
nilem вне форума Ответить с цитированием
Старый 30.09.2010, 09:26   #6
SAS888
Старожил
 
Аватар для SAS888
 
Регистрация: 05.12.2007
Сообщений: 4,180
По умолчанию

Согласен. Для решения данной задачи это вполне устраивает.
Но есть еще один вопрос:
Автор говорит, что
Цитата:
Есть таблица 40000-50000 строк...
и никак не оговаривает, каким образом она может быть заполнена.
Однако, пусть, например, столбец "A" заполнен, начиная с 1-й строки и пусть через каждую строку встречается пустое значение. В этом случае, применение метода SpecialCells даст ошибочный результат. Для SpecialCells количество несвязанных диапазонов ограничено (8192). Для примера, попробуйте на пустом листе выполнить макрос:
Код:
Sub Test()
    Dim i As Long, m As Long, a(): Application.ScreenUpdating = False
    m = InputBox("Количество строк"): [A:A].Delete: ReDim a(1 To m, 1 To 1)
    For i = 1 To UBound(a, 1) Step 2: a(i, 1) = i: Next
    Range("A1:A" & m).Value = a
    [A:A].SpecialCells(xlCellTypeBlanks).Select
End Sub
где m - это количество заполняемых строк в столбце "A" (массив примененяется только из-за экономии времени и проверка введенного значения переменной m отсутствует). Попробуйте запустить макрос и задать m = 16380. А затем, например, m = 16390. Результат очевиден.

P.S. Для 10-и столбцов такая ситуация еще более возможна.
Чем шире угол зрения, тем он тупее.

Последний раз редактировалось SAS888; 30.09.2010 в 09:30.
SAS888 вне форума Ответить с цитированием
Старый 30.09.2010, 13:11   #7
nilem
Форумчанин
 
Регистрация: 25.04.2010
Сообщений: 616
По умолчанию

Не знал о таком ограничении, спасибо. Для интереса попробовал в 2010 - выделяет до 50000 несвязанных ячеек (дальше не стал экспериментировать).
И что же теперь делать нашему ТС? Вот что пришло в голову (как-то сразу пришло и прочно засело)
Код:
Sub ToHideEmptyCells()
Dim x, i As Long, j As Long, y()
Application.ScreenUpdating = False
x = Range("A1:A" & Cells(Rows.Count, 1).End(xlUp).Row).Resize(, 10).Value

With CreateObject("Scripting.Dictionary")
'With New Dictionary     ' здесь нужен Reference на MS Scripting Runtime
    For i = 1 To UBound(x, 1)
        For j = 1 To 10
            If IsEmpty(x(i, j)) Then
            If Not .Exists(i) Then .Add Key:=i, Item:=0
            End If
        Next j, i: y = .Keys
End With
For i = 0 To UBound(y)
    Cells(y(i), 1).EntireRow.Hidden = True
Next i
Application.ScreenUpdating = True
End Sub
Не слишком ли?
nilem вне форума Ответить с цитированием
Старый 30.09.2010, 13:26   #8
EugeneS
Форумчанин
 
Регистрация: 06.08.2009
Сообщений: 472
По умолчанию

вариант с использованием библиотеки ADO:

Предварительная настройка: Excel - Ctrl+F11 - VB redaktor: Tools – References: подключите библиотеку Microsoft ActiveX Data Objects 2.8 Library

см. вложение
Вложения
Тип файла: zip Empty.zip (383.0 Кб, 9 просмотров)
EugeneS вне форума Ответить с цитированием
Старый 30.09.2010, 13:44   #9
nilem
Форумчанин
 
Регистрация: 25.04.2010
Сообщений: 616
По умолчанию

Цитата:
Сообщение от nilem Посмотреть сообщение
...Не слишком ли?
Конечно, слишком. Вот:
Код:
Sub ToHideEmptyCells2()
Dim x, i As Long, j As Long
Application.ScreenUpdating = False
x = Range("A1:A" & Cells(Rows.Count, 1).End(xlUp).Row).Resize(, 10).Value
For i = 1 To UBound(x, 1)
    For j = 1 To 10
        If IsEmpty(x(i, j)) Then
            Cells(i, 1).EntireRow.Hidden = True
            Exit For
        End If
Next j, i
Application.ScreenUpdating = True
End Sub
nilem вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Матрица. Посчитать количество строк, содержащих хотя бы один нулевой элемент Геля007 Общие вопросы C/C++ 0 02.06.2010 16:17
Как заменить обычний пробел на неразрывный пробел Jaroslav Microsoft Office Excel 2 05.05.2010 11:57
Дано предложение. Между словами предложения один пробел, а после последнего слова точка. Vadim123456 Помощь студентам 0 01.05.2010 23:28
Интерестно а есть ли здесь хотя-бы бывшие медики vasek123 Свободное общение 12 09.06.2009 14:29