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