При разработке отчетов на Системе компоновки данных (СКД) программисты часто сталкиваются с классической дилеммой: пользователю удобно вводить дату в простом формате (например, 31.12.2023), но для корректной работы запроса (особенно при получении остатков) дата должна включать время окончания дня — 23:59:59. Если передать в запрос «пустую» дату (начало дня 00:00:00), данные за последний день периода могут просто не попасть в отчет.
В этой статье мы разберем несколько способов решения этой задачи, проанализируем, как правильно настроить параметры в схеме компоновки, и выясним, как добиться того, чтобы в печатной форме отчета в секции параметров также красовалось время конца дня.
Это наиболее гибкий и «чистый» метод, который разделяет визуальное представление для ввода, внутреннюю логику запроса и итоговый вывод в табличный документ. Рассмотрим его по шагам.
Шаг 1. Настройка выражения. Перейдем на вкладку «Параметры» в схеме компоновки данных. Для нашего параметра (например, &ДатаКонца) в колонке «Выражение» пропишем стандартную функцию СКД:
КонецПериода(&ДатаКонца, "День")
Это гарантирует, что какое бы время ни выбрал пользователь (или если он его не выбирал вовсе), система компоновки перед выполнением запроса принудительно установит время на 23:59:59.
Шаг 2. Настройка формата редактирования. Чтобы не пугать пользователя лишними полями ввода времени, в этой же строке параметра найдем колонку «Параметры редактирования». Установим свойство «Формат редактирования» в значение ДФ='dd.MM.yyyy'. Теперь при нажатии на календарь или ручном вводе пользователь будет видеть только дату.
Шаг 3. Настройка формата вывода. Теперь самое важное — как вывести это в шапку отчета. Если мы просто оставим параметр как есть, СКД выведет его согласно формату редактирования или стандартному формату даты. Чтобы в секции «Параметры» отображалось время, перейдем на вкладку «Настройки», далее на вкладку «Условное оформление».
ДФ='dd.MM.yyyy 23:59:59'.&ДатаКонца.Таким образом, мы получаем идеальную цепочку: вводим «31.12.2023», в запрос уходит «31.12.2023 23:59:59», и в печатной форме заголовка мы видим «31.12.2023 23:59:59».
Разберем альтернативный, более простой, но менее гибкий вариант. Мы можем заставить пользователя «видеть» время сразу при вводе, но ограничить его возможность это время менять.
В параметрах редактирования поля (вкладка «Параметры») можно сразу указать формат: ДФ='dd.MM.yyyy 23:59:59'. В этом случае при попытке редактирования система предложит маску, где время уже заполнено. Однако проанализируем ситуацию: это может быть неудобно для пользователя, так как лишние символы в строке ввода часто мешают быстрой работе с клавиатуры.
Если задача требует сложной логики или вы хотите полностью исключить влияние настроек пользователя на этот процесс, можно прибегнуть к программному методу в модуле объекта отчета. Рассмотрим пример кода в обработчике ПриКомпоновкеРезультата:
Процедура ПриКомпоновкеРезультата(ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
// Получаем значение параметра из настроек
ПараметрДата = КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти("ДатаКонца");
Если ПараметрДата <> Неопределено И ПараметрДата.Использование Тогда
// Принудительно устанавливаем конец дня
ПараметрДата.Значение = КонецДня(ПараметрДата.Значение);
КонецЕсли;
// Далее стандартный вывод отчета
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.Настройки, ДанныеРасшифровки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(Результат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
КонецПроцедуры
Этот метод хорош тем, что он гарантирует результат. Однако стоит помнить, что прямое изменение значения параметра в КомпоновщикНастроек.Настройки приведет к тому, что пользователь увидит измененное значение в форме отчета только после формирования, что иногда вызывает вопросы.
Проанализируем, почему мы так боремся за КонецПериода. В 1С:Предприятие 8 большинство виртуальных таблиц (Остатки, ОстаткиИОбороты) воспринимают параметр даты включительно до секунды. Если вы передаете в запрос 01.10.2023 00:00:00, то движения, совершенные в течение дня 1 октября, не будут учтены в остатках на эту дату. Поэтому использование выражения КонецПериода(&Дата, "День") в настройках СКД — это не просто эстетический вопрос, а вопрос корректности учетных данных.
Выясним, как профессиональные разработчики чаще всего решают эту задачу в тиражных решениях. Они используют пару параметров:
&ПериодОтчета — тип СтандартныйПериод или просто Дата. Он доступен пользователю.&ДатаКонцаЗапроса — тип Дата. Он скрыт от пользователя (флажок «Ограничение доступности»).Для скрытого параметра в выражении прописывается &ПериодОтчета.ДатаОкончания или КонецПериода(&ПериодОтчета, "День"). В самом тексте запроса используется только скрытый параметр. Это позволяет избежать любых конфликтов с форматами отображения, так как «пользовательский» параметр служит только для ввода, а «рабочий» — только для логики базы данных.
Подведем итог: наиболее коротким и эффективным решением в рамках СКД без написания кода является использование выражения КонецПериода совместно с Условным оформлением для визуального подтверждения времени 23:59:59 в печатной форме.