Как вычислить дату по числу года в параметрах СКД?

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

При разработке отчетов на схеме компоновки данных (СКД) разработчики часто сталкиваются с необходимостью связать пользовательский ввод с логикой запроса. Типичный сценарий: пользователю для удобства предоставляется выбор финансового или календарного года в виде простого числа (например, 2026), а в сам запрос СКД необходимо передать полноценный тип Дата (например, 01.01.2026 00:00:00) для фильтрации данных.

Попытки решить эту задачу «в лоб» через выражения параметров СКД часто приводят к ошибкам компиляции. В этой статье мы подробно разберем, почему стандартные конструкторы дат вызывают сбои, и рассмотрим несколько надежных способов решения проблемы: от изящных формул в СКД до программных методов и изменения бизнес-логики.

Почему простые варианты вычисления даты не работают?

Давайте разберем типичные ошибки, с которыми сталкиваются разработчики при попытке настроить вычисление даты в выражении параметра СКД.

Попытка 1: Использование функции Дата()

Если в выражении параметра прописать Дата(&ФинансовыйГод, 1, 1), платформа выдаст ошибку: «Функция не найдена "Дата"». Это происходит потому, что язык выражений СКД отличается от встроенного языка 1С:Предприятие. В нем просто отсутствует функция-конструктор Дата() с тремя числовыми параметрами.

Попытка 2: Использование конструкции ДАТАВРЕМЯ()

Если изменить выражение на ДАТАВРЕМЯ(&ФинансовыйГод, 1, 1), система вернет ошибку: «Ожидается константа». Дело в том, что ДАТАВРЕМЯ — это не функция, выполняемая во время работы отчета, а литерал (статическое описание значения даты на этапе компиляции). Его параметры должны быть жестко прописаны числами (константами) еще при конфигурировании. Передавать туда динамические параметры или переменные категорически нельзя.

---

Решение 1: Изящный обходной путь через выражения СКД (без кода)

Наиболее красивый способ решить задачу прямо в конфигураторе, не прибегая к программированию — использовать комбинацию литерала начала нашей эры и встроенной функции СКД ДОБАВИТЬКДАТЕ.

Рассмотрим логику этого метода. Мы берем за основу минимально возможную дату в системе — 01.01.0001 — и прибавляем к ней количество лет, равное выбранному пользователем году минус один год. Например, если пользователь выбрал 2026 год, мы прибавляем к базовой дате 2025 лет и получаем ровно 01.01.2026 00:00:00.

Пошаговая настройка в СКД:

  1. Откройте схему компоновки данных вашего отчета и перейдите на вкладку Параметры.
  2. Убедитесь, что для параметра &ФинансовыйГод (тип Число) включена доступность для пользователя.
  3. Для параметра &НачалоФинансовогоГода (тип Дата) снимите флаг доступности (чтобы не путать пользователя) и в поле Выражение вставьте следующую формулу:

ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1, 0, 0, 0), "ГОД", &ФинансовыйГод - 1)

Этот метод работает абсолютно надежно, так как функция ДОБАВИТЬКДАТЕ поддерживается транслятором запросов СКД на уровне СУБД. Вычисление происходит мгновенно и не создает никакой избыточной нагрузки на сервер.

---

Решение 2: Программная установка параметра в модуле отчета

В профессиональной разработке и сложных корпоративных отчетах хорошим тоном считается явное управление параметрами через код встроенного языка 1С. Это упрощает отладку отчета и позволяет гибко обрабатывать любые нестандартные действия пользователя.

Мы можем перехватить процесс компоновки результата и принудительно установить значение скрытого параметра даты на основе выбранного числового года.

Инструкция по реализации:

  1. Откройте модуль объекта вашего отчета.
  2. Создайте обработчик события ПриКомпоновкеРезультата.
  3. Реализуйте в нем следующий алгоритм:

Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    // Отменяем стандартный вывод, так как будем компоновать макет вручную
    СтандартнаяОбработка = Ложь;
    
    // Получаем текущие настройки компоновщика
    ТекущиеНастройки = КомпоновщикНастроек.ПолучитьНастройки();
    
    // Ищем введенное пользователем числовое значение года
    ПараметрГод = ТекущиеНастройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("ФинансовыйГод"));
    
    Если ПараметрГод <> Неопределено И ПараметрГод.Использование И ЗначениеЗаполнено(ПараметрГод.Значение) Тогда
        
        // Преобразуем число в дату начала года средствами встроенного языка
        ГодЧислом = ПараметрГод.Значение;
        ДатаНачалаГода = Дата(ГодЧислом, 1, 1);
        
        // Находим скрытый параметр начала года и записываем в него полученную дату
        ПараметрДата = ТекущиеНастройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("НачалоФинансовогоГода"));
        Если ПараметрДата <> Неопределено Тогда
            ПараметрДата.Значение = ДатаНачалаГода;
            ПараметрДата.Использование = Истина;
        КонецЕсли;
        
    КонецЕсли;
    
    // Выполняем стандартную компоновку с нашими обновленными параметрами
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, ТекущиеНастройки, ДанныеРасшифровки);
    
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки, Истина);
    
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновки);
    
КонецПроцедуры

Данный подход гарантирует 100% стабильность работы. Вы можете дополнить этот код проверками (например, контролировать, чтобы введенный год находился в разумных пределах) или рассчитывать также и дату окончания финансового года.

---

Решение 3: Использование функций общих модулей

Если в вашей конфигурации уже есть общий модуль с экспортными функциями для работы с периодами (или вы готовы его создать), можно вызывать функции общего модуля прямо внутри поля выражения СКД.

Шаг 1. Создание функции в общем модуле
Создайте или откройте общий модуль (например, с именем РаботаСДатамиВызовСервера). Убедитесь, что у модуля стоят свойства Сервер и Вызов сервера (модуль не должен быть глобальным). Напишите простую экспортную функцию:


Функция ПолучитьНачалоГода(ЗначениеГода) Экспорт
    Возврат Дата(ЗначениеГода, 1, 1);
КонецФункции

Шаг 2. Настройка параметра в СКД
В схеме компоновки данных для параметра &НачалоФинансовогоГода в колонке Выражение укажите вызов этой функции:


РаботаСДатамиВызовСервера.ПолучитьНачалоГода(&ФинансовыйГод)

Важное ограничение: этот способ отлично работает в составе типовых и нетиповых конфигураций, но может вызвать трудности, если вы разрабатываете полностью автономный внешний отчет, предназначенный для работы в базах с жестко настроенными профилями безопасности (где вызовы несертифицированного кода из внешних обработок могут быть заблокированы).

---

Решение 4: Переход на стандартный тип «СтандартныйПериод» (Рекомендуемый UX-паттерн)

В экосистеме 1С:Предприятие для удобства пользователей разработан специальный тип данных — СтандартныйПериод. Вместо того чтобы заставлять пользователя вручную вводить цифры года с клавиатуры, гораздо удобнее предоставить ему интерактивный выбор периода.

Преимущества использования стандартного периода:

Как это настроить в СКД:

  1. На вкладке Параметры создайте новый параметр &ПериодОтчета с типом СтандартныйПериод и сделайте его доступным пользователю.
  2. Для системных параметров запроса &НачалоФинансовогоГода и &КонецФинансовогоГода снимите доступность и пропишите выражения автоматического извлечения границ периода:
    • Для начала периода: &ПериодОтчета.ДатаНачала
    • Для окончания периода: &ПериодОтчета.ДатаОкончания

Этот способ является наиболее предпочтительным с точки зрения стандартов проектирования интерфейсов 1С и полностью избавляет вас от необходимости писать вспомогательный код преобразования типов.

← На главную