При разработке печатных форм или отчетов часто возникает необходимость дополнить данные табличной части документа сведениями из регистра — например, получить актуальную цену из виртуальной таблицы СрезПоследних регистра сведений Цены. Однако при попытке сделать это прямо во вложенной выборке разработчики часто сталкиваются со сложностями.
Рассмотрим подробно, почему не получается выполнить ЛЕВОЕ СОЕДИНЕНИЕ к вложенной табличной части в секции ВЫБРАТЬ и как правильно составить запрос к табличной части документа 1С.
Выясним причину, почему исходная конструкция запроса не работает. В языке запросов 1С выборка вида ЗаказНаПроизводство.Операции.(...) формирует вложенную таблицу непосредственно в поле результата запроса. Синтаксис 1С не позволяет выполнять операцию СОЕДИНЕНИЕ с другими таблицами или регистрами внутри этой вложенной выборки.
Привязать ЛЕВОЕ СОЕДИНЕНИЕ к полю-массиву строк или вложенной табличной части в секции ВЫБРАТЬ технически невозможно.
Чтобы получить цены по номенклатуре из табличной части, необходимо изменить структуру запроса: вместо обращения к шапке документа следует обратиться к самой табличной части как к основной таблице источника данных — Документ.ЗаказНаПроизводство.Операции.
Разберем по шагам, как построить такой запрос:
ИЗ указываем табличную часть документа: Документ.ЗаказНаПроизводство.Операции КАК ЗаказНаПроизводствоОперации.ЛЕВОЕ СОЕДИНЕНИЕ с виртуальной таблицей регистра сведений: РегистрСведений.Цены.СрезПоследних(&НаДату, ).ПО ЦеныСрезПоследних.Номенклатура = ЗаказНаПроизводствоОперации.Номенклатура.Ссылка (например, ЗаказНаПроизводствоОперации.Ссылка.Номер) или настраиваем группировки и итоги по полю Ссылка.Посмотрим на практический пример правильно сформированного запроса:
ВЫБРАТЬ
ЗаказНаПроизводствоОперации.Ссылка КАК Ссылка,
ЗаказНаПроизводствоОперации.Ссылка.Номер КАК Номер,
ЗаказНаПроизводствоОперации.Ссылка.Дата КАК ДатаДокумента,
ЗаказНаПроизводствоОперации.Ссылка.Организация КАК Организация,
ЗаказНаПроизводствоОперации.НомерСтроки КАК НомерСтроки,
ЗаказНаПроизводствоОперации.Номенклатура КАК Операция,
ЗаказНаПроизводствоОперации.Номенклатура.Артикул КАК Артикул,
ЗаказНаПроизводствоОперации.Номенклатура.Код КАК Код,
ЗаказНаПроизводствоОперации.Номенклатура.s_ПроизводственныйРесурс КАК Ресурс,
ЗаказНаПроизводствоОперации.Исполнитель КАК Исполнитель,
ЗаказНаПроизводствоОперации.Количество КАК Количество,
ЕстьNULL(ЦеныСрезПоследних.Цена, 0) КАК Цена
ИЗ
Документ.ЗаказНаПроизводство.Операции КАК ЗаказНаПроизводствоОперации
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Цены.СрезПоследних(&НаДату) КАК ЦеныСрезПоследних
ПО ЦеныСрезПоследних.Номенклатура = ЗаказНаПроизводствоОперации.Номенклатура
ГДЕ
ЗаказНаПроизводствоОперации.Ссылка В(&МассивОбъектов)
ИТОГИ
МАКСИМУМ(Номер),
МАКСИМУМ(ДатаДокумента),
МАКСИМУМ(Организация)
ПО
Ссылка
Для корректной обработки иерархических данных в коде обход результата запроса выполняют с помощью вызова РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам) по группировке Ссылка.
Если в документе присутствует сразу несколько табличных частей, не рекомендуется объединять их все в одном плоском запросе через ЛЕВОЕ СОЕДИНЕНИЕ, так как это приведет к перемножению строк (декартову произведению). В таких случаях оптимально использовать пакет запросов с временными таблицами (МенеджерВременныхТаблиц), выбирая каждую табличную часть отдельным запросом в пакете.