Как посчитать сумму выделенных строк в форме списка 1С на клиенте

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

В процессе разработки на платформе 1С:Предприятие 8.3 часто возникает задача предоставить пользователю возможность видеть итог (например, сумму документов или количество товара) по произвольно выбранным строкам в списке. При этом критически важно выполнять такие расчеты на стороне клиента, чтобы не создавать лишнюю нагрузку на сервер приложений и базу данных, особенно если в системе одновременно работают десятки или сотни пользователей через веб-клиент или медленные каналы связи.

В данной статье мы подробно разберем, как реализовать механизм подсчета суммы выделенных строк, проанализируем различные способы отслеживания событий выделения и рассмотрим технические нюансы, включая настройки динамического списка и кэширование данных.

Метод 1: Использование свойства ДанныеСтроки для динамического списка

Если ваша таблица на форме является Динамическим списком, то самый простой и эффективный способ получить данные выделенных строк на клиенте — это использование метода ДанныеСтроки(). Этот метод позволяет обратиться к полям строки, которые уже загружены в память клиента.

Рассмотрим алгоритм реализации. Сначала нам необходимо получить массив идентификаторов выделенных строк, а затем в цикле обойти их и просуммировать значения нужной колонки (аналогично тому, как реализуется флажок в динамическом списке). Пример кода для обработчика:


&НаКлиенте
Процедура ПересчитатьСуммуВыделенных()
    
    Перем Сумма;
    Сумма = 0;
    
    // Получаем массив идентификаторов выделенных строк
    ВыделенныеСтроки = Элементы.Список.ВыделенныеСтроки;
    
    Для Каждого ИдентификаторСтроки Из ВыделенныеСтроки Цикл
        
        // Получаем данные конкретной строки на клиенте
        Данные = Элементы.Список.ДанныеСтроки(ИдентификаторСтроки);
        
        // Проверяем, что данные доступны (могут быть не загружены в кэш)
        Если Данные <> Неопределено Тогда
            Сумма = Сумма + Данные.СуммаДокумента;
        КонецЕсли;
        
    КонецЦикла;
    
    // Выводим результат в реквизит формы, отображаемый в подвале или декорации
    ИтогПоВыделенным = Сумма;
    
КонецПроцедуры

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

Метод 2: Работа с таблицей значений (ДанныеФормыКоллекция)

Если же на форме отображается не динамический список, а обычная таблица (например, объектная таблица значений или табличная часть), подход немного меняется. Вместо метода динамического списка мы используем метод НайтиПоИдентификатору() самой коллекции данных формы.

Проанализируем пример для таблицы с именем Товары:


&НаКлиенте
Процедура РассчитатьИтогТаблицы()
    
    МассивИдентификаторов = Элементы.Товары.ВыделенныеСтроки;
    РезультатСумма = 0;
    
    Для Каждого ТекущийID Из МассивИдентификаторов Цикл
        
        // Поиск строки в источнике данных по ID
        СтрокаДанных = Объект.Товары.НайтиПоИдентификатору(ТекущийID);
        
        Если СтрокаДанных <> Неопределено Тогда
            РезультатСумма = РезультатСумма + СтрокаДанных.Сумма;
        КонецЕсли;
        
    КонецЦикла;
    
    ЭтаФорма.НадписьИтого = РезультатСумма;
    
КонецПроцедуры

Выбор подходящего события для пересчета

Одной из главных сложностей является определение момента, когда нужно запускать пересчет. Стандартные события формы ведут себя по-разному в зависимости от действий пользователя:

  1. ПриАктивизацииСтроки: Срабатывает при каждом клике на новую строку. Это самый популярный вариант. Однако у него есть существенный минус — это событие не срабатывает, когда пользователь выделяет несколько строк с помощью клавиатуры (Ctrl+A) или удерживая Shift, если при этом «активная» (текущая) строка не поменялась.
  2. ПриАктивизацииЯчейки: Работает аналогично предыдущему, но срабатывает чаще. Помогает более оперативно реагировать на перемещения пользователя.
  3. ПодключитьОбработчикОжидания: Наиболее надежный способ для отслеживания массового выделения. Мы можем раз в полсекунды проверять количество выделенных строк и, если оно изменилось, запускать пересчет.

Разберем реализацию через обработчик ожидания, который гарантированно «поймает» выделение всех строк через Ctrl+A:


&НаКлиенте
Перем мКоличествоВыделенных; // Глобальная переменная модуля клиента

&НаКлиенте
Процедура ПриОткрытии(Отказ)
    мКоличествоВыделенных = 0;
    // Запускаем таймер с интервалом 0.5 сек
    ПодключитьОбработчикОжидания("КонтрольВыделения", 0.5);
КонецПроцедуры

&НаКлиенте
Процедура КонтрольВыделения()
    
    ТекВыделено = Элементы.Список.ВыделенныеСтроки.Количество();
    
    // Если количество изменилось — пересчитываем
    Если ТекВыделено <> мКоличествоВыделенных Тогда
        ПересчитатьСуммуВыделенных(); // Вызов нашей функции расчета
        мКоличествоВыделенных = ТекВыделено;
    КонецЕсли;
    
КонецПроцедуры

Технические нюансы и ограничения

При реализации данного функционала следует учитывать несколько критических моментов, которые могут повлиять на корректность работы программы:

1. Кэширование данных: Метод ДанныеСтроки() работает только с теми данными, которые физически переданы с сервера на клиент. Динамический список подгружает данные порциями (обычно по 20–50 строк). Если пользователь выделит 1000 строк и прокрутит список вниз, часть данных в начале списка может быть вытеснена из кэша. В этом случае ДанныеСтроки() вернет Неопределено. Если для вашей задачи критична 100% точность на огромных выборках, расчет придется переносить на сервер, передавая туда массив ссылок.

2. Иерархические списки: Если в вашем списке включено отображение групп (иерархия), помните, что в массив ВыделенныеСтроки попадают и идентификаторы групп. У групп, как правило, нет реквизита «Сумма», поэтому при обходе массива обязательно делайте проверку на тип данных или наличие свойства, чтобы избежать ошибок выполнения.

3. Свойство ПутьКДаннымПодвала: Чтобы результат расчета выглядел эстетично, используйте стандартные возможности платформы. У колонки таблицы в свойствах есть поле ПутьКДаннымПодвала. Если вы укажете там имя реквизита формы (например, ИтогПоВыделенным), значение будет отображаться в нижней части таблицы в соответствующей колонке, что является стандартным поведением для продуктов на базе 1С.

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

Таким образом, комбинируя использование метода ДанныеСтроки() и обработчика ожидания, можно создать отзывчивый и производительный интерфейс, который позволит пользователям мгновенно получать итоговые данные по выделенным объектам без лишних обращений к базе данных.

← На главную