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