Как обработать данные временных таблиц и выполнить сложные расчеты перед записью движений в 1С:ERP 2.5?

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

При работе с 1С:ERP 2.5 разработчики часто сталкиваются с ситуацией, когда стандартного механизма проведения через один общий запрос в модуле менеджера документа оказывается недостаточно. Типичный пример — необходимость распределения сумм пропорционально какому-либо показателю с корректным округлением "копеек". Реализовать такой алгоритм чисто средствами языка запросов крайне сложно, а иногда и невозможно. Рассмотрим, как правильно встроиться в архитектуру ERP для решения этой задачи, не нарушая логику системы и сохраняя производительность.

Анализируем архитектуру проведения ERP 2.5

В современных версиях ERP проведение документа разделено на несколько четких этапов. Основная логика сосредоточена в модуле менеджера документа, в процедурах ИнициализироватьДанныеДокумента и ПодготовитьДанныеДляПроведения. Система формирует структуру ТаблицыДляДвижений, которая в конечном итоге превращается в набор записей регистров. Наша задача — перехватить данные между моментом их формирования запросом и моментом физической записи в базу данных.

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

Способ 1. Использование процедуры ОтразитьДвижения в модуле менеджера регистра

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

Рассмотрим пример кода, который можно внедрить в модуль менеджера регистра (или использовать расширение):


Процедура ОтразитьДвижения(ТаблицыДляДвижений, Движения, Отказ) Экспорт
    
    Если Отказ Тогда
        Возврат;
    КонецЕсли;
    
    // Проверяем наличие нашей таблицы в структуре
    Если ТаблицыДляДвижений.Свойство("ТаблицаРасчетов") Тогда
        // Вызываем процедуру постобработки
        РаспределитьКопейкиПоАлгоритму(ТаблицыДляДвижений.ТаблицаРасчетов);
    КонецЕсли;
    
    // Далее следует стандартный механизм записи движений
    ...
КонецПроцедуры

В процедуре РаспределитьКопейкиПоАлгоритму мы работаем с данными как с обычной ТаблицейЗначений. Здесь мы можем использовать циклы, условия и любые сложные математические функции 1С, чтобы дозаполнить или изменить суммы перед их записью в регистр.

Способ 2. Предварительный расчет и передача данных через параметры

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

Разберем по шагам, как это реализовать:

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

Посмотрим на пример подготовки параметров:


// В модуле менеджера документа
Процедура ЗаполнитьПараметрыИнициализации(ПараметрыИнициализации, ДокументСсылка, ДополнительныеСвойства)
    
    // Выполняем сложный расчет копеек в коде
    ТаблицаСумм = РассчитатьРаспределениеСумм(ДокументСсылка);
    
    // Передаем таблицу как параметр запроса
    ПараметрыИнициализации.Вставить("ТаблицаСложныхРасчетов", ТаблицаСумм);
    
КонецПроцедуры

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

Способ 3. Работа с модулями локализации

В ERP 2.5 активно используется механизм локализации движений. Если ваша задача касается типовых регистров (например, расчеты с поставщиками или товары на складах), проанализируйте модули типа ЛокализацияДвиженийТиповые. Система предоставляет программный интерфейс для модификации текста запроса и структуры временных таблиц "на лету".

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

Использование стандартных функций распределения

Когда речь идет о распределении сумм с копейками, важно помнить, что в 1С уже реализованы надежные алгоритмы. Проанализируем функцию ОбщегоНазначенияУТ.РаспределитьСуммуПропорционально(). Она автоматически учитывает разницу округления и "скидывает" лишнюю копейку на последнюю строку (или по иному правилу), что гарантирует сходимость итогов.

Рассмотрим пример использования при постобработке таблицы значений:


// Пример распределения суммы 100 руб. пропорционально количеству
МассивМножителей = ТаблицаДвижений.ВыгрузитьКолонку("Количество");
МассивРезультатов = ОбщегоНазначенияУТ.РаспределитьСуммуПропорционально(100, МассивМножителей);

Для Ит = 0 По ТаблицаДвижений.Количество() - 1 Цикл
    ТаблицаДвижений[Ит].Сумма = МассивРезультатов[Ит];
КонецЦикла;

Рекомендации по выбору метода

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

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

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

← На главную