При разработке интерфейсов на обычных формах 1С:Предприятие 8.3 часто возникает задача визуального выделения документов (например, раскраска строк в зависимости от структуры подчиненности или статуса оплаты). Однако разработчики сталкиваются с платформенным ограничением: если цвет или текст колонки рассчитываются динамически в процессе оформления строки, стандартный механизм отбора платформы не показывает эту колонку и не позволяет выполнить фильтрацию. Разберем причинно-следственные связи этого поведения и рассмотрим проверенные способы реализации отбора.
Проанализируем механику работы элемента формы ДокументСписок. Данный элемент является динамическим списком, который получает данные непосредственно из таблиц базы данных с помощью транслируемых SQL-запросов.
Когда вы добавляете на форму новую колонку, не связанную с реквизитом объекта или табличной части, и заполняете её в событии ПриВыводеСтроки (например, задавая ОформлениеСтроки.ЦветФона или ОформлениеСтроки.Ячейки.Цвет.Значение), эти данные существуют исключительно в оперативной памяти клиента. В самой базе данных этих значений нет. Так как стандартный отбор 1С формирует условия на уровне СУБД, платформа физически не может применить фильтр к данным, которых не существует в таблицах базы данных.
Если вносить изменения в структуру метаданных нежелательно, можно организовать программный отбор. Для этого создадим на форме отдельную кнопку (или меню), по нажатию на которую будет выполняться запрос с логикой проверки условий, а результат будет передаваться в элемент отбора по полю Ссылка с видом сравнения ВСписке.
Рассмотрим пример реализации обработчика нажатия кнопки:
Процедура КоманднаяПанельОтборПоЦвету(Кнопка)
// Получаем массив ссылок на документы, которые соответствуют условию
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Док.Ссылка КАК Ссылка
|ИЗ
| Документ.ЗаказПокупателя КАК Док
|ГДЕ
| Док.Проведен = ИСТИНА"; // Здесь закладывается ваша логика раскраски
ТаблицаРезультата = Запрос.Выполнить().Выгрузить();
МассивСсылок = ТаблицаРезультата.ВыгрузитьКолонку("Ссылка");
// Применяем отбор к списку документов
ОтборСсылка = ДокументСписок.Отбор.Ссылка;
ОтборСсылка.Использование = Истина;
ОтборСсылка.ВидСравнения = ВидСравнения.ВСписке;
ОтборСсылка.Значение = МассивСсылок;
КонецПроцедуры
Важное ограничение метода: Если в результат запроса попадает несколько тысяч документов, условие ВСписке приведет к формированию громоздкого SQL-запроса с оператором IN (...). Это может существенно снизить производительность СУБД и вызвать задержки при обновлении списка.
Более надежным и быстродействующим решением является хранение вычисленного состояния прямо в базе данных. Посмотрим, как это реализовать по шагам:
ПеречислениеМенеджер (например, СостоянияДокумента со значениями Красный, Желтый, Зеленый).После добавления реквизита колонка появится в настройках «Установить отбор» формы списка, и отбор будет работать штатно на уровне базы данных с высокой скоростью.
Если перезаписывать сами документы нежелательно (чтобы не менять версию данных и не создавать блокировки), лучше всего использовать независимый регистр сведений.
Схема реализации выглядит следующим образом:
СостоянияДокументов). Измерение — Документ (ссылка), ресурс — ЦветСостояния (перечисление или строка).ПриЗаписи или ОбработкаПроведения связанных документов обновляем запись в регистре сведений.Разберем также частую ошибку при оформлении строк. Если логика определения цвета выполняет запросы к базе данных (например, проверяет структуру подчиненности) внутри события ПриВыводеСтроки, список начнет сильно «зависать» при прокрутке, так как событие вызывается отдельно для каждой ячейки каждой строки.
Для ускорения работы списка следует перенести расчет из ПриВыводеСтроки в событие ПриПолученииДанных. Это событие получает сразу весь массив оформляемых строк ОформленияСтрок, что позволяет получить данные по подчиненным документам одним пакетным запросом для всей видимой страницы.