Как вывести разность дат в формате дней, часов и минут в динамическом списке 1С

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

При разработке интерфейсов часто возникает необходимость показать пользователю остаток времени до наступления события (например, срок выполнения задачи или заявки) в компактном и наглядном виде: X дн. Y час. Z мин.

Попытка решить эту задачу непосредственно в тексте запроса динамического списка приводит к трудностям из-за специфики языка запросов 1С. Разберем, почему не удается сформировать такую строку прямо в запросе, какие нюансы работы функции РАЗНОСТЬДАТ следует учитывать и какими способами можно реализовать требуемое отображение.

Ограничения языка запросов 1С

Проанализируем ключевые ограничения платформы, с которыми сталкивается разработчик при решении подобной задачи:

  1. Невозможность преобразования числа в строку: в языке запросов 1С конструкция ВЫРАЗИТЬ(Число КАК СТРОКА) синтаксически не поддерживается. Сформировать готовую текстовую строку из вычисленных числовых значений внутри запроса невозможно.
  2. Отсутствие оператора остатка от деления: в запросе нет функции вычисления остатка от целочисленного деления (аналога % или MOD), что усложняет математический расчет остатков минут и часов.
  3. Недоступность общих модулей: в тексте запроса динамического списка нельзя вызывать экспортные функции конфигурации для форматирования.
  4. Особенности функции РАЗНОСТЬДАТ: данная функция подсчитывает число пересечений календарных границ указанной периодичности, а не точную физическую длительность интервала. Например, разность между 23:59:59 одного дня и 00:00:01 следующего дня с параметром ДЕНЬ вернет значение 1, хотя прошло всего две секунды.

Рассмотрим два основных и наиболее эффективных варианта реализации задачи.

Вариант 1. Использование события «ПриПолученииДанныхНаСервере» (Рекомендуемый способ)

Наиболее гибкий и производительный подход — получить в запросе точное числовое значение (например, разность в секундах или саму целевую дату), а форматирование строки выполнить в обработчике таблицы формы. Поскольку обработчик выполняется только для видимых пользователю строк, нагрузка на сервер остается минимальной.

Разберем реализацию по шагам:

  1. В запросе динамического списка выбираем исходную дату СрокИсполнения либо вычисляем разность в секундах:
    
    ВЫБРАТЬ
        Документ.Ссылка КАК Ссылка,
        Документ.СрокИсполнения КАК СрокИсполнения,
        РАЗНОСТЬДАТ(&ТекущаяДата, Документ.СрокИсполнения, СЕКУНДА) КАК ОстатокСекунд
    ИЗ
        Документ.ЗаказКлиента КАК Документ
    
  2. В таблице динамического списка на форме добавляем текстовую колонку (например, ОсталосьВремени).
  3. Создаем обработчик события таблицы ПриПолученииДанныхНаСервере и выполняем расчет средствами встроенного языка 1С:
    
    &НаСервере
    Процедура СписокПриПолученииДанныхНаСервере(Элемент, ОформленияСтрок)
        
        Для Каждого Оформление Из ОформленияСтрок Цикл
            
            ОстатокСекунд = 0;
            Если Оформление.ДанныеСтроки.Свойство("ОстатокСекунд") Тогда
                ОстатокСекунд = Оформление.ДанныеСтроки.ОстатокСекунд;
            КонецЕсли;
            
            Если ОстатокСекунд > 0 Тогда
                ВсегоМинут = Цел(ОстатокСекунд / 60);
                Минуты = ВсегоМинут % 60;
                
                ВсегоЧасов = Цел(ВсегоМинут / 60);
                Часы = ВсегоЧасов % 24;
                
                Дни = Цел(ВсегоЧасов / 24);
                
                ТекстСрока = СтрШаблон("%1 дн. %2 час. %3 мин.", Дни, Часы, Минуты);
            Иначе
                ТекстСрока = "Срок истек";
            КонецЕсли;
            
            Оформление.Ячейки.ОсталосьВремени.УстановитьТекст(ТекстСрока);
            
        КонецЦикла;
        
    КонецПроцедуры
    

Вариант 2. Интерфейсное объединение колонок в одну ячейку

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

Рассмотрим, как настроить данный вариант:

  1. В тексте запроса динамического списка рассчитываем дни, часы и минуты с корректным вычитанием старших периодов:
    
    ВЫБРАТЬ
        Документ.Ссылка КАК Ссылка,
        РАЗНОСТЬДАТ(&ТекущаяДата, Документ.СрокИсполнения, ДЕНЬ) КАК ОстДней,
        РАЗНОСТЬДАТ(&ТекущаяДата, Документ.СрокИсполнения, ЧАС) 
            - РАЗНОСТЬДАТ(&ТекущаяДата, Документ.СрокИсполнения, ДЕНЬ) * 24 КАК ОстЧасов,
        РАЗНОСТЬДАТ(&ТекущаяДата, Документ.СрокИсполнения, МИНУТА) 
            - РАЗНОСТЬДАТ(&ТекущаяДата, Документ.СрокИсполнения, ЧАС) * 60 КАК ОстМинут
    ИЗ
        Документ.ЗаказКлиента КАК Документ
    
  2. В редакторе формы добавляем в таблицу динамического списка элемент с видом ГруппаКолонок.
  3. В свойствах группы колонок устанавливаем свойство Группировка в значение В ячейке.
  4. Переносим поля ОстДней, ОстЧасов и ОстМинут внутрь созданной группы.
  5. Для каждого поля настраиваем формат отображения (свойство Формат), указав нужный суффикс (например, для дней: ЧДЦ=0; ЧС= дн., для часов: ЧДЦ=0; ЧС= час., для минут: ЧДЦ=0; ЧС= мин.).

В результате в интерфейсе пользователь увидит единую ячейку с визуально скомпонованной строкой времени.

← На главную