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