Приветствую! Хотел использовать дополнительный столбец для быстрого фильтра, но не тут-то было…
Задача: Вставить массив с элементами «"1"» (для фильтруемых) и «Empty» в столбец, содержащий скрытые фильтром строки Проблема: Вставка происходит некорректно Чтобы повторить "ошибку", запустите макрос при скрытых "0" в первом столбце (строки без заливки)
Выход: • проще, но дольше — вставлять "1" в каждую ячейку в цикле • сложнее, но быстрее — запоминать адреса ячеек в массив, передавать в функцию для нарезки на блоки и уже в цикле по блокам ячеек заполнять значения
Проблема очистки/заполнения скрытых ячеек была разобрана в этой теме, но тут другая ситуация
Option Explicit
'===========================================================================================
Sub iFilter()
Dim tbl As ListObject
Dim arr, tx$, r&
arr = [a2:a23].Value2
For r = 1 To UBound(arr, 1)
' If arr(r, 1) <> 0 Then arr(r, 1) = 1 ' скрин 2
If arr(r, 1) <> 1 Then arr(r, 1) = Empty ' скрин 3
Next r
On Error Resume Next: ActiveSheet.ShowAllData: On Error GoTo 0
Set tbl = ActiveSheet.ListObjects(1)
tbl.ListColumns(2).DataBodyRange.ClearContents
tbl.Range.AutoFilter Field:=1, Criteria1:="<>0", Operator:=xlFilterValues
'With Intersect(tbl.DataBodyRange, tbl.Range): End With
tbl.ListColumns(2).DataBodyRange.Value2 = arr
End Sub
'===========================================================================================
'Set tbl = ActiveSheet.ListObjects(1)
'
' Dim x, y, ApEv, ApSc
' With tbl.DataBodyRange
' x = Selection.Address
' With Range(.Address)
' y = .Offset(-1, 0).Resize(.Rows.Count + 1).Address
' End With
' If Not Intersect(Range(y), Selection) Is Nothing Then
' ApEv = Application.EnableEvents
' ApSc = Application.ScreenUpdating
' Application.EnableEvents = False
' Application.ScreenUpdating = False
' Cells(.Row + .Rows.Count + 1, 1).Activate
' Application.EnableEvents = ApEv
' Application.ScreenUpdating = ApSc
' End If
' End With
'
'tbl.ListColumns(2).DataBodyRange.Value2 = arr
'
' With tbl.DataBodyRange
' If Intersect(Range(y), Selection) Is Nothing Then
' ApEv = Application.EnableEvents
' ApSc = Application.ScreenUpdating
' Application.EnableEvents = False
' Application.ScreenUpdating = False
' Range(x).Select
' Application.EnableEvents = ApEv
' Application.ScreenUpdating = ApSc
' End If
' End With
Кто знает, почему так происходит и знаете ли вы более простые и/или быстрые способы добиться того же результата
UPD: Лучшее решения в рамках задачи «Фильтр с помощью дополнительного столбца
Запоминаем существующий фильтр "Дофильтровываем" существующий фильтр новым списком значений Снимаем фильтр Выгружаем массив критериев в столбец фильтра Быстро фильтруем по одному значению/критерию
Option Explicit
'===========================================================================================
Sub iFilter()
Dim tbl As ListObject
Dim aData, aFilt, tx$, r&, f As Boolean
Set tbl = ActiveSheet.ListObjects(1)
tbl.ListColumns(2).DataBodyRange.Value2 = "old"
aData = tbl.ListColumns(1).DataBodyRange.Value2
aFilt = tbl.ListColumns(2).DataBodyRange.Value2
For r = 1 To UBound(aData, 1)
f = (aFilt(r, 1) = "old")
If f Then f = (aData(r, 1) = 2 Or aData(r, 1) = 3)
If f Then f = False: aFilt(r, 1) = "f" Else aFilt(r, 1) = Empty
Next r
Application.ScreenUpdating = False
On Error Resume Next: ActiveSheet.ShowAllData: On Error GoTo 0
tbl.ListColumns(2).DataBodyRange.Value2 = aFilt
tbl.Range.AutoFilter Field:=2, Criteria1:="f", Operator:=xlFilterValues
tbl.ListColumns(2).DataBodyRange.ClearContents
Application.ScreenUpdating = True
End Sub
'===========================================================================================
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
bedvit, неплохо, но, если пользователь применил фильтр по другим полям, то они тоже скинутся, а это нехорошо
Пример: пользователь отфильтровал диапазон цен, а потом хочет отфильтровать поставщиков Если сбросить, то он просто увидит поставщиков и придётся снова фильтровать по ценам - то есть фильтр ЗАМЕНИТСЯ В моём варианте фильтр ДОБАВИТСЯ и всё будет ОК
Если бы вариант с резкой адреса был медленный, то я бы таки сделал, но он вполне шустрый, так что можно и позаботиться о бедных пользователях
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Можно попробовать так. См. файл. Главная идея: на момент вставки массива на лист - убрать выделение с умной таблицы. На моём Excel2010 х32, Win7 работает. Но объяснить, почему - не могу.
tolikt, работает, вроде… А как вы сделали, если не понимаете принцип?) Использовать нельзя пока непонятен механизм работы
Цитата
tolikt: Главная идея: на момент вставки массива на лист - убрать выделение с умной таблицы
Тогда зачем СТОЛЬКО кода
Код
Option Explicit
'===========================================================================================
Sub iFilter()
Dim tbl As ListObject
Dim arr, r&
arr = [a2:a23].Value2
For r = 1 To UBound(arr, 1)
' If arr(r, 1) <> 0 Then arr(r, 1) = 1 ' скрин 2
If arr(r, 1) <> 1 Then arr(r, 1) = Empty ' скрин 3
Next r
Set tbl = ActiveSheet.ListObjects(1)
Dim x, y, ApEv, ApSc
With tbl.DataBodyRange
x = Selection.Address
With Range(.Address)
y = .Offset(-1, 0).Resize(.Rows.Count + 1).Address
End With
If Not Intersect(Range(y), Selection) Is Nothing Then
ApEv = Application.EnableEvents
ApSc = Application.ScreenUpdating
Application.EnableEvents = False
Application.ScreenUpdating = False
Cells(.Row + .Rows.Count + 1, 1).Activate
Application.EnableEvents = ApEv
Application.ScreenUpdating = ApSc
End If
End With
tbl.ListColumns(2).DataBodyRange.Value2 = arr
With tbl.DataBodyRange
If Intersect(Range(y), Selection) Is Nothing Then
ApEv = Application.EnableEvents
ApSc = Application.ScreenUpdating
Application.EnableEvents = False
Application.ScreenUpdating = False
Range(x).Select
Application.EnableEvents = ApEv
Application.ScreenUpdating = ApSc
End If
End With
End Sub
'===========================================================================================
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Я в Excel около 80% делаю того, что не понимаю и уже никогда не пойму. Просто делаю по аналогии с использованием многолетнего опыта и пока ещё не полностью высохшими мозгами...
tolikt, спасибо - я протестирую вариант) а откуда вы его взяли?)
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Из своей головы. Просто потыкал туда-сюда, позапускал макрос так и сяк, придумал для себя некую причину глюка и набросал код, чтоб его обойти. Но ещё раз: глюк обойдён, но почему он возникает - мне не ясно.
tolikt, я попытался отловить, но не вышло Добавил ваш код под спойлер в шапке темы и автоматизировал пример (установка фильтра, очистка диапазона под вставку)
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Да, каюсь: я увлёкся разными вариантами условий, при которых может выполняться код. Хотя для объяснения могло хватить одной строки или даже просто описание Главной идеи. Всё остальное может быт доработано исходя из конкретных условий.
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Да, не сработает. Но это если прямо в коде применить фильтр "<>0" к столбцу А. В первоначальном варианте в коде фильтра не было и всё работало нормально, если активная ячейка была за пределами умной таблицы. Ещё раз: причина глюка непонятна, но её можно обойти, активировав ячейку сбоку и в коде не применять фильтр. Метод обхода глюка плох тем, что непонятно, в каком месте и почему он ещё вылезет, ибо указанный в примере код, думаю, это часть большого кода. Если прямо в коде нужно применять фильтр, то можно воспользоваться советом bedvit #2. Но там придётся копать сам автофильтр и, например, тему Получение массива критериев из автофильтра excel
устанете) Есть специальный столбец для фильтра, так что можно в его видимые ячейки "запомнить" текущий фильтр на момент применения макрофильтра - это легко Завтра прикин
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Jack Famous, а как лучшее решение решает поставленную задачу - вставить массив с элементами «"1"» (для фильтруемых) и «Empty» в столбец, содержащий скрытые фильтром строки при скрытых "0" в первом столбце? На первый взгляд задача одна, лучшее решение делает другое
New, а что же ты так выборочно цитируешь? Написано же Лучшее решения в рамках задачи «Фильтр с помощью дополнительного столбца» Потому и вынес в отдельный спойлер
Тема другая, однако создана тема как раз из этой задачи. Приём на вопрос темы не отвечает (скорее всего, варианты все и так описаны), однако он очень рядом и потому прикреплён
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄