При разработке и доработке внешних печатных форм часто возникает необходимость выводить в документ дополнительные свойства номенклатуры (например, температурный режим хранения, бренд или особые условия транспортировки). Кроме того, нередко требуется сгруппировать товарные позиции в печатной форме по значению этого свойства.
Рассмотрим подробно, как правильно связать табличную часть документа с регистром сведений ЗначенияСвойствОбъектов, вытащить нужное свойство и настроить программный вывод макета с группировкой по категориям.
Для того чтобы получить значение свойства номенклатуры, необходимо выполнить ЛЕВОЕ СОЕДИНЕНИЕ табличной части документа с регистром сведений ЗначенияСвойствОбъектов. Важно накладывать условие отбора свойства непосредственно в условии связи ПО, а не в секции ГДЕ, иначе левое соединение превратится во внутреннее и строки без заполненого свойства просто выпадут из печатной формы.
Разберем пример получения конкретного свойства (например, «Температурный режим»):
// Ссылка на план видов характеристик "Свойства объектов"
ТоСамоеСвойство = ПланыВидовХарактеристик.СвойстваОбъектов.НайтиПоНаименованию("Температурный режим");
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ТекущийДокумент", СсылкаНаОбъект);
Запрос.УстановитьПараметр("Свойство", ТоСамоеСвойство);
Запрос.Текст =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| ПеремещениеТоваровТовары.НомерСтроки КАК НомерСтроки,
| ПеремещениеТоваровТовары.Номенклатура КАК Номенклатура,
| ПеремещениеТоваровТовары.Номенклатура.Наименование КАК Наименование,
| ВЫРАЗИТЬ(ПеремещениеТоваровТовары.Номенклатура.НаименованиеПолное КАК СТРОКА(250)) КАК Товар,
| ПеремещениеТоваровТовары.Номенклатура.Код КАК Код,
| ПеремещениеТоваровТовары.Номенклатура.Артикул КАК Артикул,
| ПеремещениеТоваровТовары.Количество КАК Количество,
| ПеремещениеТоваровТовары.ЕдиницаИзмерения КАК ЕдиницаИзмерения,
| ПеремещениеТоваровТовары.Цена КАК Цена,
| ПеремещениеТоваровТовары.ХарактеристикаНоменклатуры КАК Характеристика,
| ПеремещениеТоваровТовары.СерияНоменклатуры КАК Серия,
| ЕСТЬNULL(ЗначенияСвойствОбъектов.Значение, ""Без температурного режима"") КАК ТемпературныйРежим
|ИЗ
| Документ.ПеремещениеТоваров.Товары КАК ПеремещениеТоваровТовары
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
| ПО ПеремещениеТоваровТовары.Номенклатура = ЗначенияСвойствОбъектов.Объект
| И ЗначенияСвойствОбъектов.Свойство = &Свойство
|ГДЕ
| ПеремещениеТоваровТовары.Ссылка = &ТекущийДокумент
|УПОРЯДОЧИТЬ ПО
| ТемпературныйРежим,
| ПеремещениеТоваровТовары.НомерСтроки
|ИТОГИ ПО
| ТемпературныйРежим";
Обратим внимание на ключевые моменты в написании этого запроса:
И ЗначенияСвойствОбъектов.Свойство = &Свойство находится в секции ПО. Это гарантирует, что товары без температурного режима все равно попадут в результат.ЕСТЬNULL: Если свойство не задано для номенклатуры, платформа вернет NULL. С помощью ЕСТЬNULL мы подменяем отсутствующее значение понятной текстовой заглушкой.ИТОГИ ПО: Чтобы впоследствии корректно выводить строки группировок в макете, мы добавляем предложение ИТОГИ ПО ТемпературныйРежим.При стандартном выгрузке результата запроса в таблицу значений или при линейном обходе группировка не отобразится. Для формирования иерархического документа необходимо обходить результат запроса по группировкам с помощью методов Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам).
Рассмотрим алгоритм вывода макета по шагам:
ШапкаГруппы) и область для детальных строк с товарами (СтрокаДетали).Пример кода вывода печатной формы:
РезультатЗапроса = Запрос.Выполнить();
// Получаем выборку верхнего уровня по группировке
ВыборкаГруппа = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Макет = ПолучитьМакет("Макет");
ОбластьШапкаГруппы = Макет.ПолучитьОбласть("ШапкаГруппы");
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
ТабличныйДокумент = Новый ТабличныйДокумент;
Пока ВыборкаГруппа.Следующий() Цикл
// Выводим заголовок группировки (например, "Температурный режим: +2...+8 C")
ОбластьШапкаГруппы.Параметры.ТемпературныйРежимЗаголовок = ВыборкаГруппа.ТемпературныйРежим;
ТабличныйДокумент.Вывести(ОбластьШапкаГруппы);
// Получаем детальные записи, входящие в текущую группу
ВыборкаДетали = ВыборкаГруппа.Выбрать();
Пока ВыборкаДетали.Следующий() Цикл
ЗаполнитьЗначенияСвойств(ОбластьСтрока.Параметры, ВыборкаДетали);
ТабличныйДокумент.Вывести(ОбластьСтрока);
КонецЦикла;
КонецЦикла;
Проанализируем частые ошибки при проектировании макета внешней печатной формы:
НайтиПоНаименованию(), проверьте отсутствие лишних пробелов в начале или конце наименования в справочнике. Добавление пробела часто используется пользователями для принудительной сортировки элементов в списках, что приводит к ненайденным ссылкам в коде.Поиск объектов по наименованию (НайтиПоНаименованию("Температурный режим")) является потенциально уязвимым решением, так как пользователь базы данных может переименовать свойство. Для повышения устойчивости решения рекомендуются следующие подходы:
УправлениеСвойствами.ЗначенияСвойствОбъектов также и по полю ХарактеристикаНоменклатуры.