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