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