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