Есть ли в Excel VBA более быстрый способ скрыть строки на основе значения ячейки?

У меня есть несколько сводных таблиц на листе с множеством пустых строк для их разделения, чтобы, если кто-то внезапно получит много значений, он не перезаписал сводную таблицу внизу. Но чтобы пользователю не приходилось прокручивать довольно далеко вниз, чтобы увидеть другую сводную таблицу, у меня есть формула в столбце A, которая проверяет, заполнено ли что-либо в каждой строке, а затем написал некоторый VBA, чтобы скрыть строки, которые определила формула: пустой.

Проблема, с которой я столкнулся, заключается в том, что скрытие строк занимает 16 секунд, а это даже не большой диапазон. Есть ли лучший способ сделать это?

For Each cell In Range("A1:A200")
    If cell.Value = "HIDDEN ROW" Then cell.EntireRow.Hidden = True
Next cell

VBA запускается в Worksheet_Change, и я запустил отладку, чтобы определить эту задержку, и результаты показывают:

Временная метка Шаг 06.05.2024 13:22:27 Начинать 06.05.2024 13:22:27 Проверка значения опорной точки завершена 06.05.2024 13:22:27 Проверяет, является ли измененный диапазон фильтрами сводной таблицы. 06.05.2024 13:22:27 Отображает все ячейки 06.05.2024 13:22:27 Очищает фильтры 06.05.2024 13:22:27 Устанавливает фильтры 06.05.2024 13:22:33 Переформатирование цветов в сводках 06.05.2024 13:22:33 Скрытие строк 06.05.2024 13:22:49 Заканчивать

Отфильтровать значение, которое вы хотите скрыть? Возможно, это пригодится

cybernetic.nomad 05.06.2024 14:51
Преобразование HTML-таблицы в профессиональный документ Excel
Преобразование HTML-таблицы в профессиональный документ Excel
Это самый простой способ создания Excel из HTML-таблицы.
Импорт excel в laravel в базу данных
Импорт excel в laravel в базу данных
Здравствуйте, дорогой читатель, в этой статье я расскажу практическим и быстрым способом, как импортировать файл Excel в вашу базу данных с помощью...
0
1
114
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Попробуйте следующее адаптированное решение. Скрытие одной строки за раз занимает много времени. Использование диапазона Union и скрытие их всех одновременно должно быть намного быстрее:

Sub HideRows()
  Dim cell As Range, uRng As Range
  For Each cell In Range("A1:A200")
    If cell.Value = "HIDDEN ROW" Then addToRange uRng, cell
 Next cell
 If Not uRng Is Nothing Then uRng.EntireRow.hiden = True
End Sub

Private Sub addToRange(rngU As Range, rng As Range)
    If rngU Is Nothing Then
        Set rngU = rng
    Else
        Set rngU = Union(rngU, rng)
    End If
End Sub

Я изменил ваше решение здесь, чтобы добавить фиктивный столбец в конец, чтобы: 1. установить константы 2. скрыть строки, а затем 3. удалить фиктивный столбец, ваше решение творит чудеса для пакетных операций со строками/столбцами

Sgdva 05.06.2024 16:12

Это идеально, красиво, компактно и значительно ускоряет процесс. Я надеялся, что мне не придется создавать отдельный модуль вне подпрограммы Worksheet_Change - возможно ли записать все это в одну и ту же подпрограмму?

seaside_escape 05.06.2024 16:55

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

FaneDuru 05.06.2024 17:21

@seaside_escape Не нужно создавать отдельный модуль! Вам следует заменить только код, который вы показываете в своем вопросе, на приведенный выше. Разумеется, скопировав функцию в тот же модуль листового кода. Если что-то еще не ясно, не стесняйтесь попросить разъяснений, конкретно описав проблему, с которой вы столкнулись...

FaneDuru 06.06.2024 08:39

Решение:
Я усовершенствовал подход FaneDuru, превратив его в функцию скрытия/удаления строк или столбцов. Там заявлена ​​экономия времени. Это самое быстрое решение, которое я пробовал, я подчеркнул, что протестировал его с анализом около 150 тысяч строк, скрывая многие из них, и не потею.
Демо:
Код:

Sub Exec_AnalyzeRowsToHide()
Dim ArrRowsToHide() As String
Dim CounterRow As Long
    ReDim ArrRowsToHide(1 To Cells.SpecialCells(xlCellTypeLastCell).Row, 1 To 1)
    For CounterRow = 1 To 200
    If Cells(CounterRow, 1).Value = "HIDDEN ROW" Then ArrRowsToHide(CounterRow, 1) = "Hide"
    Next CounterRow
    Call Exec_DeleteHideRowsOrColumns(ActiveSheet.Name, ArrRowsToHide, True, "Hide")
End Sub
Sub Exec_DeleteHideRowsOrColumns(TxtSheet As String, ArrTxtPlaceholderValues() As String, IsRowsToDo As Boolean, TxtCase As String)
'array parsed need to be like ArrNumRowsColsToDel(CounterArr, 1)
'Example usage for rows
'at least 6 rows used
'Dim arrnum() As String
'    ReDim arrnum(1 To Cells.SpecialCells(xlCellTypeLastCell).Row, 1 To 1)
'    arrnum(2, 1) = "Del": arrnum(4, 1) = "Del": arrnum(6, 1) = "Del"
'    Call Exec_DeleteHideRowsOrColumns(ActiveSheet.Name, arrnum, True,"Del")
'Example usage for columns
'at least 6 columns used
'Dim arrnum() As String
'    ReDim arrnum(1 To Cells.SpecialCells(xlCellTypeLastCell).Column, 1 To 1)
'    arrnum(2, 1) = "Del": arrnum(4, 1) = "Del": arrnum(6, 1) = "Del"
'    Call Exec_DeleteHideRowsOrColumns(ActiveSheet.Name, arrnum, False,"Del")
Dim NumLastRowOrColumn As Long
Dim CounterArr As Variant
Dim ArrDummy() As String
Dim NumRowsOrColsAdded As Long
Dim RangeDataSheet As Range
    With Sheets(TxtSheet) ' 1. With Sheets(TxtSheet)
    If IsRowsToDo = True Then ' 1. If IsRowsToDo = True
    NumLastRowOrColumn = .Cells.SpecialCells(xlCellTypeLastCell).Column + 1
    With .Cells(1, NumLastRowOrColumn).Resize(.Cells.SpecialCells(xlCellTypeLastCell).Row, 1) ' 2. With .Cells(1, NumLastRowOrColumn).Resize(.Cells.SpecialCells(xlCellTypeLastCell).Row, 1)
    On Error Resume Next
    .Value = ArrTxtPlaceholderValues
    Select Case TxtCase
    Case "Del"
    .SpecialCells(xlCellTypeConstants).EntireRow.Delete
    Case "Hide"
    .SpecialCells(xlCellTypeConstants).EntireRow.Hidden = True: .Parent.Columns(NumLastRowOrColumn).Delete
    End Select
    End With ' 2. With .Cells(1, NumLastRowOrColumn).Resize(.Cells.SpecialCells(xlCellTypeLastCell).Row, 1)
    .UsedRange
    Else ' 1. If IsRowsToDo = True
    NumLastRowOrColumn = .Cells.SpecialCells(xlCellTypeLastCell).Row + 1
    With .Cells(NumLastRowOrColumn, 1).Resize(1, .Cells.SpecialCells(xlCellTypeLastCell).Column) ' 2. With .Cells(NumLastRowOrColumn, 1).Resize(1, .Cells.SpecialCells(xlCellTypeLastCell).Column)
    .Value = Application.WorksheetFunction.Transpose(ArrTxtPlaceholderValues): DoEvents
    Select Case TxtCase
    Case "Del"
    .SpecialCells(xlCellTypeConstants).EntireColumn.Delete
    Case "Hide"
    .SpecialCells(xlCellTypeConstants).EntireColumn.Hidden = True: .Parent.Rows(NumLastRowOrColumn).Delete
    End Select
    End With ' 2. With .Cells(NumLastRowOrColumn, 1).Resize(1, .Cells.SpecialCells(xlCellTypeLastCell).Column)
    .UsedRange
    End If ' 1. If IsRowsToDo = True
    End With ' 1. With Sheets(TxtSheet)
End Sub

Другие вопросы по теме