Как правильно создать отчет по продажам с остатками в 1С, чтобы данные не «съезжали»?

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

Создание отчета, который одновременно показывает продажи (обороты) и остатки товаров на складах — одна из самых частых задач для разработчика 1С. Однако начинающие специалисты часто сталкиваются с проблемой: при попытке вывести данные в разрезе регистратора или при наложении определенных фильтров остатки начинают отображаться некорректно («съезжают» или задваиваются). В этой статье мы подробно разберем причины возникновения таких ошибок и рассмотрим надежные методы построения подобных отчетов.

Почему «едут» остатки при использовании виртуальных таблиц?

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

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

Метод 1. Использование «ОБЪЕДИНИТЬ ВСЕ» вместо соединений

Одной из самых распространенных ошибок является использование ЛЕВОЕ СОЕДИНЕНИЕ между таблицей продаж и таблицей остатков. Если у одного товара за день было 10 продаж, то при соединении с таблицей остатков (где остаток один на конец дня), строка с остатком продублируется 10 раз. При суммировании в отчете итоговый остаток увеличится в 10 раз. Чтобы избежать этого, рекомендуется использовать конструкцию ОБЪЕДИНИТЬ ВСЕ (UNION ALL).

Разберем этот метод по шагам. Мы создаем запрос, который выбирает данные из двух разных источников и объединяет их в одну структуру с идентичными полями. Посмотрим на пример логики построения запроса:


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

ОБЪЕДИНИТЬ ВСЕ

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

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

Метод 2. Использование временных таблиц (ВТ)

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

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

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

Метод 3. Правильная настройка ролей в СКД

Если вы используете Систему компоновки данных, крайне важно правильно настроить Роли полей. Даже если ваш запрос написан верно, СКД может неправильно рассчитать итоги, если не понимает природу данных. Выясним, как это настроить:

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

Это позволит СКД использовать специфические алгоритмы расчета. Например, при группировке по складам остатки будут суммироваться, а при выводе детальных записей за разные даты — нет (будет браться значение на последнюю дату), что исключит дублирование показателей.

Метод 4. Периодичность «Авто» и ручная фильтрация регистратора

Как отмечалось в обсуждении на форуме, использование периодичности Регистратор в виртуальной таблице часто избыточно и опасно. Посмотрим на альтернативный вариант — использование периодичности Авто.

Рассмотрим ситуацию: нам нужно вывести продажи только по определенному документу, но сохранить общий остаток. Вместо наложения фильтра в параметрах виртуальной таблицы, мы можем использовать конструкцию ВЫБОР в тексте запроса:


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

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

Важные рекомендации по оптимизации

Работая с большими объемами данных в регистрах ВыручкаИСебестоимостьПродаж или ТоварыНаСкладах, помните о следующих правилах:

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

← На главную