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