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

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

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

Выясняем причину: почему не работает обращение через «Объект»?

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

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

Запрос.УстановитьПараметр("Сотрудник", Объект.Сотрудник); // Ошибка!

неизбежно приведет к синтаксической ошибке на сервере, так как платформа пытается найти переменную Объект в контексте формы и не находит ее.

Разбираем вторую ошибку: почему не работает обращение напрямую?

Когда разработчик пытается исправить ситуацию и обращается к реквизиту напрямую по имени, например:

Запрос.УстановитьПараметр("Организация", Организация); // Ошибка!

платформа выдает следующую ошибку: «Переменная не определена (Организация)». Выясним причину этого поведения.

Дело в том, что реквизиты, созданные в самом объекте метаданных «Отчет» (на вкладке «Реквизиты» в окне конфигуратора внешнего отчета), не становятся глобальными переменными модуля формы. Они являются подчиненными элементами основного реквизита формы Отчет. Напрямую по имени (без указания родительского реквизита) в модуле формы можно обращаться только к тем реквизитам, которые были созданы непосредственно в самой форме на вкладке «Реквизиты формы».

Анализируем ошибку использования «Элементы.Сотрудник»

Иногда у начинающих разработчиков возникает идея использовать конструкцию Элементы.Сотрудник. Разберем, почему этот путь ведет в тупик.

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

Решение №1: Исправление обращения через реквизит «Отчет» (Контекстный вызов)

Если ваши процедуры выполняются в контексте формы на сервере (директива компиляции &НаСервере), самым простым и быстрым решением будет правильное обращение к реквизитам через основное свойство Отчет. Рассмотрим пример правильного кода:


&НаСервере
Процедура ВыполнитьЗапросНаСервере()
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	КадроваяИсторияСотрудниковСрезПоследних.Сотрудник КАК Сотрудник,
        |	КадроваяИсторияСотрудниковСрезПоследних.Должность КАК Должность
        |ИЗ
        |	РегистрСведений.КадроваяИсторияСотрудников.СрезПоследних(
        |		,
        |		Организация = &Организация
        |			И Сотрудник = &Сотрудник
        |			И Регистратор ССЫЛКА Документ.ПриемНаРаботу) КАК КадроваяИсторияСотрудниковСрезПоследних";
    
    // Правильное обращение к реквизитам отчета
    Запрос.УстановитьПараметр("Сотрудник", Отчет.Сотрудник);
    Запрос.УстановитьПараметр("Организация", Отчет.Организация);
    
    РезультатЗапроса = Запрос.Выполнить();
    // Дальнейшая обработка выборки запроса...
    
КонецПроцедуры

Решение №2: Передача параметров при безконтекстном вызове

В современной разработке на платформе 1С 8.3 хорошим тоном считается использование безконтекстных серверных вызовов (директива &НаСервереБезКонтекста). Это снижает нагрузку на сеть и сервер, так как на сервер не передаются все данные формы (контекст).

В процедурах с директивой &НаСервереБезКонтекста переменная Отчет недоступна. В этом случае правильным решением будет передача значений реквизитов с клиента на сервер в качестве параметров функции. Разберем этот метод по шагам:

  1. На клиенте получаем значения реквизитов из свойства Отчет.
  2. Передаем эти значения аргументами в безконтекстную функцию.
  3. На сервере принимаем аргументы и устанавливаем их в качестве параметров запроса.

Посмотрим на практический пример реализации такого подхода:


&НаКлиенте
Процедура СформироватьОтчет(Команда)
    // Вызываем серверную функцию без передачи контекста формы, передавая только нужные данные
    ТаблицаРезультата = ПолучитьДанныеНаСервере(Отчет.Сотрудник, Отчет.Организация);
    // Обрабатываем полученную таблицу на клиенте (например, выводим в табличный документ)
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПолучитьДанныеНаСервере(Знач ВыбранныйСотрудник, Знач ВыбраннаяОрганизация)
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	КадроваяИсторияСотрудниковСрезПоследних.Сотрудник КАК Сотрудник,
        |	КадроваяИсторияСотрудниковСрезПоследних.Должность КАК Должность
        |ИЗ
        |	РегистрСведений.КадроваяИсторияСотрудников.СрезПоследних(
        |		,
        |		Организация = &Организация
        |			И Сотрудник = &Сотрудник) КАК КадроваяИсторияСотрудниковСрезПоследних";
    
    // Устанавливаем параметры из аргументов функции
    Запрос.УстановитьПараметр("Сотрудник", ВыбранныйСотрудник);
    Запрос.УстановитьПараметр("Организация", ВыбраннаяОрганизация);
    
    Возврат Запрос.Выполнить().Выгрузить();
    
КонецФункции

Решение №3: Использование реквизитов самой формы

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

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

В этом случае обращение в контекстной процедуре &НаСервере будет происходить напрямую по имени созданных реквизитов формы:


&НаСервере
Процедура ВыполнитьЗапросНаФорме()
    Запрос = Новый Запрос;
    Запрос.Текст = "ВЫБРАТЬ ... ГДЕ Организация = &Организация";
    
    // Прямое обращение к собственным реквизитам формы разрешено!
    Запрос.УстановитьПараметр("Организация", ВыбраннаяОрганизация);
    // ...
КонецПроцедуры

Лучшая практика (Best Practice): Разработка отчетов на СКД

В типовых конфигурациях (таких как ЗУП 3.1, ERP, КА) ручное написание запросов и вывод данных через код в модуле формы отчета считается устаревшим подходом. Платформа предоставляет мощный инструмент — Систему компоновки данных (СКД). Намного эффективнее настроить параметры отчета без написания программного кода.

Разберем по шагам, как решить задачу автора темы с помощью СКД:

  1. В окне конфигуратора внешнего отчета добавим схему компоновки данных (кнопка «Открыть схему компоновки данных»).
  2. Добавим набор данных - запрос. Поместим туда наш запрос по кадровой истории сотрудников.
  3. Перейдем на вкладку «Параметры». Платформа автоматически создаст параметры Организация и Сотрудник, так как они объявлены в тексте запроса с символом "&".
  4. Настроим свойства параметров: укажем нужный тип данных (ссылки на справочники) и снимем галочку «Доступен список значений», если выбор должен быть единичным.
  5. Перейдем на вкладку «Настройки». В нижней части экрана выберем вкладку «Параметры».
  6. Для параметров Организация и Сотрудник нажмем кнопку «Свойства элемента пользовательских настроек» (иконка с шестеренкой) и установим флажок «Включать в пользовательские настройки».

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

← На главную