При разработке отчетов на схеме компоновки данных (СКД) разработчики часто сталкиваются с необходимостью связать пользовательский ввод с логикой запроса. Типичный сценарий: пользователю для удобства предоставляется выбор финансового или календарного года в виде простого числа (например, 2026), а в сам запрос СКД необходимо передать полноценный тип Дата (например, 01.01.2026 00:00:00) для фильтрации данных.
Попытки решить эту задачу «в лоб» через выражения параметров СКД часто приводят к ошибкам компиляции. В этой статье мы подробно разберем, почему стандартные конструкторы дат вызывают сбои, и рассмотрим несколько надежных способов решения проблемы: от изящных формул в СКД до программных методов и изменения бизнес-логики.
Давайте разберем типичные ошибки, с которыми сталкиваются разработчики при попытке настроить вычисление даты в выражении параметра СКД.
Попытка 1: Использование функции Дата()
Если в выражении параметра прописать Дата(&ФинансовыйГод, 1, 1), платформа выдаст ошибку: «Функция не найдена "Дата"». Это происходит потому, что язык выражений СКД отличается от встроенного языка 1С:Предприятие. В нем просто отсутствует функция-конструктор Дата() с тремя числовыми параметрами.
Попытка 2: Использование конструкции ДАТАВРЕМЯ()
Если изменить выражение на ДАТАВРЕМЯ(&ФинансовыйГод, 1, 1), система вернет ошибку: «Ожидается константа». Дело в том, что ДАТАВРЕМЯ — это не функция, выполняемая во время работы отчета, а литерал (статическое описание значения даты на этапе компиляции). Его параметры должны быть жестко прописаны числами (константами) еще при конфигурировании. Передавать туда динамические параметры или переменные категорически нельзя.
---
Наиболее красивый способ решить задачу прямо в конфигураторе, не прибегая к программированию — использовать комбинацию литерала начала нашей эры и встроенной функции СКД ДОБАВИТЬКДАТЕ.
Рассмотрим логику этого метода. Мы берем за основу минимально возможную дату в системе — 01.01.0001 — и прибавляем к ней количество лет, равное выбранному пользователем году минус один год. Например, если пользователь выбрал 2026 год, мы прибавляем к базовой дате 2025 лет и получаем ровно 01.01.2026 00:00:00.
Пошаговая настройка в СКД:
&ФинансовыйГод (тип Число) включена доступность для пользователя.&НачалоФинансовогоГода (тип Дата) снимите флаг доступности (чтобы не путать пользователя) и в поле Выражение вставьте следующую формулу:
ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1, 0, 0, 0), "ГОД", &ФинансовыйГод - 1)
Этот метод работает абсолютно надежно, так как функция ДОБАВИТЬКДАТЕ поддерживается транслятором запросов СКД на уровне СУБД. Вычисление происходит мгновенно и не создает никакой избыточной нагрузки на сервер.
---
В профессиональной разработке и сложных корпоративных отчетах хорошим тоном считается явное управление параметрами через код встроенного языка 1С. Это упрощает отладку отчета и позволяет гибко обрабатывать любые нестандартные действия пользователя.
Мы можем перехватить процесс компоновки результата и принудительно установить значение скрытого параметра даты на основе выбранного числового года.
Инструкция по реализации:
ПриКомпоновкеРезультата.
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
// Отменяем стандартный вывод, так как будем компоновать макет вручную
СтандартнаяОбработка = Ложь;
// Получаем текущие настройки компоновщика
ТекущиеНастройки = КомпоновщикНастроек.ПолучитьНастройки();
// Ищем введенное пользователем числовое значение года
ПараметрГод = ТекущиеНастройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("ФинансовыйГод"));
Если ПараметрГод <> Неопределено И ПараметрГод.Использование И ЗначениеЗаполнено(ПараметрГод.Значение) Тогда
// Преобразуем число в дату начала года средствами встроенного языка
ГодЧислом = ПараметрГод.Значение;
ДатаНачалаГода = Дата(ГодЧислом, 1, 1);
// Находим скрытый параметр начала года и записываем в него полученную дату
ПараметрДата = ТекущиеНастройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("НачалоФинансовогоГода"));
Если ПараметрДата <> Неопределено Тогда
ПараметрДата.Значение = ДатаНачалаГода;
ПараметрДата.Использование = Истина;
КонецЕсли;
КонецЕсли;
// Выполняем стандартную компоновку с нашими обновленными параметрами
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, ТекущиеНастройки, ДанныеРасшифровки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки, Истина);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
КонецПроцедуры
Данный подход гарантирует 100% стабильность работы. Вы можете дополнить этот код проверками (например, контролировать, чтобы введенный год находился в разумных пределах) или рассчитывать также и дату окончания финансового года.
---
Если в вашей конфигурации уже есть общий модуль с экспортными функциями для работы с периодами (или вы готовы его создать), можно вызывать функции общего модуля прямо внутри поля выражения СКД.
Шаг 1. Создание функции в общем модуле
Создайте или откройте общий модуль (например, с именем РаботаСДатамиВызовСервера). Убедитесь, что у модуля стоят свойства Сервер и Вызов сервера (модуль не должен быть глобальным). Напишите простую экспортную функцию:
Функция ПолучитьНачалоГода(ЗначениеГода) Экспорт
Возврат Дата(ЗначениеГода, 1, 1);
КонецФункции
Шаг 2. Настройка параметра в СКД
В схеме компоновки данных для параметра &НачалоФинансовогоГода в колонке Выражение укажите вызов этой функции:
РаботаСДатамиВызовСервера.ПолучитьНачалоГода(&ФинансовыйГод)
Важное ограничение: этот способ отлично работает в составе типовых и нетиповых конфигураций, но может вызвать трудности, если вы разрабатываете полностью автономный внешний отчет, предназначенный для работы в базах с жестко настроенными профилями безопасности (где вызовы несертифицированного кода из внешних обработок могут быть заблокированы).
---
В экосистеме 1С:Предприятие для удобства пользователей разработан специальный тип данных — СтандартныйПериод. Вместо того чтобы заставлять пользователя вручную вводить цифры года с клавиатуры, гораздо удобнее предоставить ему интерактивный выбор периода.
Преимущества использования стандартного периода:
Как это настроить в СКД:
&ПериодОтчета с типом СтандартныйПериод и сделайте его доступным пользователю.&НачалоФинансовогоГода и &КонецФинансовогоГода снимите доступность и пропишите выражения автоматического извлечения границ периода:
&ПериодОтчета.ДатаНачала&ПериодОтчета.ДатаОкончанияЭтот способ является наиболее предпочтительным с точки зрения стандартов проектирования интерфейсов 1С и полностью избавляет вас от необходимости писать вспомогательный код преобразования типов.