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