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