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