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