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