Как получить корректные остатки при фильтрации по реквизитам регистратора в 1С

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

В практике разработки на платформе 1С:Предприятие часто возникает задача: получить отчет по остаткам и оборотам, но с условием по реквизиту, которого нет в измерениях регистра. Например, нужно увидеть движение денежных средств в разрезе подразделений, но в типовой конфигурации Подразделение является лишь реквизитом документа-регистратора, а не измерением регистра накопления.

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

Анализ проблемы: почему остатки «врут»

Разберем типичный пример запроса, который на первый взгляд кажется логичным, но выдает ошибочные цифры начального и конечного остатков:


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

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

  1. Выбирает остатки по всем измерениям (например, Касса, Валюта) на начало периода.
  2. Выбирает обороты за период, которые соответствуют условию (конкретной статье или подразделению).
  3. Пытается сопоставить эти данные.

Проблема в том, что в остатке «сидят» суммы, сформированные сотнями документов прошлых периодов. Эти документы имели разные статьи и подразделения. Поскольку подразделение не является измерением, система не знает, какая часть остатка в 1 000 000 рублей относится к «Подразделению А», а какая к «Подразделению Б». Накладывая фильтр в секции ГДЕ, мы просто отсекаем записи, не учитывая, что остаток должен был сформироваться из всех предыдущих движений. В итоге оборот за месяц будет верным, а начальный остаток — либо равен полному остатку по всем подразделениям, либо (что чаще при использовании периодичности) будет рассчитан только на основании документов, попавших в выборку, что методологически неверно.

Решение №1: Расчет остатка через обороты с начала времен

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

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


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

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

Решение №2: Оптимизация через разницу с текущим остатком

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

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

Решение №3: Изменение структуры регистра (рекомендуемый путь)

Если заказчик настаивает на регулярном получении отчетов по подразделениям с корректными остатками, самым правильным и производительным решением будет добавление измерения в регистр накопления.

Рассмотрим шаги по реализации:

  1. Включите возможность изменения конфигурации (сохранив поддержку).
  2. Добавьте новое измерение Подразделение в регистр ДенежныеСредства.
  3. Настройте заполнение этого измерения в процедурах проведения документов.
  4. Выполните обработку по заполнению нового измерения в исторических данных.

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

Работа в СКД (Система компоновки данных)

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

Рассмотрим подробнее:

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

Методологическая справка по УНФ

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

Если ваша задача — контролировать остатки денежных средств в разрезе бизнес-единиц, убедитесь, что в программе подразделения не соответствуют разным кассам или банковским счетам. Если соответствуют — просто фильтруйте по измерениям БанковскийСчет или Касса, и проблема решится сама собой без сложного программирования.

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

← На главную