При разработке конфигураций на платформе 1С:Предприятие часто возникает задача автоматического расчета итоговых показателей документа. Если вы столкнулись с тем, что после изменения данных в строках табличной части расчет вознаграждения выдает «0» или неверную сумму, давайте разберем, в чем кроется причина и как правильно организовать алгоритм пересчета.
Основная сложность заключается в архитектуре управляемых форм. В отличие от обычных форм, где многие процессы могли происходить «автоматом», здесь все вычисления нужно инициировать явно. Когда пользователь меняет цену или количество в строке, система пересчитывает сумму только в этой конкретной строке (если вы вызвали процедуру расчета), но реквизит СуммаДокумента, находящийся на уровне шапки документа, остается неизменным. Он не «знает», что данные в табличной части изменились.
Когда ваша серверная процедура РассчётВознаграждения обращается к Объект.СуммаДокумента, она получает либо пустое значение, либо устаревшую цифру. Использование отладчика позволяет убедиться в этом: при пошаговом выполнении кода вы увидите, что Объект.СуммаДокумента не содержит актуального итога по всей табличной части.
Для того чтобы получить корректную сумму документа, необходимо просуммировать значения всех строк табличной части. В 1С для этого существует эффективный метод объекта — Итог(). Рассмотрим, как применить его на практике:
// В серверной процедуре расчета
// Предположим, что табличная часть называется ПереченьНоменклатуры,
// а поле с суммой строки — Сумма.
Объект.СуммаДокумента = Объект.ПереченьНоменклатуры.Итог("Сумма");
Этот код необходимо вызывать до того, как вы начнете вычислять вознаграждение. Только после того, как реквизит шапки Объект.СуммаДокумента будет актуализирован, вы сможете корректно рассчитать процент.
Давайте соберем правильный алгоритм действий. Рекомендуется создать логически завершенную процедуру на сервере, которая выполняет обновление данных. Проанализируем пример:
&НаСервере
Процедура РассчётВознагражденияНаСервере()
// Сначала актуализируем общую сумму документа
Объект.СуммаДокумента = Объект.ПереченьНоменклатуры.Итог("Сумма");
// Теперь выполняем расчет вознаграждения, используя свежие данные
Если Объект.СуммаДокумента > 5000 Тогда
Объект.Вознаграждение = 0.15 * Объект.СуммаДокумента;
Иначе
Объект.Вознаграждение = 0.10 * Объект.СуммаДокумента;
КонецЕсли;
КонецПроцедуры
Если после внесения изменений вы все еще сомневаетесь в том, какие данные видит система, используйте простой инструмент отладки — Сообщить(). Это «старая добрая» практика, которая помогает быстро выявить проблему:
&НаСервере
Процедура РассчётВознаграждения()
// Тестовая печать для проверки значения перед расчетом
Сообщить("Текущая СуммаДокумента: " + Объект.СуммаДокумента);
// ... дальнейшая логика расчета ...
КонецПроцедуры
ПриИзменении и смотрите, в какой именно момент переменная получает «0».Объект (который является основной формой данных) изменения подхватываются автоматически, иногда полезно проверить свойства элементов формы в конфигураторе.Реализовав пересчет методом Итог() перед математическими операциями, вы навсегда избавитесь от проблемы «нулевого вознаграждения» и обеспечите корректную работу вашего документа.