Перевод информационной базы 1С с файлового режима работы на клиент-серверный вариант (например, под управлением MS SQL Server) часто сопровождается неожиданным поведением системы. Одной из таких проблем является возникновение синтаксических ошибок вида «Переменная не определена» при попытке открыть Конструктор запросов в пользовательском режиме. Примечательно, что в Конфигураторе обычная проверка синтаксиса может показывать, что ошибок не обнаружено, а сам запрос в обычном режиме выполняется без нареканий.
В этой статье мы подробно разберем, почему возникает эта ошибка, как особенности компиляции программных модулей в различных режимах запуска влияют на поведение платформы «1С:Предприятие» и какими способами можно навсегда устранить эту проблему согласно стандартам разработки.
При запуске Конструктора запросов в пользовательском режиме платформа 1С выполняет динамический анализ метаданных. Ей необходимо построить интерактивное дерево таблиц, доступных для выбора. В этот момент происходит неявная инициализация и компиляция модулей менеджеров объектов (в нашем примере — модуля менеджера справочника ДоговорыКонтрагентов), которые участвуют в запросе.
Проблема кроется в месте компиляции этого модуля и доступности контекста:
Взаиморасчеты. Если у общего модуля Взаиморасчеты в свойствах установлен только флаг «Сервер», клиентское приложение ничего не знает о существовании этого модуля. При компиляции кода на стороне клиента платформа выдает закономерную ошибку: Переменная не определена (Взаиморасчеты).Многие разработчики задаются вопросом: почему при нажатии кнопки «Синтаксический контроль» в Конфигураторе система рапортует об отсутствии ошибок? Дело в том, что по умолчанию проверка выполняется для основного режима запуска конфигурации — Управляемого приложения (Тонкий клиент). В этом режиме модуль менеджера считается чисто серверным, его компиляция на клиенте не моделируется, и обращение к серверному общему модулю Взаиморасчеты признается абсолютно корректным.
Чтобы Конфигуратор смог обнаружить эту ошибку на этапе разработки, выполним синтаксический контроль с правильными настройками. Проанализируем ситуацию по шагам:
Теперь, когда мы понимаем природу ошибки, рассмотрим три способа ее решения: от быстрого «костыля» до архитектурно правильных подходов.
Самый надежный и правильный метод решения подобных проблем с контекстом — разделение выполнения кода с помощью инструкций препроцессора. Это исключит компиляцию серверных вызовов на стороне клиента без изменения логики работы конфигурации.
Рассмотрим подробнее, как должен выглядеть программный код в модуле менеджера справочника ДоговорыКонтрагентов. Нам необходимо обернуть вызовы процедур и функций общего модуля Взаиморасчеты в инструкцию препроцессора:
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
ТаблицаГрафика = Взаиморасчеты.ПолучитьАктуальныйГрафикПогашенияЗайма(ДоговорКонтрагента, ТекущаяДата());
ЗначениеПараметра = Взаиморасчеты.ПоказательВЗаданнойПериодичности(Выборка.Процент, "Год", Выборка.ПериодичностьПроцентнойСтавки);
#КонецЕсли
При таком подходе во время компиляции модуля менеджера на стороне толстого управляемого клиента этот блок кода будет просто проигнорирован. Ошибка компиляции исчезнет, а на сервере код продолжит выполняться в штатном режиме.
Если вы разрабатываете современное решение на управляемых формах, использование Толстого клиента для повседневной работы и отладки постепенно уходит в прошлое. Начиная с версии платформы 8.3.5, стандартный Конструктор запросов платформы умеет полноценно работать в режиме Тонкого клиента через специальное веб-окно.
Для исправления ситуации выполним следующие действия:
В режиме тонкого клиента модуль менеджера компилируется исключительно на сервере. Соответственно, клиентская часть платформы даже не попытается прочитать код обращения к общему модулю Взаиморасчеты, и ошибка не возникнет.
Этот способ позволяет быстро решить проблему «здесь и сейчас», однако использовать его следует с большой осторожностью, так как он нарушает стандарты разработки фирмы «1С».
Для реализации этого способа найдем в дереве метаданных общий модуль Взаиморасчеты, откроем его свойства (палитру свойств) и установим флажок «Вызов сервера» (при этом флаг «Сервер» также должен быть активен).
После этого клиентский контекст Толстого клиента получит доступ к экспортным методам этого модуля, компиляция пройдет успешно, и Конструктор запросов откроется без ошибок.
Важное предупреждение: Бессистемное включение свойства «Вызов сервера» для общих модулей является плохой практикой (антипаттерном) по следующим причинам:
СправочникОбъект, а не ссылки).При возникновении ошибок компиляции модулей менеджера при работе в консоли запросов всегда анализируйте контекст выполнения вашего кода. Наиболее технологичным решением является использование современных консолей запросов в Тонком клиенте и аккуратное обрамление потенциально опасного кода в модулях менеджеров и объектов директивами препроцессора #Если Сервер Тогда. Это обеспечит стабильную работу системы и избавит конфигурацию от избыточных вызовов сервера.