Почему в отчете «Анализ доступности товаров» не плюсуются значения после модификации запроса?

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

При доработке типовых отчетов в конфигурации Управление торговлей 10.3, таких как «Анализ доступности товаров на складах», программисты часто сталкиваются с ситуацией, когда новые поля, добавленные через ЛЕВОЕ СОЕДИНЕНИЕ, не суммируются или отображают некорректные данные. Особенно это актуально, когда логика отчета требует подмены типовых остатков на значения из дополнительных регистров сведений. Разберем по шагам, почему возникают такие расхождения и как правильно модифицировать сложный запрос построителя отчета.

Причина 1: Коварство значения NULL в арифметических операциях

Проанализируем фрагмент запроса, где происходит вычисление доступного количества: ВложенныйЗапрос.КоличествоВРезерве + ДоступноеКоличествоНоменклатуры.ДоступноеКоличество. В языке запросов 1С любая арифметическая операция с участием NULL всегда возвращает NULL. Если в регистре сведений ДоступноеКоличествоНоменклатуры отсутствует запись для конкретной комбинации номенклатуры и склада, поле из левого соединения будет пустым (NULL). В итоге вся сумма «зануляется».

Для решения этой проблемы обязательно используем функцию ЕСТЬNULL. Рассмотрим правильный вариант написания выражения:


ВложенныйЗапрос.КоличествоВРезерве + ЕСТЬNULL(ДоступноеКоличествоНоменклатуры.ДоступноеКоличество, 0) КАК ДоступноеКоличествоСРезервами

Важно: Это касается всех вычисляемых полей. Если вы строите условие ВЫБОР КОГДА..., проверяйте входящие переменные на NULL до того, как начнете их сравнивать или складывать.

Причина 2: Несоответствие измерений при соединении таблиц

В типовой УТ 10.3 регистр накопления ТоварыНаСкладах имеет измерение Качество, а регистр ТоварыВРезервеНаСкладах — нет. Когда мы пытаемся соединить эти таблицы (или наш новый Регистр Сведений) по полному набору измерений, связь разрывается. Выясним причину: если в одном источнике Качество заполнено как «Новый», а в другом этого поля просто нет (или оно содержит NULL из-за левого соединения), 1С не сможет сопоставить эти строки.

Проанализируем ситуацию с регистром резервов. Чтобы соединение работало корректно, при выборе данных из регистра резервов нужно принудительно подставлять значение качества. Посмотрим на пример кода:


ВЫБРАТЬ
    ТоварыВРезерве.Склад,
    ТоварыВРезерве.Номенклатура,
    &КачествоНовый КАК Качество, // Подставляем пустую ссылку или значение "Новый"
    ТоварыВРезерве.КоличествоОстаток
ИЗ
    РегистрНакопления.ТоварыВРезервеНаСкладах.Остатки(&ДатаКон, ) КАК ТоварыВРезерве

Если же вы убираете Качество из условий связи ПО, убедитесь, что это не приведет к дублированию строк (если в основной таблице остатков есть несколько записей с разным качеством для одной номенклатуры).

Причина 3: Использование Построителя отчетов и СКД

Часто в консоли запросов мы видим правильные цифры, а в самом отчете — нет. Это происходит потому, что типовой отчет «Анализ доступности» использует Построитель отчета. Построитель умеет динамически изменять текст запроса, добавляя свои условия из настроек отбора.

Разберем основные моменты, на которые стоит обратить внимание:

  1. Роли полей: Если вы используете СКД, проверьте вкладку «Наборы данных». Убедитесь, что для числовых полей установлена роль «Остатки», а для измерений указаны правильные связи.
  2. Автозаполнение: Отключите автозаполнение в запросе, если вы используете сложные вложенные конструкции, иначе система может самостоятельно добавить измерения в группировки, что приведет к «размножению» строк.
  3. Граница периода: Убедитесь, что параметр &ДатаКон в консоли и в отчете совпадает до секунды. В 1С 01.01.2023 00:00:00 и Граница(01.01.2023 00:00:00, Включая) — это разные моменты времени для остатков.

Причина 4: Логика формирования итогов

В тексте запроса автора используется секция ИТОГИ СУММА(...) ПО ОБЩИЕ. Проанализируем ситуацию: если мы делаем левое соединение к таблице, которая уже содержит агрегированные данные (остатки), с таблицей регистра сведений (где лежит некий порог или лимит), то при наличии нескольких документов-оснований (например, резервов) значение из регистра сведений будет суммироваться столько раз, сколько строк резерва нашлось для этой номенклатуры.

Рассмотрим правильный подход к структуре запроса:

  1. Сначала соберите все данные из регистров накопления (остатки, резервы, заказы) во временную таблицу.
  2. Сгруппируйте эту временную таблицу по Складу и Номенклатуре, чтобы получить одну строку на одну позицию.
  3. И только после этого выполняйте ЛЕВОЕ СОЕДИНЕНИЕ с вашим Регистром Сведений.

Посмотрим на упрощенную схему такого запроса:


// 1. Собираем все данные в кучу
ВЫБРАТЬ
    Т.Склад, Т.Номенклатура, СУММА(Т.Количество) КАК ОбщийОстаток
ПОМЕСТИТЬ ВТ_ДанныеРегистров
ИЗ (
    ВЫБРАТЬ Склад, Номенклатура, КоличествоОстаток КАК Количество ИЗ РегистрНакопления.ТоварыНаСкладах.Остатки(...)
    ОБЪЕДИНИТЬ ВСЕ
    ВЫБРАТЬ Склад, Номенклатура, -КоличествоОстаток ИЗ РегистрНакопления.ТоварыВРезервеНаСкладах.Остатки(...)
) КАК Т
СГРУППИРОВАТЬ ПО Т.Склад, Т.Номенклатура;

// 2. Соединяем с пороговыми значениями
ВЫБРАТЬ
    ВТ.Склад, ВТ.Номенклатура,
    ВЫБОР КОГДА РС.ДоступноеКоличество ЕСТЬ NULL ТОГДА ВТ.ОбщийОстаток ИНАЧЕ РС.ДоступноеКоличество КОНЕЦ КАК ИтоговоеНаличие
ИЗ ВТ_ДанныеРегистров КАК ВТ
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДоступноеКоличествоНоменклатуры КАК РС
ПО ВТ.Склад = РС.Склад И ВТ.Номенклатура = РС.Номенклатура

Такой подход гарантирует, что значения из Регистра Сведений не будут задваиваться, а расчеты будут прозрачными для отладки. При работе с УТ 10.3 помните, что порядок объединения таблиц в типовых запросах критически важен для производительности и корректности итогов по складам.

← На главную