При работе с обычными (толстыми) формами в 1С разработчики часто сталкиваются с неприятным визуальным эффектом: при смене закладок или программном изменении фильтров табличная часть начинает «моргать». В этот момент система сначала отображает все строки без фильтра, а затем резко скрывает ненужные. Если в таблице более 50-100 строк, этот процесс становится заметным и раздражает пользователя. В этой статье мы подробно разберем причины такого поведения платформы и изучим несколько эффективных способов реализации плавного переключения отборов.
Сбросить()Разберем ситуацию, с которой столкнулся автор темы. Традиционный подход к обновлению фильтров часто выглядит так:
ЭлементыФормы.ТЧ.ОтборСтрок.Сбросить();
ЭлементыФормы.ТЧ.ОтборСтрок.Заказчик.Установить(ТекущийЗаказчик);
ЭлементыФормы.ТЧ.ОтборСтрок.Закрыт.Установить(флЗакрытия);
Проблема кроется в методе Сбросить(). Как только вызывается эта команда, платформа 1С мгновенно дает сигнал графической оболочке: «Отбор снят, покажи всё, что есть в коллекции». Табличное поле немедленно перерисовывается. Следующие строки кода устанавливают новые условия, и платформа вынуждена выполнять перерисовку еще раз. Именно этот промежуточный этап «показать всё» и создает эффект мерцания.
Важный нюанс: даже если вы не используете Сбросить(), но меняете несколько полей отбора через Установить(), каждое такое изменение может инициировать отдельное обновление интерфейса.
Наиболее эффективный способ, предложенный в обсуждении, — это полный отказ от метода Сбросить(). Вместо этого мы будем обращаться к каждому элементу коллекции Отбор и напрямую управлять его состоянием. Рассмотрим, как реализовать этот алгоритм правильно.
Проанализируем программный код, который позволяет избежать лагов:
// Получаем коллекцию отборов напрямую
Отбор = ЭлементыФормы.ТЧ.ОтборСтрок;
// Проходим циклом по всем доступным полям отбора
Для Каждого ЭлементОтбора Из Отбор Цикл
Если ЭлементОтбора.Имя = "Заказчик" Тогда
ЭлементОтбора.Значение = ТекущийЗаказчик;
ЭлементОтбора.Использование = Истина;
ИначеЕсли ЭлементОтбора.Имя = "Закрыт" Тогда
ЭлементОтбора.Значение = флЗакрытия;
ЭлементОтбора.Использование = Истина;
Иначе
// Все остальные фильтры, которые могли быть установлены ранее, отключаем
ЭлементОтбора.Использование = Ложь;
КонецЕсли;
КонецЦикла;
В чем преимущество этого метода? Мы не сбрасываем состояние всей коллекции целиком. Мы последовательно перенастраиваем параметры каждого поля. Платформа 1С в обычных формах более стабильно обрабатывает изменение свойства Использование, чем полную очистку коллекции.
Выясним еще одну важную деталь. Если вы все же предпочитаете обращаться к полям отбора по именам, крайне важно соблюдать последовательность установки свойств. Посмотрим на два варианта:
Неправильно: сначала включаем использование, потом меняем значение.
Отбор.Заказчик.Использование = Истина; // Система может начать фильтрацию по пустому значению
Отбор.Заказчик.Значение = ТекущийЗаказчик;
Правильно: сначала готовим данные, а последним шагом активируем фильтр.
Отбор.Заказчик.Значение = ТекущийЗаказчик;
Отбор.Заказчик.ВидСравнения = ВидСравнения.Равно;
Отбор.Заказчик.Использование = Истина; // Только теперь система пересчитывает таблицу
Такой подход минимизирует количество промежуточных пересчетов видимости строк.
Если ваша табличная часть содержит сложные условия (например, нужно отфильтровать строки по сумме условий из пяти разных колонок), стандартный ОтборСтрок может работать медленно, вызывая фризы интерфейса. В этом случае мы рекомендуем применить метод «Индекса фильтра».
Разберем шаги реализации этого метода:
СлужебныйФлагОтбора (тип Булево).СлужебныйФлагОтбора = Истина.Пример реализации:
// 1. Рассчитываем признак видимости строк
Для Каждого СтрокаТЧ Из Объект.ТабличнаяЧасть Цикл
СтрокаТЧ.СлужебныйФлагОтбора = (СтрокаТЧ.Заказчик = ТекущийЗаказчик) И (СтрокаТЧ.Закрыт = флЗакрытия);
КонецЦикла;
// 2. Накладываем один простой отбор
ЭлементыФормы.ТабличнаяЧасть.ОтборСтрок.СлужебныйФлагОтбора.Установить(Истина);
Поскольку меняется только один параметр фильтрации, графическая оболочка перестраивается один раз, что практически полностью исключает мелькание.
В исключительных случаях, когда форма крайне перегружена элементами и стандартные методы 1С не помогают, опытные разработчики используют блокировку перерисовки окна на уровне операционной системы. Для этого используется сообщение WM_SETREDRAW.
Суть метода заключается в следующем:
Важно: этот метод требует использования внешних компонент или библиотек для вызова функций Windows API, поэтому его следует применять только как крайнюю меру.
Помимо самого кода установки отборов, на «плавность» работы влияют и другие факторы, которые мы сейчас проанализируем:
ПриВыводеСтроки или ПриПолученииДанных.ОтборСтрок в обычных формах работает неэффективно. В таких случаях стоит рассмотреть возможность использования ПостроителяЗапроса, который подготовит выборку в памяти, и последующую выгрузку результата в таблицу.ЭлементыФормы.ТЧ.Видимость = Ложь на время смены отбора. Это создает еще больший дискомфорт для глаз пользователя, так как вся таблица исчезает и появляется снова.Подведем итог: чтобы переключение закладок и фильтров было плавным, всегда используйте прямой перебор элементов коллекции ОтборСтрок, избегайте метода Сбросить() и всегда устанавливайте свойство Использование = Истина в самую последнюю очередь.