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