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