Как в отчете СКД отобразить время длительности более 24 часов в формате ЧЧ:ММ

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

При разработке отчетов в системе компоновки данных (СКД) программисты часто сталкиваются с задачей отображения временных интервалов. Например, время работы оборудования или производственного цикла может составлять 45.5 часов. Стандартное приведение к типу Дата с форматом ДФ=ЧЧ:мм здесь не поможет, так как платформа при превышении 24 часов автоматически перекинет «лишнее» время в сутки, и вместо ожидаемых «45:30» пользователь увидит «21:30» (одни сутки отбросятся). В этой статье мы подробно разберем, как обойти это ограничение и корректно вывести длительность в человекочитаемом виде, сохранив при этом возможность расчета итогов.

Проблема использования стандартного типа Дата

Рассмотрим ситуацию: у нас есть числовое поле ВремяЦикла, значение которого равно 25.5. Мы хотим видеть в отчете «25:30». Если мы попытаемся в запросе прибавить это число (в секундах) к пустой дате '0001-01-01' и задать формат в СКД, то получим «01:30», так как 24 часа превратятся в полноценный день, который формат ЧЧ просто не отображает. Наша задача — заставить систему вывести общее количество часов, не ограничиваясь сутками.

Способ 1: Использование функций общего модуля

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


Функция ПреобразоватьЧислоВЧасыМинуты(Знач ЧислоМинут) Экспорт
    Если ЧислоМинут = 0 Или ЧислоМинут = Неопределено Тогда
        Возврат "00:00";
    КонецЕсли;
    
    ЦелоеКоличествоЧасов = Цел(ЧислоМинут / 60);
    ОстатокМинут = ЧислоМинут - (ЦелоеКоличествоЧасов * 60);
    
    // Формируем строку с лидирующими нулями для минут
    СтрокаЧасов = Формат(ЦелоеКоличествоЧасов, "ЧГ=0");
    СтрокаМинут = Формат(ОстатокМинут, "ЧЦ=2; ЧВН=; ЧН=00");
    
    Возврат СтрокаЧасов + ":" + СтрокаМинут;
КонецФункции

Для использования этой функции в СКД выполним следующие шаги:

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

Способ 2: Использование вычисляемых полей и ресурсов

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

В поле Выражение на закладке Ресурсы пропишем формулу, которая суммирует часы и минуты отдельно, а затем склеивает их в строку:


Формат(Цел(Сумма(ВремяВЧасах)), "ЧГ=0") 
+ ":" 
+ Формат((Сумма(ВремяВЧасах) - Цел(Сумма(ВремяВЧасах))) * 60, "ЧЦ=2; ЧВН=; ЧН=00")

Рассмотрим подробнее, что здесь происходит: Цел(Сумма(ВремяВЧасах)) выделяет целое количество часов из суммы. Далее мы вычитаем из общей суммы целую часть, получая дробный остаток часа, и умножаем его на 60, чтобы перевести в минуты. Функция Формат с параметром ЧВН= гарантирует нам появление нуля перед цифрой, если минут меньше десяти (например, «05» вместо «5»).

Способ 3: Математический хак через форматную строку (без строк)

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

  1. В запросе или вычисляемом поле преобразуем время (в секундах) в число вида ЧЧММ.СС. Формула будет выглядеть так: Цел(ВремяСекунды/3600)*100 + Цел((ВремяСекунды%3600)/60) + (ВремяСекунды%60)/100
  2. В настройках оформления поля в СКД задаем форматную строку: ЧЦ=10; ЧДЦ=2; ЧРД=:; ЧРГ=:; ЧГ=2,2.

Проанализируем ситуацию: мы превратили время в число, где каждые две цифры — это разряд времени. С помощью ЧРД=: (разделитель дробной части) мы заменяем точку на двоеточие, а с помощью ЧРГ=: (разделитель групп) и ЧГ=2,2 (группировка по две цифры) мы заставляем систему разделять часы и минуты двоеточием. Это позволяет полю оставаться «числовым» для системы сортировки, но выглядеть как «127:22:46».

Способ 4: Расчет в тексте запроса

Иногда удобнее подготовить данные еще на этапе выполнения запроса к базе данных. Выясним, как это сделать с помощью конструкции ВЫБОР и ВЫРАЗИТЬ. Это актуально, когда нам нужно получить готовое представление сразу в наборе данных.


ВЫБОР 
    КОГДА ВремяВСекундах <> 0 
    ТОГДА СТРОКА(ВЫРАЗИТЬ(ВремяВСекундах / 3600 - 0.5 КАК ЧИСЛО(15, 0))) 
          + ":" + 
          СТРОКА(ФОРМАТ((ВремяВСекундах / 60) % 60, "ЧЦ=2; ЧВН=; ЧН=00"))
    ИНАЧЕ "00:00" 
КОНЕЦ

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

Важные нюансы и решение проблем

1. Проблема сортировки: Если вы преобразуете время в строку (например, «100:05» и «20:10»), стандартная сортировка СКД может поставить «100:05» выше «20:10», так как будет сравнивать их посимвольно. Чтобы этого избежать, на вкладке Наборы данных для вашего вычисляемого поля обязательно заполните колонку Выражение упорядочивания, указав в ней исходное числовое поле с временем в секундах или часах.

2. Отрицательные значения: Если ваш отчет подразумевает отклонения (например, экономия времени может быть отрицательной), формулы из примера выше могут выдать некорректный результат (например, «-1:-30»). В таких случаях рекомендуется сначала вычислить абсолютное значение времени (Abs), сформировать строку, а затем добавить знак «-» в начало выражения, если исходное число было меньше нуля.

3. Использование БСП: Если ваша конфигурация использует Библиотеку Стандартных Подсистем, проанализируем возможности модуля Длительность. Вы можете вызвать в СКД функцию Длительность.СтрокаДлительности(Секунды). Она автоматически сформирует представление вида «1 дн. 2 ч.» или «26:15» в зависимости от переданных параметров. Это избавит вас от написания собственного кода.

4. Корректные итоги (Ресурсы): Помните, что если вы создали макет оформления поля для вывода времени, итоги могут перестать считаться автоматически. Рекомендуется всегда использовать Выражение представления или сложные формулы в Ресурсах с использованием функции ВычислитьВыражение, чтобы агрегация данных (сумма) происходила по числам, а пользователь видел результат в удобном временном формате.

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

← На главную