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

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

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

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

Суть проблемы: почему код «не видит» реквизиты?

Рассмотрим ситуацию. Разработчик создает новую обработку, добавляет в нее реквизиты (например, ФИОПоиск, ТелефонПоиск) и табличную часть (например, РезультатПоиска). Затем переносит их на форму и пишет следующий код для поиска:


&НаКлиенте
Процедура Поиск()
    Результат = ПоискНаСервере(ФИОПоиск, ТелефонПоиск);
    РезультатПоиска.Очистить();
    РезультатПоиска.Загрузить(Результат);
КонецПроцедуры

При попытке сохранить или запустить этот код платформа выдает целый букет ошибок:

  1. Переменная не определена (ФИОПоиск)
  2. Переменная не определена (ТелефонПоиск)
  3. Переменная не определена (РезультатПоиска)

Выясним причину такого поведения платформы. В управляемом приложении 1С код формы выполняется в контексте самой управляемой формы, а не прикладного объекта (обработки или документа). Существует жесткое разделение на два типа реквизитов:

Поскольку автор темы создал реквизиты внутри самой обработки, прямое обращение к ним на клиенте вызвало ошибку компиляции. Исправление имен на Объект.ФИОПоиск решает проблему видимости, но в исходном коде кроются еще более опасные архитектурные ошибки, которые приведут к падению программы при выполнении.

Критическая ошибка №1: Передача мутабельных типов с сервера на клиент

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


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

Метод Выгрузить() возвращает объект типа ТаблицаЗначений. В платформе «1С:Предприятие 8» тип данных ТаблицаЗначений является мутабельным (изменяемым) типом данных. Такие объекты физически могут существовать только на стороне сервера (или в толстом клиенте).

Попытка передать ТаблицуЗначений из серверной функции обратно в тонкий клиент (в процедуру Поиск) гарантированно вызовет аварийное завершение работы программы с ошибкой: «Ошибка передачи данных между клиентом и сервером. Недопустимый тип значения». Тонкий клиент просто «не умеет» работать с таблицами значений напрямую.

Критическая ошибка №2: Использование серверных методов на клиенте

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

РезультатПоиска.Загрузить(Результат);

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

Разберем по шагам правильный архитектурный шаблон поиска

Чтобы избежать постоянного «гоняния» тяжелых данных между клиентом и сервером и не сталкиваться с ограничениями типов данных на клиенте, всю работу по заполнению табличной части нужно перенести на сервер в рамках единого контекстного вызова. На клиенте должна остаться только стартовая команда.

Рассмотрим правильный вариант реализации модуля управляемой формы:


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

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

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

Особенности работы с ИИ (DeepSeek, ChatGPT) при написании кода для 1С

Как упоминал автор темы, данный некорректный код был сгенерирован с помощью нейросети. Искусственный интеллект сегодня — отличный инструмент для подсказок, составления текстов запросов и написания простых алгоритмов. Однако ИИ регулярно совершает архитектурные ошибки в 1С по следующим причинам:

Чтобы получать от ИИ качественный код для 1С, всегда четко формулируйте ограничения в промпте. Например: «Напиши код поиска для управляемой формы 1С 8.3. Поиск должен выполняться на сервере в контексте формы. Учти, что результат запроса нужно выгрузить и заполнить в табличную часть "Объект.РезультатПоиска" на сервере, так как метод Загрузить() недоступен на клиенте».

← На главную