При написании кода формирования отчета программисты 1С часто сталкиваются с ошибкой компиляции вида «Переменная не определена (НачалоПериода)» или «Переменная не определена (КонецПериода)». Выясним причину этой проблемы и разберем по шагам, как правильно обращаться к реквизитам формы и объекта при передаче параметров в запрос.
Проанализируем ситуацию на примере кода, в котором выполняется установка параметров запроса:
Запрос.УстановитьПараметр("КонецПериода", КонецПериода);
Запрос.УстановитьПараметр("НачалоПериода", НачалоПериода);
Платформа 1С выдает ошибку о неопределенной переменной, потому что в модуле формы НачалоПериода и КонецПериода не являются локальными переменными процедуры. Они объявлены как реквизиты объекта отчета или реквизиты самой формы. Без указания объекта-контекста система не может определить, откуда считывать значение.
Если реквизиты периода добавлены в сам отчет (в ветке метаданных или на вкладке «Реквизиты» основной схемы), то в управляемой форме основной реквизит формы обычно носит имя Отчет (в некоторых случаях — Объект).
Разберем правильный вариант обращения к реквизитам через путь к данным:
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| ДоговорыКонтрагентов.Ссылка,
| ДоговорыКонтрагентов.Полуфабрикат,
| ДоговорыКонтрагентов.КоличествоПолуфабриката,
| ДоговорыКонтрагентов.СрокДействия
|ИЗ
| Справочник.ДоговорыКонтрагентов КАК ДоговорыКонтрагентов
|ГДЕ
| ДоговорыКонтрагентов.СрокДействия МЕЖДУ &НачалоПериода И &КонецПериода";
// Обращаемся к реквизитам через имя основного реквизита формы "Отчет"
Запрос.УстановитьПараметр("НачалоПериода", Отчет.НачалоПериода);
Запрос.УстановитьПараметр("КонецПериода", Отчет.КонецПериода);
Если в форме отчета основным реквизитом является Объект, установка параметров будет выглядеть аналогично: Объект.НачалоПериода.
Рассмотрим случай, когда вызов процедуры происходит на сервере без контекста. Если процедура объявлена с директивой &НаСервереБезКонтекста, прямое обращение к Отчет или ЭтаФорма вызовет ошибку, так как контекст формы на сервер не передается.
В этом случае передадим значения периода из клиента в серверную процедуру в качестве аргументов:
Отчет.НачалоПериода и Отчет.КонецПериода.
&НаКлиенте
Процедура СформироватьОтчет(Команда)
СформироватьНаСервере(Отчет.НачалоПериода, Отчет.КонецПериода);
КонецПроцедуры
&НаСервереБезКонтекста
Процедура СформироватьНаСервере(НачалоПериода, КонецПериода)
Запрос = Новый Запрос;
// Настройка текста запроса...
Запрос.УстановитьПараметр("НачалоПериода", НачалоПериода);
Запрос.УстановитьПараметр("КонецПериода", КонецПериода);
// Выполнение запроса...
КонецПроцедуры
Посмотрим на частую логическую ошибку при работе с типом Дата. Когда пользователь выбирает дату в поле ввода без указания времени, система подставляет время 00:00:00.
Если пользователь указал период с 01.01.2024 по 31.01.2024, в параметр &КонецПериода попадет значение 31.01.2024 00:00:00. Все документы и записи, созданные 31 января в течение дня, не попадут в выборку запроса.
Для решения этой проблемы применимы два подхода:
КонецДня() при установке параметра в коде 1С:
Запрос.УстановитьПараметр("КонецПериода", КонецДня(Отчет.КонецПериода));
КОНЕЦПЕРИОДА прямо в тексте запроса:
ГДЕ
ДоговорыКонтрагентов.СрокДействия МЕЖДУ &НачалоПериода И КОНЕЦПЕРИОДА(&КонецПериода, ДЕНЬ)
Чтобы предоставить пользователю удобный выбор интервала (месяц, квартал, год) и не работать с двумя отдельными реквизитами даты, добавим в отчет один реквизит с типом СтандартныйПериод.
При работе с реквизитом Период выборка дат в коде выполняется следующим образом:
Запрос.УстановитьПараметр("НачалоПериода", Отчет.Период.ДатаНачала);
// Свойство ДатаОкончания автоматически включает время 23:59:59
Запрос.УстановитьПараметр("КонецПериода", Отчет.Период.ДатаОкончания);
Использование СтандартныйПериод позволяет избежать ошибок с границами дат и делает интерфейс формы более удобным для пользователя.