Как создать отчет по остаткам и резервам товаров в 1С при помощи системы компоновки данных

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

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

Анализируем структуру данных и задачу

Представим, что в нашей конфигурации существуют два регистра накопления остатков:

  1. ДвиженияТовара: хранит информацию о фактическом наличии. Измерения: Организация, Склад, Товар. Ресурс: Количество.
  2. Резерв: хранит информацию о забронированных товарах. Измерения: Склад, Товар, Организация. Ресурс: Количество.

Наша цель — получить итоговую таблицу, где в одной строке по конкретному товару и складу будут выведены: Остаток, Резерв и вычисляемый показатель Свободный остаток (Остаток минус Резерв).

Шаг 1. Работа с виртуальными таблицами

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

РегистрНакопления.ДвиженияТовара.Остатки(&Период, )

Эта таблица уже содержит сгруппированные данные на указанный момент времени. Параметр &Период позволяет нам получать остатки на любую дату в прошлом. Если его не указать, система выдаст актуальные остатки на текущий момент.

Шаг 2. Выбор стратегии объединения данных

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

Способ А: Использование ПОЛНОГО СОЕДИНЕНИЯ

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


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

Обратите внимание на использование функции ЕСТЬNULL. Проанализируем причину: если в одной из таблиц нет соответствующей записи, система вернет значение NULL. Математические операции с NULL всегда дают NULL, поэтому мы принудительно заменяем пустые значения на 0 для корректных расчетов.

Способ Б: Использование объединения (ОБЪЕДИНИТЬ ВСЕ)

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


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

СГРУППИРОВАТЬ ПО
    ОстаткиИРезервы.Склад,
    ОстаткиИРезервы.Товар

Шаг 3. Настройка Системы компоновки данных (СКД)

Выясним, как собрать этот запрос в полноценный отчет через конструктор СКД. Создадим новый объект типа «Отчет» и откроем схему компоновки данных.

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

Шаг 4. Оформление структуры отчета

Перейдем на закладку «Настройки». Разберем, как сделать отчет удобным для пользователя:

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

Резюме

Мы рассмотрели основной механизм создания отчета по остаткам и резервам. Подведем итоги: работайте с виртуальными таблицами .Остатки, используйте ЕСТЬNULL для обработки пустых значений и применяйте ОБЪЕДИНИТЬ ВСЕ для наиболее стабильной работы запроса. С помощью вычисляемых полей в СКД вы сможете легко добавить любую дополнительную аналитику, такую как процент резерва или дефицит товаров.

← На главную