Как избавиться от мерцания таблицы значений на форме при её заполнении в 1С 7.7?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

При циклическом заполнении или обновлении визуальной таблицы значений на форме в 1С:Предприятии 7.7 разработчики часто сталкиваются с неприятным эффектом: строки начинают непрерывно моргать, интерфейс перерисовывается при каждом добавлении строки, а общая скорость работы алгоритма падает. Разберем причины возникновения этой проблемы и рассмотрим надежные варианты её решения.

Почему происходит мерцание? В платформе 1С 7.7 при вызове методов добавления строк и установки значений в визуальном элементе формы (ТаблицаЗначений) каждое изменение инициирует системное событие перерисовки окна (WM_PAINT) и пересчет полос прокрутки. Кроме того, если к колонкам или строкам привязаны обработчики событий или формулы, они могут многократно срабатывать во время цикла. Отсутствие встроенной двойной буферизации у стандартного элемента управления диалога приводит к заметному мерцанию и потере производительности.

Способ 1. Заполнение промежуточной таблицы в памяти с последующей загрузкой

Проанализируем наиболее универсальный и рекомендованный подход. Вместо того чтобы построчно изменять визуальный элемент управления, всю подготовку данных, сортировку и установку отметок выполняем в объекте ТаблицаЗначений, созданном в оперативной памяти. После завершения всех манипуляций готовая таблица мгновенно загружается в элемент формы.

Разберем пошаговый алгоритм реализации этого метода:

  1. Создаем объект ТаблицаЗначений в памяти через СоздатьОбъект("ТаблицаЗначений").
  2. Клонируем структуру колонок из экранной таблицы с помощью метода Выгрузить() и очищаем строки.
  3. Выполняем расчеты и наполнение в памяти (интерфейс при этом не затрагивается).
  4. Загружаем итоговую таблицу в элемент диалога методом Загрузить() — перерисовка формы происходит ровно один раз.

Посмотрим на пример программного кода:


// 1. Создаем временную таблицу в памяти и копируем структуру с формы
ТЗ_Память = СоздатьОбъект("ТаблицаЗначений");
ТЗ.Выгрузить(ТЗ_Память);
ТЗ_Память.Очистить();

// 2. Заполняем данные в фоновом режиме
Для Сч = 1 По СписокДанных.РазмерСписка() Цикл
    ТЗ_Память.НоваяСтрока();
    ТЗ_Память.Номенклатура = СписокДанных.ПолучитьЗначение(Сч);
    ТЗ_Память.Количество   = 1;
    ТЗ_Память.Отметка      = 0;
КонецЦикла;

// Выполняем требуемую сортировку до вывода на форму
ТЗ_Память.Сортировать("Номенклатура+");

// 3. Быстро загружаем результат на форму без мерцания
ТЗ.Загрузить(ТЗ_Память);

Способ 2. Временное отключение видимости элемента диалога

Если по логике работы требуется модифицировать именно текущий элемент формы (например, уже настроены специфические привязки или выполняется точечная модификация), можно временно скрыть таблицу на время выполнения цикла. При отключенной видимости платформа перестает перерисовывать контрол при каждом изменении строки, что полностью убирает мерцание и дает ощутимый прирост скорости (порядка 20–30% и более).

Рассмотрим, как правильно использовать управление видимостью через объект Форма:


// Скрываем таблицу значений перед началом долгой обработки
Форма.ТЗ.Видимость(0);

// Выполняем цикл заполнения
Для Сч = 1 По ИсточникДанных.РазмерСписка() Цикл
    ТЗ.НоваяСтрока();
    ТЗ.Товар = ИсточникДанных.ПолучитьЗначение(Сч);
КонецЦикла;

// Возвращаем видимость элементу формы
Форма.ТЗ.Видимость(1);

Способ 3. Блокировка перерисовки и обработчиков текущей строки

Рассмотрим дополнительные технические нюансы, которые помогут сделать интерфейс максимально отзывчивым и стабильным:

  1. Отключение процедур текущей строки: Если в модуле формы определена процедура, привязанная к изменению активной строки таблицы (например, синхронное обновление подчиненных данных), она может вызываться на каждом шаге цикла. Рекомендуется ввести флаг блокировки (булеву переменную), чтобы внутри процедур прерывать выполнение на время массового заполнения:
    
    // В начале заполнения
    мБлокировкаОбработчиков = 1;
    
    // Цикл обработки данных...
    
    // В конце заполнения
    мБлокировкаОбработчиков = 0;
    
  2. Очистка вычисляемых формул колонок: Если в параметрах колонок формы заданы формулы, они вычисляются при перерисовке каждого видимого элемента. Для больших массивов данных эффективнее очистить формулы в свойствах колонок и заполнять значения явно в коде.
  3. Использование внешних компонент (FormEx, 1C++): Если штатных возможностей платформы 7.7 недостаточно, можно заблокировать обновление окна через WinAPI-сообщение WM_SETREDRAW или заменить стандартную таблицу на ТабличноеПоле из библиотеки 1C++, поддерживающее аппаратную буферизацию и виртуальный режим отображения строк.

Применение разделения данных на фоновую обработку в памяти с последующим вызовом Загрузить() либо временное скрытие элемента диалога через Видимость(0) полностью устраняют визуальные артефакты и делают работу пользователей комфортной.

← На главную