Как работает свертка таблицы значений при суммировании колонки с типом Булево

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

В практике разработчика 1С часто возникает задача агрегации данных в объекте ТаблицаЗначений. Метод Свернуть() является стандартным инструментом для группировки строк и суммирования ресурсов. Однако, когда дело доходит до колонок с типом Булево, поведение платформы может показаться неочевидным. Разберем детально, что происходит при попытке «просуммировать» логические значения и какие альтернативные способы существуют для решения более сложных задач группировки.

Стандартная логика свертки для типа Булево

Проанализируем базовый механизм работы метода Свернуть(). Если в параметре КолонкиСуммирования указана колонка с типом Булево, платформа не выдает ошибку, а применяет специфическую логику. На практике это работает как логическая операция ИЛИ по всем строкам, входящим в группу.

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

Рассмотрим этот процесс на примере кода:


// Создаем таблицу значений
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Группа", Новый ОписаниеТипов("Строка"));
ТЗ.Колонки.Добавить("Флаг", Новый ОписаниеТипов("Булево"));

// Заполняем данными
НоваяСтрока = ТЗ.Добавить();
НоваяСтрока.Группа = "Объект1";
НоваяСтрока.Флаг = Ложь;

НоваяСтрока = ТЗ.Добавить();
НоваяСтрока.Группа = "Объект1";
НоваяСтрока.Флаг = Истина;

// Выполняем свертку
ТЗ.Свернуть("Группа", "Флаг");

// В результате для Группы "Объект1" Флаг будет равен Истина (Ложь ИЛИ Истина)

Важность строгой типизации колонок

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

Посмотрим на важные нюансы:

  1. Если в колонке встречаются значения NULL или Неопределено, поведение метода зависит от версии платформы, но чаще всего это приводит к ошибке преобразования типов при суммировании.
  2. Для обеспечения безопасности операции всегда явно указывайте тип колонки при создании ТаблицыЗначений через объект ОписаниеТипов.

Подсчет количества истинных значений

Часто разработчику требуется не логическое «ИЛИ», а именно количество строк, где установлено значение Истина. Метод Свернуть() не умеет выполнять операцию КОЛИЧЕСТВО для булевых данных напрямую. В этом случае мы должны применить обходной путь — приведение к числовому типу.

Разберем алгоритм действий по шагам:

  1. Добавим в таблицу вспомогательную числовую колонку.
  2. Пройдем циклом по таблице и установим в новой колонке 1, если флаг равен Истина, и 0 в противном случае.
  3. Выполним свертку по новой числовой колонке.

Пример реализации такого подхода:


// Добавляем колонку для счета
ТЗ.Колонки.Добавить("Счетчик", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10, 0)));

Для Каждого Стр Из ТЗ Цикл
    Стр.Счетчик = ?(Стр.Флаг = Истина, 1, 0);
КонецЦикла;

// Сворачиваем по колонке Счетчик
ТЗ.Свернуть("Группа", "Счетчик");
// Теперь в колонке Счетчик содержится количество попаданий Истина

Использование запросов к таблице значений

Если задача агрегации данных выходит за рамки простого суммирования (например, нужно одновременно получить МИНИМУМ, МАКСИМУМ и КОЛИЧЕСТВО), использование метода Свернуть() становится неэффективным. Наиболее профессиональным подходом в 1С v8 является использование Запроса к временной таблице.

Проанализируем преимущества этого метода:

Пример использования запроса для обработки ТаблицыЗначений:


МенеджерВТ = Новый МенеджерВременныхТаблиц;
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МенеджерВТ;

// Передаем таблицу в запрос
Запрос.Текст = "ВЫБРАТЬ * ПОМЕСТИТЬ ВТ_Данные ИЗ &ТЗ КАК ТЗ";
Запрос.УстановитьПараметр("ТЗ", ТЗ);
Запрос.Выполнить();

// Выполняем группировку с нужными функциями
Запрос.Текст = 
"ВЫБРАТЬ
|	ВТ_Данные.Группа КАК Группа,
|	МАКСИМУМ(ВТ_Данные.Флаг) КАК ФлагИЛИ,
|	МИНИМУМ(ВТ_Данные.Флаг) КАК ФлагИ,
|	СУММА(ВЫБОР КОГДА ВТ_Данные.Флаг ТОГДА 1 ИНАЧЕ 0 КОНЕЦ) КАК КоличествоИстин
|ИЗ
|	ВТ_Данные КАК ВТ_Данные
|ГРУППИРОВАТЬ ПО
|	ВТ_Данные.Группа";

РезультатТЗ = Запрос.Выполнить().Выгрузить();

Ручной обход как альтернатива для малых таблиц

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

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


Функция ЕстьХотяБыОднаИстина(ТЗ, ИмяКолонки)
    Для Каждого Стр Из ТЗ Цикл
        Если Стр[ИмяКолонки] = Истина Тогда
            Возврат Истина;
        КонецЕсли;
    КонецЦикла;
    Возврат Ложь;
КонецФункции

Заключение и рекомендации

Подведем итоги нашего анализа. Метод Свернуть() — это мощный и быстрый инструмент, встроенный непосредственно в движок платформы 1С. Его поведение с типом Булево как логическое «ИЛИ» является штатным и может эффективно использоваться для схлопывания статусов или признаков в отчетности.

Основные выводы:

  1. Для получения логического ИЛИ смело используйте Свернуть() по булевой колонке.
  2. Обязательно проверяйте типизацию колонок перед сверткой, чтобы избежать ошибок рантайма.
  3. Для подсчета количества «Истин» преобразуйте булево в число 0/1 перед сверткой.
  4. Для сложной аналитики (минимумы, средние, сложные условия) всегда отдавайте предпочтение Запросам к временным таблицам.

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

← На главную