Как вывести остатки в отчете 1С, если за выбранный период не было движений?

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

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

Почему пропадают остатки без движений?

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

Решение №1: Использование метода дополнения «Движения и границы периода»

Первое, что необходимо сделать — это изменить четвертый параметр виртуальной таблицы ОстаткиИОбороты. Проанализируем стандартный запрос, который часто генерирует конструктор:


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

В данном примере используется метод дополнения Движения. Это означает, что записи будут выбраны только за те секунды/дни, когда были движения. Чтобы исправить это, заменим параметр на ДвиженияИГраницыПериода. Посмотрим на обновленный код:


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

Теперь система принудительно добавит в результат запроса две виртуальные записи: на начало периода и на конец периода. Даже если оборотов не было, начальная граница периода «подтянет» актуальный остаток, и он отобразится в отчете.

Проблема «лишних» или пустых строк

После включения метода ДвиженияИГраницыПериода вы можете заметить, что в отчете появились странные пустые строки, в которых выводится только сальдо, а поля Регистратор или ПериодДень не заполнены. Выясним причину этого поведения.

Так как записи границ периода являются виртуальными, у них нет физического регистратора (документа). Если в вашем отчете настроена детальная группировка по регистратору, СКД честно выводит эти технические строки. Чтобы избавиться от визуального мусора, выполним следующие действия:

  1. Настройка отбора в СКД: В настройках группировки по регистратору добавьте условие Регистратор Заполнено. Это скроет пустые строки границ, при этом итоги по остаткам на уровне вышестоящих группировок сохранятся.
  2. Использование функции ЕСТЬNULL: В тексте запроса рекомендуется оборачивать ресурсы, чтобы избежать пустых значений в вычислениях: ЕСТЬNULL(СуммаНачальныйОстаток, 0).

Важность настройки ролей полей в СКД

Если вы используете Систему компоновки данных, мало просто изменить запрос. Выясним, как правильно настроить вкладку «Наборы данных». Для корректной работы остатков СКД должна понимать, какое поле является начальным остатком, а какое — конечным. Проверьте следующие настройки в колонке «Роль»:

Важный нюанс: Если роли не настроены, СКД может начать суммировать остатки по иерархии группировок как обычные числа, что приведет к неверным итоговым суммам (остатки будут удваиваться или утраиваться при наличии нескольких движений внутри периода).

Альтернативный метод: Левое соединение таблиц

В сложных случаях, когда виртуальная таблица ОстаткиИОбороты ведет себя непредсказуемо из-за специфических фильтров, рассмотрим вариант разделения запроса на два набора данных или две временные таблицы:

  1. Получаем Остатки на начало периода (виртуальная таблица Остатки).
  2. Получаем Обороты за период (виртуальная таблица Обороты).
  3. Соединяем их ЛЕВЫМ СОЕДИНЕНИЕМ по измерениям (Поставщик, Организация и т.д.).

Этот способ гарантирует наличие строки с контрагентом, если у него был остаток, даже если во второй таблице (оборотах) данных нет. Конечный остаток в этом случае рассчитывается формулой: НачальныйОстаток + Приход - Расход. Для построения выборок срезов остатков на диапазоне дат в запросах можно использовать методику формирования срезов остатков и диапазонов дат через запросы.

Проверка параметров виртуальной таблицы

Проанализируем еще одну частую ошибку. Иногда программисты накладывают условия на данные в секции ГДЕ основного запроса, а не в параметрах виртуальной таблицы. Рассмотрим пример неправильного кода:


ВЫБРАТЬ ...
ИЗ РегистрНакопления.РасчетыСПоставщиками.ОстаткиИОбороты(,, Авто, ДвиженияИГраницыПериода, ) КАК Таблица
ГДЕ Таблица.Организация = &Организация

В этом случае записи дополнения (границы), созданные системой, могут быть отсечены условием ГДЕ, если поле организации в них окажется пустым или не будет соответствовать логике компоновки. Правильный подход — передавать все фильтры по измерениям непосредственно в параметры виртуальной таблицы (последний параметр «Условие»).

Подведем итог: для исправления «пропадающего» сальдо используйте метод ДвиженияИГраницыПериода, правильно настраивайте роли полей в конструкторе СКД и следите за тем, чтобы фильтры не отсекали технические записи границ периода.

← На главную