При циклическом заполнении или обновлении визуальной таблицы значений на форме в 1С:Предприятии 7.7 разработчики часто сталкиваются с неприятным эффектом: строки начинают непрерывно моргать, интерфейс перерисовывается при каждом добавлении строки, а общая скорость работы алгоритма падает. Разберем причины возникновения этой проблемы и рассмотрим надежные варианты её решения.
Почему происходит мерцание? В платформе 1С 7.7 при вызове методов добавления строк и установки значений в визуальном элементе формы (ТаблицаЗначений) каждое изменение инициирует системное событие перерисовки окна (WM_PAINT) и пересчет полос прокрутки. Кроме того, если к колонкам или строкам привязаны обработчики событий или формулы, они могут многократно срабатывать во время цикла. Отсутствие встроенной двойной буферизации у стандартного элемента управления диалога приводит к заметному мерцанию и потере производительности.
Проанализируем наиболее универсальный и рекомендованный подход. Вместо того чтобы построчно изменять визуальный элемент управления, всю подготовку данных, сортировку и установку отметок выполняем в объекте ТаблицаЗначений, созданном в оперативной памяти. После завершения всех манипуляций готовая таблица мгновенно загружается в элемент формы.
Разберем пошаговый алгоритм реализации этого метода:
ТаблицаЗначений в памяти через СоздатьОбъект("ТаблицаЗначений").Выгрузить() и очищаем строки.Загрузить() — перерисовка формы происходит ровно один раз.Посмотрим на пример программного кода:
// 1. Создаем временную таблицу в памяти и копируем структуру с формы
ТЗ_Память = СоздатьОбъект("ТаблицаЗначений");
ТЗ.Выгрузить(ТЗ_Память);
ТЗ_Память.Очистить();
// 2. Заполняем данные в фоновом режиме
Для Сч = 1 По СписокДанных.РазмерСписка() Цикл
ТЗ_Память.НоваяСтрока();
ТЗ_Память.Номенклатура = СписокДанных.ПолучитьЗначение(Сч);
ТЗ_Память.Количество = 1;
ТЗ_Память.Отметка = 0;
КонецЦикла;
// Выполняем требуемую сортировку до вывода на форму
ТЗ_Память.Сортировать("Номенклатура+");
// 3. Быстро загружаем результат на форму без мерцания
ТЗ.Загрузить(ТЗ_Память);
Если по логике работы требуется модифицировать именно текущий элемент формы (например, уже настроены специфические привязки или выполняется точечная модификация), можно временно скрыть таблицу на время выполнения цикла. При отключенной видимости платформа перестает перерисовывать контрол при каждом изменении строки, что полностью убирает мерцание и дает ощутимый прирост скорости (порядка 20–30% и более).
Рассмотрим, как правильно использовать управление видимостью через объект Форма:
// Скрываем таблицу значений перед началом долгой обработки
Форма.ТЗ.Видимость(0);
// Выполняем цикл заполнения
Для Сч = 1 По ИсточникДанных.РазмерСписка() Цикл
ТЗ.НоваяСтрока();
ТЗ.Товар = ИсточникДанных.ПолучитьЗначение(Сч);
КонецЦикла;
// Возвращаем видимость элементу формы
Форма.ТЗ.Видимость(1);
Рассмотрим дополнительные технические нюансы, которые помогут сделать интерфейс максимально отзывчивым и стабильным:
// В начале заполнения
мБлокировкаОбработчиков = 1;
// Цикл обработки данных...
// В конце заполнения
мБлокировкаОбработчиков = 0;
WM_SETREDRAW или заменить стандартную таблицу на ТабличноеПоле из библиотеки 1C++, поддерживающее аппаратную буферизацию и виртуальный режим отображения строк.Применение разделения данных на фоновую обработку в памяти с последующим вызовом Загрузить() либо временное скрытие элемента диалога через Видимость(0) полностью устраняют визуальные артефакты и делают работу пользователей комфортной.