В практике разработки на платформе «1С:Предприятие» стандартным инструментом для учета взаиморасчетов является регистр накопления остатков. Однако существуют задачи, в которых архитектурно оправдано использование именно оборотного регистра. Например, когда нам не требуется оперативный контроль остатков в реальном времени, но важен детальный многомерный анализ оборотов или когда объем данных настолько велик, что хранение остатков в разрезе всех измерений становится слишком ресурсозатратным.
Рассмотрим подробнее ситуацию, когда по условию задачи нам необходимо использовать оборотный регистр для учета взаиморасчетов, где документ «Реализация» должен фиксировать увеличение долга (условный «приход»), а «Банковская выписка» — его погашение (условный «расход»). Поскольку в оборотном регистре нет системного понятия ВидДвиженияНакопления (Приход/Расход), разберем три основных способа реализации этой задачи.
Проанализируем самый распространенный подход, который часто встречается в типовых конфигурациях (например, в регистре «Движения денежных средств» в УПП). Чтобы разделить потоки данных, мы можем добавить в регистр измерение или реквизит, указывающий на характер операции.
Алгоритм действий:
ВидДвижения. Типом данных может выступать ПеречислениеСсылка.ВидыДвиженийВзаиморасчетов (с значениями «УвеличениеДолга» и «ПогашениеДолга»).Пример программной записи для документа «Реализация»:
Движение = Движения.ВзаиморасчетыОбороты.Добавить();
Движение.Период = Объект.Дата;
Движение.Контрагент = Объект.Контрагент;
Движение.Сумма = Объект.СуммаДокумента;
Движение.ВидДвижения = Перечисления.ВидыДвиженийВзаиморасчетов.УвеличениеДолга;
Для документа «Банковская выписка» код будет аналогичным, но с другим значением перечисления. Этот метод удобен тем, что в отчетах мы можем легко группировать данные по этому измерению, видя структуру оборотов в чистом виде.
Выясним причину, по которой этот метод считается наиболее «бухгалтерским» и прозрачным. Вместо одного ресурса Сумма мы создаем два: СуммаПриход и СуммаРасход (или Дебет и Кредит).
Преимущества этого подхода:
Пример записи в регистр при реализации:
Движение = Движения.ВзаиморасчетыОбороты.Добавить();
Движение.Период = Объект.Дата;
Движение.СуммаПриход = Объект.СуммаДокумента;
Движение.СуммаРасход = 0;
Такой подход минимизирует ошибки при сторнировании операций, так как сторно всегда будет записываться с минусом в ту же колонку, не искажая обороты противоположной стороны.
Посмотрим на самый лаконичный, но требующий внимательности метод. Мы оставляем один ресурс Сумма, но договариваемся, что увеличение долга пишется с плюсом, а погашение — с минусом.
Как это реализуется программно:
// В документе оплаты
Движение = Движения.ВзаиморасчетыОбороты.Добавить();
Движение.Сумма = -Объект.СуммаОплаты; // Записываем отрицательное число
Этот способ позволяет получить текущее сальдо простым суммированием ресурса за весь период. Однако у него есть существенный недостаток: в стандартных отчетах будет сложно разделить «чистый» оборот продаж от «чистого» оборота оплат, так как они перемешаны в одном ресурсе.
Разберем, почему иногда разработчики намеренно уходят от регистров остатков. Важным моментом является механизм хранения итогов. Регистры остатков хранят итоги на конец каждого месяца по всем комбинациям измерений, которые когда-либо имели ненулевой остаток. Если в базе много «брошенных» мелких остатков (копейки из-за округлений), таблица итогов начинает «раздуваться», что замедляет запись новых движений и расчет итогов.
Оборотные регистры работают иначе:
Агрегаты. Это позволяет системе заранее рассчитывать итоги в различных разрезах (например, только по «Организации» без «Контрагента»). Это значительно ускоряет работу аналитических отчетов на больших объемах данных.Важное ограничение: Помните, что у оборотного регистра нет виртуальной таблицы Остатки. Если вы попытаетесь рассчитать «остаток долга» на текущую дату через таблицу Обороты, системе придется просуммировать все движения с самого начала ведения учета. Для больших баз это недопустимо. В таких случаях остаток обычно получают либо из отдельного регистра остатков, либо путем периодического «закрытия» оборотов (свертки) специальными документами.
Таким образом, использование оборотного регистра для взаиморасчетов — это мощный инструмент для систем с высокой нагрузкой и сложной аналитикой, если правильно выбрать способ разделения движений и учитывать особенности работы виртуальных таблиц.