В процессе модернизации старых конфигураций, работающих в режиме обычного приложения (толстый клиент), мы часто сталкиваемся с необходимостью внедрения управляемых форм. Это так называемый «гибридный» режим работы. Одной из распространенных проблем в такой архитектуре является ошибка видимости общих модулей. Разберем подробно ситуацию, когда при вызове процедуры общего модуля из управляемой формы система выдает ошибку «Переменная не определена», хотя синтаксически вызов оформлен верно.
Рассмотрим сценарий: у нас есть конфигурация, запускаемая в режиме Обычное приложение (Толстый клиент). В свойствах конфигурации установлен флаг, разрешающий использование управляемых форм. Мы создали новую управляемую форму (УФ) и попытались вызвать из нее процедуру экспортного общего модуля.
Пример кода в модуле управляемой формы:
&НаКлиенте
Процедура ТекШтрихкодПриИзменении(Элемент)
// Попытка вызова функции из общего модуля
нКлиент.ВоспроизвестиЗвук(3);
КонецПроцедуры
При выполнении этого кода (или даже при синтаксическом контроле) платформа выдает ошибку:
{Документ.Инвентаризация.Форма.ФормаДокумента.Форма(87,2)}: Переменная не определена (нКлиент)
На первый взгляд это кажется странным. Ведь модуль нКлиент существует, процедура в нем помечена как Экспорт, и вызов происходит из процедуры с директивой &НаКлиенте. Почему платформа не «видит» этот модуль?
Чтобы понять причину, нам нужно разобраться, как платформа 1С:Предприятие загружает контекст приложения.
&НаКлиенте) исполняется по правилам управляемого приложения, доступ к глобальным объектам (общим модулям) ограничивается тем, что загружено в текущий процесс.Таким образом, переменная не найдена не потому, что форма «не видит» модуль, а потому что модуль физически не скомпилирован в текущем сеансе работы пользователя.
Чтобы исправить эту ошибку, нам необходимо явно указать платформе, что данный общий модуль должен быть доступен в контексте обычного приложения. Выполним следующие действия в Конфигураторе:
нКлиент).После установки этого флага и обновления конфигурации базы данных, платформа начнет включать этот модуль в контекст запуска толстого клиента. Ошибка «Переменная не определена» исчезнет.
Если мы разрабатываем функционал, который должен работать универсально (и в старом интерфейсе, и, возможно, через тонкий клиент в будущем), проанализируем оптимальную настройку флагов.
Рекомендуется устанавливать следующую комбинацию для чисто клиентских модулей:
1cv8c.exe (Тонкий клиент).1cv8.exe (Толстый клиент), и мы открываем управляемую форму внутри него.Обратите внимание: если ваш модуль также содержит серверный код или вызывает серверные процедуры, вам могут понадобиться флаги Сервер и Вызов сервера.
В некоторых случаях код внутри общего модуля может использовать методы, которые доступны только в управляемом или только в обычном приложении (например, работа с интерфейсом). В таких ситуациях простого включения галочек недостаточно — код может вызвать ошибку компиляции в «неродной» среде.
Для разделения кода используем инструкции препроцессора. Разберем пример безопасного оформления кода:
Процедура ПоказатьСообщениеПользователю(Текст) Экспорт
#Если ТонкийКлиент Или ТолстыйКлиентУправляемоеПриложение Тогда
// Код для управляемого режима
ПоказатьОповещениеПользователя("Информация", , Текст);
#ИначеЕсли ТолстыйКлиентОбычноеПриложение Тогда
// Код для обычного режима (если нужен специфичный функционал)
Сообщить(Текст);
#КонецЕсли
КонецПроцедуры
Однако в контексте рассматриваемой проблемы (вызов из управляемой формы, открытой в обычном приложении) код, написанный для управляемого приложения, как правило, отрабатывает корректно, так как форма сама по себе является управляемой. Главное — обеспечить видимость самого модуля («контейнера» процедур).
В теме также упоминался старый режим совместимости (Версия 8.2.13). Это важный нюанс. В старых режимах совместимости (ниже 8.3.x) механизмы изоляции кода работают более жестко.
Если вы работаете в режиме совместимости с версией 8.2, убедитесь, что:
&НаКлиенте, &НаСервере.Также стоит помнить, что при переходе на новые версии платформы и отказе от режима совместимости, поведение модальных окон и синхронных вызовов меняется. Если ваша старая конфигурация использует модальность, то вызов процедур из управляемых форм может потребовать рефакторинга в сторону асинхронных методов (например, использование ОписаниеОповещения), но это уже тема для отдельного рассмотрения.
Если при вызове общего модуля из управляемой формы вы получаете ошибку о том, что переменная не найдена, в 99% случаев проблема кроется в настройках компиляции общего модуля. Убедитесь, что для текущего режима запуска (Толстый клиент) разрешена компиляция этого модуля, установив флаг Клиент (обычное приложение).