Как выводить длительность в секундах (более 24 часов) в формате ЧЧ:ММ:СС в динамическом списке 1С

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

При работе с динамическими списками в управляемых формах 1С часто возникает задача отображения длительности процессов (например, времени выполнения документов или регламентных заданий). Если интервал измеряется в секундах и может превышать 24 часа, стандартные механизмы форматирования даты перестают работать некорректно. Рассмотрим подробнее, почему так происходит, и разберем эффективные способы решения этой задачи.

Причина проблемы: особенности типа Дата и языка запросов

Распространенная ошибка заключается в попытке прибавить количество секунд к пустой дате в запросе dynamic list:


ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, ВложенныйЗапрос.ВремяВыполненияСекунды) КАК ВремяВыполнения

Если затем применить к полученному полю формат длительности времени ДЛФ=T или ДФ=ЧЧ:мм:сс, то при значении длительности в 101 559 секунд (что составляет 28 часов 12 минут и 39 секунд) платформа выведет 04:12:39. Происходит это потому, что тип Дата в 1С хранит календарное время. При превышении 24 часов дата переходит на следующие сутки (станет 02.01.0001 04:12:39), а стандартный формат выводит лишь время текущих суток, игнорируя прибавившиеся дни.

В самом языке запросов 1С при этом нельзя преобразовать числовое значение в строку (отсутствует функция СТРОКА() или возможность приведения типов к строке).

Способ 1. Использование вычисляемых полей в схеме компоновки данных (СКД)

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

Разберем по шагам настройку вычисляемого поля:

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

    МойОбщийМодуль.ПреобразоватьСекундыВВремя(ВремяВыполненияСекунды)

    или составим выражение прямо в СКД:

    Строка(Цел(ВремяВыполненияСекунды / 3600)) + ":" + Строка(Цел((ВремяВыполненияСекунды % 3600) / 60)) + ":" + Строка(ВремяВыполненияСекунды % 60)

  4. Выведем созданное вычисляемое поле в список элементов формы.

Способ 2. Обработчик «ПриПолученииДанныхНаСервере» (для платформы 8.3.10 и выше)

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

Проанализируем пример кода для данного обработчика:


&НаСервере
Процедура СписокПриПолученииДанныхНаСервере(ИмяЭлемента, Настройки, Строки)
    
    Для Каждого СтрокаИзСписка Из Строки Цикл
        
        // Получаем значение секунд из текущей строки
        ВсегоСекунд = СтрокаИзСписка.Данные.ВремяВыполненияСекунды;
        
        Если ВсегоСекунд = Неопределено Или ВсегоСекунд = 0 Тогда
            Продолжить;
        КонецЕсли;
        
        // Переводим секунды в формат ЧЧ:ММ:СС
        Часы = Цел(ВсегоСекунд / 3600);
        Остаток = ВсегоСекунд % 3600;
        Минуты = Цел(Остаток / 60);
        Секунды = Остаток % 60;
        
        ТекстВремени = Формат(Часы, "ЧЦ=10; ЧВН=") + ":" 
                     + Формат(Минуты, "ЧЦ=2; ЧЧ=02; ЧВН=") + ":" 
                     + Формат(Секунды, "ЧЦ=2; ЧЧ=02; ЧВН=");
        
        // Устанавливаем текстовое представление в оформление ячейки
        ОформлениеЯчейки = СтрокаИзСписка.Оформление["ВремяВыполненияФорматированное"];
        ОформлениеЯчейки.УстановитьПараметр("Текст", ТекстВремени);
        
    КонецЦикла;
    
КонецПроцедуры

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

Способ 3. Разделение времени на колонки в запросе

Если платформа не поддерживает событие ПриПолученииДанныхНаСервере, а вычисляемые поля СКД по каким-то причинам использовать нельзя, можно рассчитать часы, минуты и секунды прямо в запросе динамического списка в виде отдельных числовых колонок:


ВЫБРАТЬ
    Т.Ссылка КАК Ссылка,
    Т.ВремяВыполненияСекунды КАК ВремяВыполненияСекунды,
    ВЫРАЗИТЬ(Т.ВремяВыполненияСекунды / 3600 - 0.5 КАК ЧИСЛО(10, 0)) КАК Часы,
    // Расчет минут и секунд через математический остаток
    ...
ИЗ
    Документ.Заявка КАК Т

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

Способ 4. Сохранение готовой строки в базе данных

В случаях, когда по форматированному полю требуется выполнять полноценную сортировку, поиск или группировку пользователем непосредственно в списке, оптимальным решением является расчет и запись готовой строки вида "28:12:39" в реквизит объекта или регистр сведений при проведении/записи документа.

← На главную