Как настроить индивидуальную раскраску строк табличного поля в обычных формах 1С без потери производительности?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При разработке интерфейсов в обычных формах платформы 1С часто возникает задача визуального выделения элементов списка. Например, необходимо дать пользователям возможность самостоятельно устанавливать цвет фона для конкретных позиций номенклатуры, сохраняя эти настройки персонально для каждого сотрудника.

Рассмотрим частую проблему, с которой сталкиваются разработчики: использование обращения к БД внутри событий оформления строк приводит к существенным задержкам при прокрутке и открытии списка. Разберем по шагам, как правильно реализовать данный функционал, сохраняя высокую скорость работы системы.

Причины проблем с производительностью при оформлении строк

Основная ошибка при реализации визуального оформления в обычных формах — использование события ПриВыводеСтроки в сочетании со считыванием данных из регистра сведений или с обращениями к реквизитам через точку (например, ДанныеСтроки.Ссылка.КакоеТоСвойство).

Событие ПриВыводеСтроки вызывается платформой последовательно для каждой видимой ячейки и строки. Если внутри обработчика выполняется SQL-запрос к базе данных или обращение к сторонним источникам, система начинает делать сотни одиночных обращений к СУБД, что вызывает зависание интерфейса.

Решение 1. Кэширование цветов в памяти и обработка в событиях формы

Наиболее сбалансированный и удобный подход состоит в предварительной загрузке персональных настроек пользователя в оперативную память при открытии формы с последующим оформлением пакета строк через событие ПриПолученииДанных.

Разберем алгоритм реализации по шагам:

  1. Создание структуры хранения: В конфигурации создается регистр сведений (например, ЦветаНоменклатурыПользователей) с измерениями Пользователь, Товар и ресурсом ЦветФона.
  2. Загрузка данных при открытии: В событии ПриОткрытии формы списка считываем все настройки текущего пользователя в модуль формы — в Соответствие или в индексированную ТаблицуЗначений.
  3. Пакетная раскраска: Используем обработчик события табличного поля ПриПолученииДанных, который получает сразу массив всех видимых на экране строк.
  4. Обновление данных: При изменении цвета пользователем обновляем локальный кэш (соответствие) и записываем данные в регистр сведений.

Рассмотрим пример кода для модуля формы списка:


Перем КэшЦветов; // Переменная модуля формы

Процедура ПриОткрытии()
    // Инициализируем соответствие: Ключ - Ссылка на товар, Значение - Цвет
    КэшЦветов = Новый Соответствие;
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	РС.Товар КАК Товар,
        |	РС.ЦветФона КАК ЦветФона
        |ИЗ
        |	РегистрСведений.ЦветаНоменклатурыПользователей КАК РС
        |ГДЕ
        |	РС.Пользователь = &ТекущийПользователь";
        
    Запрос.УстановитьПараметр("ТекущийПользователь", ПараметрыСеанса.ТекущийПользователь);
    Выборка = Запрос.Выполнить().Выбрать();
    
    Пока Выборка.Следующий() Цикл
        // Преобразуем сохраненные данные в объект Цвет
        КэшЦветов.Вставить(Выборка.Товар, Выборка.ЦветФона.Получить());
    КонецЦикла;
КонецПроцедуры

Процедура СписокПриПолученииДанных(Элемент, ОформленияСтрок)
    Для Каждого ОформлениеСтроки Из ОформленияСтрок Цикл
        ЦветТовара = КэшЦветов[ОформлениеСтроки.ДанныеСтроки.Ссылка];
        Если ЦветТовара <> Неопределено Тогда
            ОформлениеСтроки.Ячейки.Наименование.ЦветФона = ЦветТовара;
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Решение 2. Запрос по видимым строкам (Батчинг)

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

Проанализируем работу этого алгоритма в событии ПриПолученииДанных:

  1. Из входящей коллекции ОформленияСтрок формируется массив ссылок на отображаемые элементы.
  2. Выполняется один пакетный запрос к регистру сведений с условием ГДЕ Товар В (&МассивСсылок) И Пользователь = &ТекущийПользователь.
  3. Результаты запроса сопоставляются с элементами коллекции ОформленияСтрок для установки свойства ЦветФона.

Процедура СписокПриПолученииДанных(Элемент, ОформленияСтрок)
    МассивСсылок = Новый Массив;
    СоответствиеСтрок = Новый Соответствие;
    
    Для Каждого ОформлениеСтроки Из ОформленияСтрок Цикл
        СсылкаНаТовар = ОформлениеСтроки.ДанныеСтроки.Ссылка;
        МассивСсылок.Добавить(СсылкаНаТовар);
        СоответствиеСтрок.Вставить(СсылкаНаТовар, ОформлениеСтроки);
    КонецЦикла;
    
    Если МассивСсылок.Количество() = 0 Тогда
        Возврат;
    КонецЕсли;
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	РС.Товар КАК Товар,
        |	РС.ЦветФона КАК ЦветФона
        |ИЗ
        |	РегистрСведений.ЦветаНоменклатурыПользователей КАК РС
        |ГДЕ
        |	РС.Товар В(&МассивСсылок)
        |	И РС.Пользователь = &ТекущийПользователь";
        
    Запрос.УстановитьПараметр("МассивСсылок", МассивСсылок);
    Запрос.УстановитьПараметр("ТекущийПользователь", ПараметрыСеанса.ТекущийПользователь);
    
    Выборка = Запрос.Выполнить().Выбрать();
    Пока Выборка.Следующий() Цикл
        ОформлениеСтроки = СоответствиеСтрок[Выборка.Товар];
        Если ОформлениеСтроки <> Неопределено Тогда
            ОформлениеСтроки.ЦветФона = Выборка.ЦветФона.Получить();
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Решение 3. Использование произвольного запроса в источнике данных

Ещё один эффективный архитектурный вариант — передать задачу сопоставления цветов механизму динамического списка или динамической выборки табличного поля.

Если для табличного поля настраивается произвольный запрос в источнике данных, соединение с регистром сведений выполняется непосредственно в SQL-запросе:


ВЫБРАТЬ
	СпрНоменклатура.Ссылка КАК Ссылка,
	СпрНоменклатура.Наименование КАК Наименование,
	ЕСТЬNULL(РСЦвета.ЦветФона, НЕОПРЕДЕЛЕНО) КАК ЦветФона
ИЗ
	Справочник.Номенклатура КАК СпрНоменклатура
	ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦветаНоменклатурыПользователей КАК РСЦвета
		ПО СпрНоменклатура.Ссылка = РСЦвета.Товар
		И РСЦвета.Пользователь = &ТекущийПользователь

При таком подходе значение цвета поступает прямо в ДанныеСтроки. В обработчике ПриПолученииДанных останется только обратиться к колонке ДанныеСтроки.ЦветФона и применить оформление без дополнительных запросов и локальных таблиц кэширования.

Важные ограничения и особенности работы

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

← На главную