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