Как распределить сумму оплаты по нескольким строкам в 1С

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

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

Метод 1. Последовательное распределение по порядку (FIFO)

С точки зрения методики бухгалтерского и управленческого учета наиболее корректным считается разнесение поступающих платежей по датам возникновения задолженности или по очередности документов в таблице. Проанализируем алгоритм последовательного погашения:

  1. Оператор вводит общую сумму выписки в шапке документа или специальном поле ввода.
  2. Программа обнуляет текущие распределенные суммы во всех строках табличной части.
  3. Циклом обходится коллекция строк: если оставшаяся распределяемая сумма больше или равна сумме строки, строка закрывается полностью; если оставшаяся сумма меньше сумм строки, в строку записывается остаток, а распределение завершается.

Рассмотрим пример реализации такого алгоритма в коде 1С:


ОстатокРаспределения = ОбщаяСуммаОплаты;

Для Каждого СтрокаТаблицы Из Объект.Платежи Цикл
    Если ОстатокРаспределения <= 0 Тогда
        СтрокаТаблицы.СуммаОплаты = 0;
        Продолжить;
    КонецЕсли;
    
    СуммаКРаспределению = Мин(СтрокаТаблицы.СуммаДокумента, ОстатокРаспределения);
    СтрокаТаблицы.СуммаОплаты = СуммаКРаспределению;
    
    ОстатокРаспределения = ОстатокРаспределения - СуммаКРаспределению;
КонецЦикла;

Преимущества метода: простота реализации, высокий быстродействие, отсутствие риска зависания системы при большом количестве строк.

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

Метод 2. Подбор точного совпадения сумм (Задача о рюкзаке)

Если требуется найти среди множества строк именно те, сумма которых в точности равна введенному значению (без частичного гашения), мы сталкиваемся с комбинаторной задачей о сумме подмножеств (Subset Sum Problem). Каждая строка либо полностью входит в искомый набор (значение 1), либо пропускается (значение 0).

Проанализируем задачу математически: для списка строк с суммами A1, A2, ..., AN нужно найти такие бинарные коэффициенты Xi ∈ {0, 1}, чтобы выдерживалось равенство:

СУММА(Ai * Xi) = B, где B — искомая сумма платежа.

Для небольшого количества строк (до 15–20 элементов) можно применить итеративный или рекурсивный перебор комбинаций. Посмотрим, как написать рекурсивный поиск комбинации в 1С:


Функция НайтиКомбинацию(МассивСумм, Индекс, ТекущаяСумма, ЦелеваяСумма, ВыбранныеИндексы)
    Если ТекущаяСумма = ЦелеваяСумма Тогда
        Возврат Истина;
    КонецЕсли;
    
    Если ТекущаяСумма > ЦелеваяСумма Или Индекс > МассивСумм.В Граница() Тогда
        Возврат Ложь;
    КонецЕсли;
    
    // Вариант 1: включаем текущую строку в набор
    ВыбранныеИндексы.Добавить(Индекс);
    Если НайтиКомбинацию(МассивСумм, Индекс + 1, ТекущаяСумма + МассивСумм[Индекс], ЦелеваяСумма, ВыбранныеИндексы) Тогда
        Возврат Истина;
    КонецЕсли;
    
    // Вариант 2: пропускаем текущую строку
    ВыбранныеИндексы.Удалить(ВыбранныеИндексы.Количество() - 1);
    Возврат НайтиКомбинацию(МассивСумм, Индекс + 1, ТекущаяСумма, ЦелеваяСумма, ВыбранныеИндексы);
КонецФункции

При вызове данной функции передается исходный массив сумм строк и пустой массив ВыбранныеИндексы. Если функция возвращает Истина, в массиве ВыбранныеИндексы будут содержаться номера элементов, сумма которых точно дает запрашиваемый результат.

Ограничения платформы 1С и пути оптимизации

При реализации точного подбора сумм в реальных базах данных следует учитывать особенности работы платформы 1С:

← На главную