Почему некорректно считаются итоги в СКД при использовании выражения представления и как это исправить?

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

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

В чем суть проблемы? Анализируем поведение СКД

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

РАЗНОСТЬДАТ(ДатаНачала, ДатаОкончания, "СЕКУНДА")

Чтобы вывести эти секунды пользователю в удобном и красивом виде (например, "2 дн. 4 ч. 15 мин."), разработчик заполняет колонку Выражение представления для этого поля, вызывая функцию общего модуля:

ПродолжительностьВДнях(ПродолжительностьРемонта)

Далее это же поле добавляется на вкладку Ресурсы, чтобы получить суммарное время ремонта по группировкам. В поле выражения ресурса пишется формула:

ПродолжительностьВДнях(Сумма(ПродолжительностьРемонта))

На первый взгляд логика безупречна. Однако при формировании отчета оказывается, что общие итоги и итоги по группировкам рассчитываются неверно. Вместо суммы секунд всех ремонтов, преобразованной в дни, СКД выводит представление, соответствующее только первой строке в группировке. Если же убрать выражение представления у вычисляемого поля, то числовые итоги (секунды) начинают суммироваться абсолютно правильно.

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

Проанализируем доступные и наиболее эффективные варианты решения этой проблемы.

Решение 1. Перенос форматирования в выражение ресурса

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

Выполним следующие шаги:

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

При таком подходе СКД сначала математически точно сложит все секунды на уровне группировки, а затем передаст полученное итоговое число в функцию общего модуля ПродолжительностьВДнях, которая вернет красивую строку для вывода в отчет.

Решение 2. Разделение данных на два независимых поля

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

Рассмотрим этот алгоритм:

  1. Создадим первое вычисляемое поле с именем ПродолжительностьЧисло. В выражении укажем разность дат в секундах. Это поле мы будем использовать только для математических расчетов и вывода итогов.
  2. Создадим второе вычисляемое поле с именем ПродолжительностьСтрока. В выражении представления этого поля укажем вызов нашей функции общего модуля: ПродолжительностьВДнях(ПродолжительностьЧисло).
  3. На вкладке Ресурсы добавим только поле ПродолжительностьЧисло с выражением: ПродолжительностьВДнях(Сумма(ПродолжительностьЧисло))
  4. В настройках варианта отчета на вкладке Выбранные поля для детальных записей выведем поле ПродолжительностьСтрока, а для группировок — ресурс ПродолжительностьЧисло.

Этот способ позволяет избежать конфликтов типов в СКД, так как строковое представление применяется только там, где это действительно необходимо, не ломая математику суммирования.

Решение 3. Использование макетов оформления СКД

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

Разберем по шагам, как настроить макет оформления для вывода представления:

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

При формировании отчета СКД выполнит все арифметические операции в числовом формате, а на этапе рендеринга таблицы перехватит значение ресурса, передаст его в макет и отобразит результат работы функции общего модуля. Это гарантирует максимальную производительность и корректность расчетов.

Решение 4. Расчет представления средствами СКД (без общих модулей)

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

Для простых вычислений и приведения секунд к эквиваленту даты/времени можно использовать следующее выражение в СКД:


ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), "Секунда", РАЗНОСТЬДАТ(ДатаНачала, ДатаОкончания, "Секунда"))

Полученное значение будет иметь тип Дата. В условном оформлении или в формате самого поля мы можем задать маску отображения, например, ДФ='ЧЧ:мм:сс'. Это позволит вывести время красиво, а СКД сможет без проблем агрегировать такие данные на уровне ресурсов.

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

← На главную