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