Как в СКД вывести длительность в секундах, если значение превышает 24 часа?

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

При разработке отчетов в системе компоновки данных (СКД) часто возникает задача вывести время выполнения операций или хронометраж, хранящийся в виде суммарного количества секунд. Стандартный прием с добавлением секунд к начальной дате через выражение ДобавитьКДате(ДатаВремя(1, 1, 1), "Секунда", Секунды) и применением формата времени ДЛФ=T отлично работает только в пределах одних суток. Как только сумма секунд превышает 86 400 (24 часа), результат сбрасывается на начало нового дня, и мы видим некорректные значения часов.

Выясним причину такого поведения платформы и подробно разберем несколько способов правильного вывода интервалов в формате ЧЧЧ:мм:сс или с выделением дней.

Почему стандартное форматирование даты сбрасывает часы

Проанализируем особенности платформы 1С:Предприятие. Тип данных Дата хранит абсолютную дату григорианского календаря и время дня, а не временной интервал (длительность). Когда мы прибавляем, например, 90 000 секунд к дате 0001-01-01 00:00:00, значение превращается в дату 0001-01-02 01:00:00. При применении маски ДЛФ=T или ЧЧ:мм:сс календарная часть отбрасывается, и отчет отображает всего лишь 01:00:00 вместо ожидаемых 25 часов.

В языке запросов также нет встроенной операции вычисления остатка от деления (%) и целочисленного деления. Поэтому попытки рассчитать часы через конструкцию ВЫРАЗИТЬ((Секунды / 3600) - 0.5 КАК ЧИСЛО(15, 0)) подвержены особенностям банковского округления платформы и часто дают расхождение на минуту или секунду на граничных значениях. Однако в СКД есть более точные и гибкие инструменты.

Способ 1. Использование языка выражений на вкладке «Ресурсы»

Рассмотрим самый удобный и быстрый способ, не требующий изменения конфигурации или усложнения текста запроса. В отличие от языка запросов 1С, язык выражений СКД поддерживает функцию получения целой части Цел(), оператор получения остатка от деления %, а также функцию Формат().

Перейдем на вкладку «Ресурсы» схемы компоновки данных. Для числового поля с секундами в колонке «Выражение» напишем расчет строкового представления от общей суммы секунд.

Если нам требуется получить непрерывный формат часов ЧЧЧ:мм:сс (где часы могут быть больше 24):


Формат(Цел(Сумма(Секунды) / 3600), "ЧЦ=10; ЧН=0; ЧГ=0") 
+ ":" + Формат(Цел((Сумма(Секунды) % 3600) / 60), "ЧЦ=2; ЧВН=; ЧГ=0") 
+ ":" + Формат(Сумма(Секунды) % 60, "ЧЦ=2; ЧВН=; ЧГ=0")

Если нам требуется детальный формат с выделением суток вида Дни д. ЧЧ:мм:сс:


Формат(Цел(Сумма(Секунды) / 86400), "ЧГ=0") + " д. " 
+ Формат(Цел((Сумма(Секунды) % 86400) / 3600), "ЧЦ=2; ЧВН=; ЧГ=0") 
+ ":" + Формат(Цел((Сумма(Секунды) % 3600) / 60), "ЧЦ=2; ЧВН=; ЧГ=0") 
+ ":" + Формат(Сумма(Секунды) % 60, "ЧЦ=2; ЧВН=; ЧГ=0")

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

  1. Параметр ЧВН= (выводить нули) гарантирует, что для значений минут и секунд меньше 10 будет обязательно добавлен ведущий ноль (например, 04 вместо 4).
  2. Параметр ЧГ=0 отключает группировку разрядов числа пробелами, исключая появление неразрывных пробелов внутри чисел.
  3. Агрегатная функция Сумма(...) обеспечивает правильный расчет: СКД сначала суммирует исходные секунды по группировке, и только затем выполняет математическое преобразование в строку.

Способ 2. Вызов экспортной функции модуля через СКД

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

Создадим или дополним функцию в общем модуле:


Функция ДлительностьВСтроку(Знач ВсегоСекунд) Экспорт

    Если ВсегоСекунд = 0 Или ВсегоСекунд = Неопределено Тогда
        Возврат "00:00:00";
    КонецЕсли;

    КоличествоДней = Цел(ВсегоСекунд / 86400);
    ОстатокСекунд = ВсегоСекунд % 86400;
    
    КоличествоЧасов = Цел(ОстатокСекунд / 3600);
    ОстатокСекунд = ОстатокСекунд % 3600;
    
    КоличествоМинут = Цел(ОстатокСекунд / 60);
    Секунды = ОстатокСекунд % 60;

    Результат = "";
    Если КоличествоДней > 0 Тогда
        Результат = Формат(КоличествоДней, "ЧГ=0") + " д. ";
    КонецЕсли;

    Результат = Результат 
        + Формат(КоличествоЧасов, "ЧЦ=2; ЧВН=; ЧГ=0") + ":" 
        + Формат(КоличествоМинут, "ЧЦ=2; ЧВН=; ЧГ=0") + ":" 
        + Формат(Секунды, "ЧЦ=2; ЧВН=; ЧГ=0");

    Возврат Результат;

КонецФункции

После этого перейдем в СКД на вкладку «Ресурсы» и укажем имя функции в поле выражения:

ИмяОбщегоМодуля.ДлительностьВСтроку(Сумма(Секунды))

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

Способ 3. Сохранение правильной сортировки через «Выражение представления»

Проанализируем распространенную проблему: если ресурс СКД возвращает строку, сортировка данных по этой колонке начинает выполняться по алфавитному принципу. В таком случае строка "100:00:00" в отчете окажется раньше строки "20:00:00". Чтобы этого избежать, разделим реальное значение и его визуальное представление.

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

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

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

Способ 4. Подготовка данных для выгрузки отчета в Excel

Посмотрим на ситуацию, когда отчет строится для последующей выгрузки в Microsoft Excel и пользователям требуется продолжать работать с ячейками как со временем (суммировать, находить среднее). В Excel время измеряется в долях суток, где единица равна 24 часам.

Для корректной интеграции сделаем следующее:

  1. В запросе СКД или вычисляемом поле рассчитаем доли суток: Секунды / 86400.
  2. В настройках оформления поля отчета укажем формат ячейки Excel. Для этого в свойствах оформления ячейки зададим формат: [h]:mm:ss (или [ч]:мм:сс в русскоязычной локализации Excel).

Квадратные скобки в формате Excel указывают на то, что счетчик часов не должен сбрасываться по достижении 24, а ячейка остается полноценным числом для дальнейших математических расчетов.

← На главную