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