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