Как исправить ошибку «Переменная не определена» при обращении к реквизитам периода в отчете 1С?

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

При написании кода формирования отчета программисты 1С часто сталкиваются с ошибкой компиляции вида «Переменная не определена (НачалоПериода)» или «Переменная не определена (КонецПериода)». Выясним причину этой проблемы и разберем по шагам, как правильно обращаться к реквизитам формы и объекта при передаче параметров в запрос.

Анализ ошибки и причина её возникновения

Проанализируем ситуацию на примере кода, в котором выполняется установка параметров запроса:


Запрос.УстановитьПараметр("КонецПериода", КонецПериода);
Запрос.УстановитьПараметр("НачалоПериода", НачалоПериода);

Платформа 1С выдает ошибку о неопределенной переменной, потому что в модуле формы НачалоПериода и КонецПериода не являются локальными переменными процедуры. Они объявлены как реквизиты объекта отчета или реквизиты самой формы. Без указания объекта-контекста система не может определить, откуда считывать значение.

Решение 1. Обращение к реквизитам объекта отчета

Если реквизиты периода добавлены в сам отчет (в ветке метаданных или на вкладке «Реквизиты» основной схемы), то в управляемой форме основной реквизит формы обычно носит имя Отчет (в некоторых случаях — Объект).

Разберем правильный вариант обращения к реквизитам через путь к данным:


Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
|	ДоговорыКонтрагентов.Ссылка,
|	ДоговорыКонтрагентов.Полуфабрикат,
|	ДоговорыКонтрагентов.КоличествоПолуфабриката,
|	ДоговорыКонтрагентов.СрокДействия
|ИЗ
|	Справочник.ДоговорыКонтрагентов КАК ДоговорыКонтрагентов
|ГДЕ
|	ДоговорыКонтрагентов.СрокДействия МЕЖДУ &НачалоПериода И &КонецПериода";

// Обращаемся к реквизитам через имя основного реквизита формы "Отчет"
Запрос.УстановитьПараметр("НачалоПериода", Отчет.НачалоПериода);
Запрос.УстановитьПараметр("КонецПериода", Отчет.КонецПериода);

Если в форме отчета основным реквизитом является Объект, установка параметров будет выглядеть аналогично: Объект.НачалоПериода.

Решение 2. Учет контекста серверной процедуры

Рассмотрим случай, когда вызов процедуры происходит на сервере без контекста. Если процедура объявлена с директивой &НаСервереБезКонтекста, прямое обращение к Отчет или ЭтаФорма вызовет ошибку, так как контекст формы на сервер не передается.

В этом случае передадим значения периода из клиента в серверную процедуру в качестве аргументов:

  1. На клиенте получаем значения Отчет.НачалоПериода и Отчет.КонецПериода.
  2. Передаем их в процедуру выполнения запроса.

&НаКлиенте
Процедура СформироватьОтчет(Команда)
	СформироватьНаСервере(Отчет.НачалоПериода, Отчет.КонецПериода);
КонецПроцедуры

&НаСервереБезКонтекста
Процедура СформироватьНаСервере(НачалоПериода, КонецПериода)
	Запрос = Новый Запрос;
	// Настройка текста запроса...
	Запрос.УстановитьПараметр("НачалоПериода", НачалоПериода);
	Запрос.УстановитьПараметр("КонецПериода", КонецПериода);
	// Выполнение запроса...
КонецПроцедуры

Критическая особенность: обработка времени в конце периода

Посмотрим на частую логическую ошибку при работе с типом Дата. Когда пользователь выбирает дату в поле ввода без указания времени, система подставляет время 00:00:00.

Если пользователь указал период с 01.01.2024 по 31.01.2024, в параметр &КонецПериода попадет значение 31.01.2024 00:00:00. Все документы и записи, созданные 31 января в течение дня, не попадут в выборку запроса.

Для решения этой проблемы применимы два подхода:

  1. Использование функции КонецДня() при установке параметра в коде 1С: Запрос.УстановитьПараметр("КонецПериода", КонецДня(Отчет.КонецПериода));
  2. Использование встроенной функции языка запросов КОНЕЦПЕРИОДА прямо в тексте запроса:
    
    ГДЕ
    	ДоговорыКонтрагентов.СрокДействия МЕЖДУ &НачалоПериода И КОНЕЦПЕРИОДА(&КонецПериода, ДЕНЬ)
    

Альтернативный вариант: использование типа «СтандартныйПериод»

Чтобы предоставить пользователю удобный выбор интервала (месяц, квартал, год) и не работать с двумя отдельными реквизитами даты, добавим в отчет один реквизит с типом СтандартныйПериод.

При работе с реквизитом Период выборка дат в коде выполняется следующим образом:


Запрос.УстановитьПараметр("НачалоПериода", Отчет.Период.ДатаНачала);
// Свойство ДатаОкончания автоматически включает время 23:59:59
Запрос.УстановитьПараметр("КонецПериода", Отчет.Период.ДатаОкончания);

Использование СтандартныйПериод позволяет избежать ошибок с границами дат и делает интерфейс формы более удобным для пользователя.

← На главную