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

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

Перевод информационной базы 1С с файлового режима работы на клиент-серверный вариант (например, под управлением MS SQL Server) часто сопровождается неожиданным поведением системы. Одной из таких проблем является возникновение синтаксических ошибок вида «Переменная не определена» при попытке открыть Конструктор запросов в пользовательском режиме. Примечательно, что в Конфигураторе обычная проверка синтаксиса может показывать, что ошибок не обнаружено, а сам запрос в обычном режиме выполняется без нареканий.

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

Выясняем причину: почему падает Конструктор запросов?

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

Проблема кроется в месте компиляции этого модуля и доступности контекста:

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

Почему стандартная проверка конфигурации не видит ошибку?

Многие разработчики задаются вопросом: почему при нажатии кнопки «Синтаксический контроль» в Конфигураторе система рапортует об отсутствии ошибок? Дело в том, что по умолчанию проверка выполняется для основного режима запуска конфигурации — Управляемого приложения (Тонкий клиент). В этом режиме модуль менеджера считается чисто серверным, его компиляция на клиенте не моделируется, и обращение к серверному общему модулю Взаиморасчеты признается абсолютно корректным.

Чтобы Конфигуратор смог обнаружить эту ошибку на этапе разработки, выполним синтаксический контроль с правильными настройками. Проанализируем ситуацию по шагам:

  1. Откроем Конфигуратор вашей базы данных.
  2. В главном меню перейдем в раздел Конфигурация — Проверка конфигурации...
  3. В открывшемся окне настроек обязательно установим флажок напротив пункта «Толстый клиент (управляемое приложение)» в блоке «Проверять конфигурацию для режимов запуска».
  4. Запустим проверку. После этого система смоделирует компиляцию модулей на стороне толстого клиента и выведет все скрытые ошибки.

Теперь, когда мы понимаем природу ошибки, рассмотрим три способа ее решения: от быстрого «костыля» до архитектурно правильных подходов.

Способ 1. Использование инструкций препроцессора (Рекомендуемый стандарт 1С)

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

Рассмотрим подробнее, как должен выглядеть программный код в модуле менеджера справочника ДоговорыКонтрагентов. Нам необходимо обернуть вызовы процедур и функций общего модуля Взаиморасчеты в инструкцию препроцессора:


#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда

    ТаблицаГрафика = Взаиморасчеты.ПолучитьАктуальныйГрафикПогашенияЗайма(ДоговорКонтрагента, ТекущаяДата());
    ЗначениеПараметра = Взаиморасчеты.ПоказательВЗаданнойПериодичности(Выборка.Процент, "Год", Выборка.ПериодичностьПроцентнойСтавки);

#КонецЕсли

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

Способ 2. Запуск консоли запросов в Тонком клиенте

Если вы разрабатываете современное решение на управляемых формах, использование Толстого клиента для повседневной работы и отладки постепенно уходит в прошлое. Начиная с версии платформы 8.3.5, стандартный Конструктор запросов платформы умеет полноценно работать в режиме Тонкого клиента через специальное веб-окно.

Для исправления ситуации выполним следующие действия:

  1. Скачаем или настроим консоль запросов, адаптированную для работы в управляемом приложении (например, стандартную консоль запросов для управляемых форм из состава Инструментов разработчика или с диска ИТС).
  2. Запустим сеанс «1С:Предприятия» в режиме Тонкого клиента.
  3. Откроем консоль запросов и вызовем Конструктор запросов.

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

Способ 3. Включение флага «Вызов сервера» у общего модуля (Быстрый обход проблемы)

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

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

После этого клиентский контекст Толстого клиента получит доступ к экспортным методам этого модуля, компиляция пройдет успешно, и Конструктор запросов откроется без ошибок.

Важное предупреждение: Бессистемное включение свойства «Вызов сервера» для общих модулей является плохой практикой (антипаттерном) по следующим причинам:

Резюме

При возникновении ошибок компиляции модулей менеджера при работе в консоли запросов всегда анализируйте контекст выполнения вашего кода. Наиболее технологичным решением является использование современных консолей запросов в Тонком клиенте и аккуратное обрамление потенциально опасного кода в модулях менеджеров и объектов директивами препроцессора #Если Сервер Тогда. Это обеспечит стабильную работу системы и избавит конфигурацию от избыточных вызовов сервера.

← На главную