Почему не обновляется СуммаДокумента и неверно рассчитывается вознаграждение?

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

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

Разберем причины возникновения проблемы

Основная сложность заключается в архитектуре управляемых форм. В отличие от обычных форм, где многие процессы могли происходить «автоматом», здесь все вычисления нужно инициировать явно. Когда пользователь меняет цену или количество в строке, система пересчитывает сумму только в этой конкретной строке (если вы вызвали процедуру расчета), но реквизит СуммаДокумента, находящийся на уровне шапки документа, остается неизменным. Он не «знает», что данные в табличной части изменились.

Когда ваша серверная процедура РассчётВознаграждения обращается к Объект.СуммаДокумента, она получает либо пустое значение, либо устаревшую цифру. Использование отладчика позволяет убедиться в этом: при пошаговом выполнении кода вы увидите, что Объект.СуммаДокумента не содержит актуального итога по всей табличной части.

Шаг 1: Правильный расчет итоговой суммы

Для того чтобы получить корректную сумму документа, необходимо просуммировать значения всех строк табличной части. В 1С для этого существует эффективный метод объекта — Итог(). Рассмотрим, как применить его на практике:


// В серверной процедуре расчета
// Предположим, что табличная часть называется ПереченьНоменклатуры, 
// а поле с суммой строки — Сумма.
Объект.СуммаДокумента = Объект.ПереченьНоменклатуры.Итог("Сумма");

Этот код необходимо вызывать до того, как вы начнете вычислять вознаграждение. Только после того, как реквизит шапки Объект.СуммаДокумента будет актуализирован, вы сможете корректно рассчитать процент.

Шаг 2: Структурируем процедуру расчета

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


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

Как проверить работу кода

Если после внесения изменений вы все еще сомневаетесь в том, какие данные видит система, используйте простой инструмент отладки — Сообщить(). Это «старая добрая» практика, которая помогает быстро выявить проблему:


&НаСервере
Процедура РассчётВознаграждения()
    // Тестовая печать для проверки значения перед расчетом
    Сообщить("Текущая СуммаДокумента: " + Объект.СуммаДокумента);
    
    // ... дальнейшая логика расчета ...
КонецПроцедуры

Важные советы по доработке

  1. Используйте отладчик: Не полагайтесь на догадки. Ставьте точки останова в процедурах ПриИзменении и смотрите, в какой именно момент переменная получает «0».
  2. Место вызова: Помните, что процедуру расчета нужно вызывать не только при изменении цены, но и при изменении количества, а также при удалении строк из табличной части.
  3. Программный вызов: Убедитесь, что после расчета на сервере форма понимает, что данные изменились. Хотя при работе с объектом Объект (который является основной формой данных) изменения подхватываются автоматически, иногда полезно проверить свойства элементов формы в конфигураторе.

Реализовав пересчет методом Итог() перед математическими операциями, вы навсегда избавитесь от проблемы «нулевого вознаграждения» и обеспечите корректную работу вашего документа.

← На главную