Как реализовать логику прихода и расхода в оборотном регистре накопления 1С?

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

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

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

Способ 1. Использование дополнительного измерения или реквизита

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

Алгоритм действий:

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

Пример программной записи для документа «Реализация»:


Движение = Движения.ВзаиморасчетыОбороты.Добавить();
Движение.Период = Объект.Дата;
Движение.Контрагент = Объект.Контрагент;
Движение.Сумма = Объект.СуммаДокумента;
Движение.ВидДвижения = Перечисления.ВидыДвиженийВзаиморасчетов.УвеличениеДолга;

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

Способ 2. Использование двух раздельных ресурсов (Дебет и Кредит)

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

Преимущества этого подхода:

Пример записи в регистр при реализации:


Движение = Движения.ВзаиморасчетыОбороты.Добавить();
Движение.Период = Объект.Дата;
Движение.СуммаПриход = Объект.СуммаДокумента;
Движение.СуммаРасход = 0;

Такой подход минимизирует ошибки при сторнировании операций, так как сторно всегда будет записываться с минусом в ту же колонку, не искажая обороты противоположной стороны.

Способ 3. Математический метод (Знак значения)

Посмотрим на самый лаконичный, но требующий внимательности метод. Мы оставляем один ресурс Сумма, но договариваемся, что увеличение долга пишется с плюсом, а погашение — с минусом.

Как это реализуется программно:


// В документе оплаты
Движение = Движения.ВзаиморасчетыОбороты.Добавить();
Движение.Сумма = -Объект.СуммаОплаты; // Записываем отрицательное число

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

Архитектурные нюансы и производительность

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

Оборотные регистры работают иначе:

  1. Итоги по периодам: Они хранят обороты за календарные периоды (обычно месяц). Если в конкретном месяце движений по контрагенту не было, записи в таблице итогов за этот месяц просто не будет.
  2. Механизм агрегатов: Для оборотных регистров можно настраивать Агрегаты. Это позволяет системе заранее рассчитывать итоги в различных разрезах (например, только по «Организации» без «Контрагента»). Это значительно ускоряет работу аналитических отчетов на больших объемах данных.
  3. Отсутствие блокировок остатков: При записи в оборотный регистр платформа не выполняет проверку на отрицательные остатки и не блокирует таблицу итогов так жестко, как при работе с остатками, что повышает параллельность работы пользователей.

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

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

← На главную