При разработке отчетов в Системе компоновки данных (СКД) программисты часто сталкиваются с необходимостью вывести разницу между двумя датами не в секундах или десятичных часах (например, 1.5 часа), а в привычном пользователю виде — ЧЧ:ММ (например, 01:30). Стандартная функция РАЗНОСТЬДАТ возвращает целое число, а простое деление на 3600 дает дробное значение. Давайте подробно разберем, как реализовать правильное отображение времени, сохранив при этом возможность расчета итогов по группировкам.
Самый простой на первый взгляд способ — прибавить полученную разницу в секундах к «пустой» дате и применить форматную строку. Рассмотрим этот пример подробнее. В запросе или вычисляемом поле можно использовать конструкцию:
ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, РАЗНОСТЬДАТ(ДатаНачала, ДатаОкончания, СЕКУНДА))
Затем в оформлении поля задается формат ДФ=ЧЧ:мм. Однако у этого метода есть два существенных недостатка, которые мы проанализируем:
Дата в ресурсах. Если вам нужно получить общую сумму времени по отчету, этот метод в чистом виде не подойдет.ЧЧ:мм «обнулится» и покажет только остаток от деления на 24. Например, разница в 25 часов отобразится как 01:00.Для корректного отображения времени, включая интервалы более 24 часов, мы можем собрать строку вручную. Разберем формулу, которую можно вставить в колонку Выражение вычисляемого поля СКД. Предположим, что в наборе данных у нас уже есть поле ДлительностьСекунды.
Формат(Цел(ДлительностьСекунды / 3600), "ЧГ=0") + ":" + Формат((ДлительностьСекунды % 3600) / 60, "ЧЦ=2; ЧВН=; ЧГ=0")
Проанализируем, что делает эта формула:
Цел(ДлительностьСекунды / 3600) — вычисляет полное количество часов. Параметр ЧГ=0 в функции Формат убирает разделитель групп разрядов (чтобы не было «1 250:30»).ДлительностьСекунды % 3600 — находит остаток секунд после выделения целых часов./ 60 — переводит остаток в минуты.ЧЦ=2; ЧВН= — критически важные параметры форматирования. Они гарантируют, что 5 минут будут выглядеть как «05», а не «5», обеспечивая корректный вид «01:05» вместо «1:5».Чтобы сохранить правильный расчет итогов и при этом видеть красивый формат ЧЧ:ММ, лучше всего использовать механизм Выражения представления в СКД. Это позволяет полю оставаться числом для математических операций, но выводить строку для пользователя.
Выполним следующие шаги:
Сумма(ИмяПоля).Теперь СКД будет складывать секунды (числа), а при выводе каждой строки или итога — преобразовывать результат в формат времени. Это самый надежный и устойчивый метод.
Если логика преобразования требуется во многих отчетах, целесообразно вынести ее в общий модуль. Посмотрим, как это реализовать. Создадим функцию в общем модуле (например, ОбщегоНазначенияКлиентСервер) с флагом «Сервер, Внешнее соединение»:
Функция ПреобразоватьСекундыВЧЧММ(Знач Секунды) Экспорт
Если Секунды = NULL Тогда
Возврат "00:00";
КонецЕсли;
Часы = Цел(Секунды / 3600);
Минуты = Цел((Секунды % 3600) / 60);
Возврат Формат(Часы, "ЧГ=0") + ":" + Формат(Минуты, "ЧЦ=2; ЧВН=; ЧГ=0");
КонецФункции
Затем в СКД в поле Выражение представления или в Вычисляемое поле мы просто вызываем эту функцию:
ОбщегоНазначенияКлиентСервер.ПреобразоватьСекундыВЧЧММ(ДлительностьСекунды)
Рассмотрим ситуацию, когда одна из дат может быть не заполнена. Выясним причину возможных ошибок: если ДатаНачала или ДатаОкончания имеет значение NULL, функция РАЗНОСТЬДАТ или последующее деление могут привести к непредсказуемым результатам или ошибке исполнения отчета. Чтобы этого избежать, всегда добавляйте проверку в запросе или в выражении СКД:
ВЫБОР
КОГДА ДатаНачала = ДАТАВРЕМЯ(1, 1, 1) ИЛИ ДатаОкончания = ДАТАВРЕМЯ(1, 1, 1)
ТОГДА 0
ИНАЧЕ РАЗНОСТЬДАТ(ДатаНачала, ДатаОкончания, СЕКУНДА)
КОНЕЦ
Важный нюанс: Стандартная функция РАЗНОСТЬДАТ(..., СЕКУНДА) не учитывает миллисекунды. Для большинства бизнес-задач (учет рабочего времени, длительность событий) точности в 1 секунду более чем достаточно для формирования корректного отчета в формате ЧЧ:ММ.
Для достижения наилучшего результата мы рекомендуем придерживаться следующего алгоритма:
Сумма(ВашеПоле).Цел() и % 3600.Такой подход гарантирует точность вычислений, корректность итогов по группировкам и привычный визуальный вид отчета для конечного пользователя.