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