При разработке отчетов и печатных форм часто возникает необходимость объединить две даты (например, ДатаНачала и ДатаОкончания) в один столбец со строковым представлением вида "01.01.2024 - 31.01.2024" или "1 квартал 2024 г.". Рассмотрим, с какими ограничениями можно столкнуться при выполнении этой задачи в языке запросов 1С и какими способами ее можно эффективно решить.
Проанализируем, почему не получается выполнить простое сложение полей в запросе вида ДатаС + " - " + ДатаПо:
+ в языке запросов требует, чтобы оба операнда имели строковый тип. Попытка сложить поле типа Дата со строкой приводит к ошибке СУБД.Формат(), а приведение типа Дата к строке через ВЫРАЗИТЬ не поддерживается.Строка(), однако она приводит дату к стандартному системному формату и не позволяет задать произвольную маску (например, вырезать время или изменить разделители).Наиболее производительным и гибким решением является выборка дат в исходном типе Дата с последующей программной обработкой результата. Это позволяет сохранить высокую скорость выполнения запроса и корректность сортировок.
Для человекочитаемого представления периода можно использовать встроенную функцию ПредставлениеПериода() или механизмы Библиотеки стандартных подсистем (БСП):
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
// Формирование стандартного представления периода ("1 квартал 2024 г.")
ТекстПериода = ПредставлениеПериода(Выборка.ДатаНачала, Выборка.ДатаОкончания, "ФП=Истина");
// Или с помощью подсистем БСП:
// ТекстПериода = ОбщегоНазначенияКлиентСервер.СформироватьПредставлениеПериода(Выборка.ДатаНачала, Выборка.ДатаОкончания);
КонецЦикла;
Разберем, как объединить поля без написания кода постобработки, если отчет строится на базе СКД.
В СКД предусмотрено специальное свойство поля — Выражение представления. Оно позволяет изменить отображение данных, не меняя само значение поля в выборке:
Пример выражения представления для объединения полей периода:
Формат(ДатаНачала, "ДФ=dd.MM.yyyy") + " - " + Формат(ДатаОкончания, "ДФ=dd.MM.yyyy")
Также в выражениях СКД можно вызывать экспортные функции общих модулей. При этом важно учитывать особенности контекста исполнения:
Если результат выводится в табличный документ без СКД, логику соединения столбцов можно перенести в макет:
[ДатаНачала] - [ДатаОкончания].Рассмотрим вариант конструирования строки даты непосредственно в тексте запроса через математические функции работы с датой и подстроками. На практике такой подход считается крайним средством из-за высокой нагрузки на СУБД и сложности поддержки кода:
ВЫБРАТЬ
ПОДСТРОКА("0123456789", ДЕНЬ(ТаблицаДанных.ДатаНачала) / 10 + 1, 1)
+ ПОДСТРОКА("0123456789", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, 6 * ДЕНЬ(ТаблицаДанных.ДатаНачала))) / 6 + 1, 1)
+ "/" + ПОДСТРОКА("0123456789", МЕСЯЦ(ТаблицаДанных.ДатаНачала) / 10 + 1, 1)
+ " - "
+ ПОДСТРОКА("0123456789", ДЕНЬ(ТаблицаДанных.ДатаОкончания) / 10 + 1, 1) КАК Период
ИЗ
&ТаблицаДанных КАК ТаблицаДанных
Важно: не рекомендуется использовать сложные математические преобразования типов внутри запросов для рабочих конфигураций. Оптимальным решением остается выборка исходных дат и их форматирование средствами СКД или языка 1С на этапе вывода.