Как вывести итог по нечисловой колонке в подвал таблицы в 1С?

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

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

Причины ограничения платформы

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

Несмотря на то, что флаг автоматического итога для колонки отключен, сама строка подвала у табличного поля может отображаться при установленном свойстве таблицы Подвал = Истина. Это дает нам возможность программно рассчитать нужное значение и передать его в ячейку подвала.

Способ 1. Программный подсчет в цикле для обычных форм

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

Посмотрим на пример процедуры подсчета количества выходов по дням месяца:


Процедура РассчитатьИтогиТабеля()
    
    // Включаем отображение подвала у элемента формы
    ЭлементыФормы.Табель.Подвал = Истина;
    
    // Инициализируем структуру или переменные счетчиков
    СчетчикиДней = Новый Массив(32);
    Для Индекс = 1 По 31 Цикл
        СчетчикиДней[Индекс] = 0;
    КонецЦикла;
    
    // Обходим строки табличной части
    Для Каждого Стр Из Табель Цикл
        Для День = 1 По 31 Цикл
            ИмяКолонки = "День" + День;
            Если ЗначениеЗаполнено(Стр[ИмяКолонки]) Тогда
                СчетчикиДней[День] = СчетчикиДней[День] + 1;
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;
    
    // Выводим полученные значения в подвал соответствующих колонок
    Для День = 1 По 31 Цикл
        ИмяКолонки = "День" + День;
        ЭлементыФормы.Табель.Колонки[ИмяКолонки].ТекстПодвала = Формат(СчетчикиДней[День], "ЧН=0");
        ЭлементыФормы.Табель.Колонки[ИмяКолонки].ГоризонтальноеПоложениеВПодвале = ПоложениеТекста.Право;
    КонецЦикла;
    
КонецПроцедуры

Оптимизация событийной модели

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

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

  1. При открытии формы (событие ПриОткрытии) — для первичного заполнения подвала при загрузке данных.
  2. При изменении значения в ячейке (событие ПриИзменении поля ввода колонки) — пересчитывает итог сразу после выбора значения пользователем.
  3. При изменении состава строк (события ПослеУдаления, ПриОкончанииРедактированияСтроки) — обновляет итоги при удалении или добавлении сотрудников.

Способ 2. Расчет итогов с помощью запроса

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

Рассмотрим пример формирования запроса к временной таблице:


Процедура РассчитатьИтогиЗапросом()
    
    Запрос = Новый Запрос;
    Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
    
    // Передаем текущие данные таблицы в запрос
    Запрос.Текст = 
        "ВЫБРАТЬ *
        |ПОМЕСТИТЬ ВТ_Табель
        |ИЗ &ТаблицаТабеля КАК ТаблицаТабеля;
        |
        |ВЫБРАТЬ
        |   СУММА(ВЫБОР КОГДА ВТ.День1 <> ЗНАЧЕНИЕ(Справочник.Магазины.ПустаяСсылка) ТОГДА 1 ИНАЧЕ 0 КОНЕЦ) КАК День1,
        |   СУММА(ВЫБОР КОГДА ВТ.День2 <> ЗНАЧЕНИЕ(Справочник.Магазины.ПустаяСсылка) ТОГДА 1 ИНАЧЕ 0 КОНЕЦ) КАК День2
        |ИЗ
        |   ВТ_Табель КАК ВТ";
        
    Запрос.УстановитьПараметр("ТаблицаТабеля", Табель.Выгрузить());
    
    Выборка = Запрос.Выполнить().Выбрать();
    Если Выборка.Следующий() Тогда
        ЭлементыФормы.Табель.Колонки.День1.ТекстПодвала = Строка(Выборка.День1);
        ЭлементыФормы.Табель.Колонки.День2.ТекстПодвала = Строка(Выборка.День2);
    КонецЕсли;
    
КонецПроцедуры

Особенности реализации в Управляемых формах

В управляемом интерфейсе прямое свойство ТекстПодвала у элемента колонки таблицы формы отсутствует. Для вывода произвольных итогов используется другой механизм:

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

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

← На главную