При доработке типовых конфигураций на обычных формах, таких как «1С:Управление торговлей 10.3», часто возникает задача визуального выделения позиций в форме подбора. Например, необходимо подсветить красным фоном товары, требующие срочной продажи, или позиции с определенным статусом. Начинающие разработчики нередко пытаются обращаться к элементам отбора формы при открытии или вызывать поиск по коду для каждой отдельной строки. Разберем по шагам, почему такие подходы приводят к ошибкам, и как правильно реализовать визуальное оформление строк с учетом производительности системы.
Рассмотрим распространенные заблуждения, с которыми сталкиваются при решении этой задачи:
ЭлементыФормы.СправочникНоменклатура.Значение.Отбор.Код.Значение возвращает только значение поля отбора, если отбор по коду был установлен пользователем или программно. Это свойство не содержит список отображаемых в таблице товаров и не имеет отношения к обходу строк списка.Найти() для проверки логических условий. Глобальная функция Найти() предназначена исключительно для поиска подстроки в строке и принимает строковые параметры. Выражения вида Найти(Код, Реквизит = Истина) приводят к ошибочному поведению, так как сравнение булевых значений нельзя использовать в качестве аргумента строкового поиска.Справочники.Номенклатура.НайтиПоКоду() внутри событий отрисовки. Обработчики вывода строк вызываются платформой непрерывно при каждой прокрутке таблицы или изменении фокуса. Поиск в цикле для каждого элемента создает лавину запросов к базе данных и приводит к зависанию интерфейса.В платформе 1С для обычных форм основным и наиболее производительным инструментом динамического оформления табличных полей является событие ПриПолученииДанных. В отличие от события ПриВыводеСтроки, которое срабатывает персонально для каждой строки, ПриПолученииДанных принимает на вход коллекцию ОформленияСтрок, содержащую сразу всю видимую порцию данных на экране.
Проанализируем базовый вариант установки фона. Обратите внимание: у объекта ОформлениеСтроки нет прямого свойства Ссылка, обращение к данным текущей записи выполняется через свойство ДанныеСтроки.
Процедура СправочникНоменклатураПриПолученииДанных(Элемент, ОформленияСтрок)
ЦветАвто = Цвета.Автоматический;
Для Каждого Оформление Из ОформленияСтрок Цикл
// Проверяем, что строка содержит данные и не является пустой
Если Оформление.ДанныеСтроки = Неопределено Тогда
Продолжить;
КонецЕсли;
// Получаем значение признака через данные текущей строки
Если Оформление.ДанныеСтроки.Ссылка.СрочнаяПродажа = Истина Тогда
Оформление.ЦветФона = WebЦвета.Красный;
Иначе
Оформление.ЦветФона = ЦветАвто;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Для возврата стандартного цвета платформы лучше всего использовать предопределенное значение Цвета.Автоматический, что гарантирует корректное отображение системной палитры и чередования строк.
В приведенном выше базовом примере обращение к реквизиту выполняется через точку: Оформление.ДанныеСтроки.Ссылка.СрочнаяПродажа. В этот момент платформа считывает данные каждого элемента отдельным неявным обращением к СУБД. Если пользователь быстро прокручивает каталог, это вызывает сильные задержки.
Разберем профессиональный шаблон пакетного считывания данных. Сначала соберем массив ссылок всех отображаемых строк, сделаем один быстрый запрос и запишем результаты в Соответствие:
Процедура СправочникНоменклатураПриПолученииДанных(Элемент, ОформленияСтрок)
МассивСсылок = Новый Массив;
// Шаг 1: Формируем список ссылок только для видимых строк
Для Каждого Оформление Из ОформленияСтрок Цикл
Если Оформление.ДанныеСтроки <> Неопределено И ЗначениеЗаполнено(Оформление.ДанныеСтроки.Ссылка) Тогда
// Исключаем группы номенклатуры при необходимости
Если Не Оформление.ДанныеСтроки.ЭтоГруппа Тогда
МассивСсылок.Добавить(Оформление.ДанныеСтроки.Ссылка);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если МассивСсылок.Количество() = 0 Тогда
Возврат;
КонецЕсли;
// Шаг 2: Получаем данные одним пакетным запросом
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.СрочнаяПродажа КАК СрочнаяПродажа
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Ссылка В(&МассивСсылок)";
Запрос.УстановитьПараметр("МассивСсылок", МассивСсылок);
Выборка = Запрос.Выполнить().Выбрать();
// Шаг 3: Сохраняем признаки в соответствие для быстрого поиска в памяти
ПризнакиОформления = Новый Соответствие;
Пока Выборка.Следующий() Цикл
ПризнакиОформления.Вставить(Выборка.Ссылка, Выборка.СрочнаяПродажа);
КонецЦикла;
// Шаг 4: Раскрашиваем строки без обращений к базе данных
ЦветАвто = Цвета.Автоматический;
Для Каждого Оформление Из ОформленияСтрок Цикл
Если Оформление.ДанныеСтроки = Неопределено Тогда
Продолжить;
КонецЕсли;
НужноВыделить = ПризнакиОформления[Оформление.ДанныеСтроки.Ссылка];
Если НужноВыделить = Истина Тогда
Оформление.ЦветФона = WebЦвета.Красный;
Иначе
Оформление.ЦветФона = ЦветАвто;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
В типовой обработке «ПодборНоменклатуры» данные могут выводиться в различных режимах. Рассмотрим дополнительные способы интеграции реквизита в отображение:
Данные с путем к реквизиту (например, Ссылка.СрочнаяПродажа). Сделав эту колонку невидимой, мы заставляем платформу выбирать значение сразу в основном запросе списка. В этом случае значение становится доступно напрямую: Оформление.ДанныеСтроки.СрочнаяПродажа без выполнения каких-либо дополнительных запросов.Номенклатура.СрочнаяПродажа в выборку запроса, и колонка автоматически появится в строках таблицы.Чтобы быстро ориентироваться в коде типовых и нетиповых конфигураций, используем следующие приемы:
ТипЗнч(ЭлементыФормы.СправочникНоменклатура.Значение) сразу покажет, с чем работает форма в данный момент — со СправочникСписок или с ТаблицаЗначений.ОформлениеСтроки, легко убедиться, что он управляет свойствами ячеек (ЦветФона, ЦветТекста, Шрифт), а доступ к полям источника данных строки осуществляется через свойство ДанныеСтроки.