Как обеспечить доступность общего модуля для работы с формой в тонком и толстом клиенте

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

В процессе разработки на платформе 1С:Предприятие 8.3 (особенно в крупных конфигурациях вроде УТ 11, ERP или КА) программисты часто сталкиваются с ситуацией, когда код, успешно работающий в тонком клиенте, внезапно выдает ошибку «Переменная не определена» при запуске в толстом клиенте или через инструменты разработчика. Рассмотрим детально, почему это происходит и как правильно организовать вызов процедур, оперирующих контекстом формы, из общих модулей.

Разбор технической проблемы

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

Основная причина кроется в том, как 1С компилирует программный код для различных типов клиентских приложений. Флаг «Клиент (управляемое приложение)» обеспечивает доступность модуля в тонком клиенте и веб-клиенте. Однако для того, чтобы этот же модуль был доступен в толстом клиенте (даже если он работает в режиме управляемого приложения), системе требуются дополнительные настройки или проверки контекста.

Решение 1: Настройка свойств общего модуля

Первым делом проверим свойства общего модуля в дереве метаданных. Разберем по шагам, какие флаги за что отвечают:

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

Важно: Чтобы исправить ошибку в толстом клиенте, убедитесь, что у модуля стоят флаги «Клиент (управляемое приложение)» и проверьте необходимость флага «Клиент (обычное приложение)», если работа ведется в смешанном режиме или используются внешние компоненты отладки.

Решение 2: Использование директив препроцессора

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


#Если Клиент Тогда
// Процедура будет скомпилирована только на стороне клиента
Процедура УстановитьЗначениеРеквизитаЕстьУточнение(ЭтаФорма) Экспорт
    // Проверяем наличие реквизита перед установкой, чтобы избежать ошибок рантайма
    Попытка
        ЭтаФорма.ЕстьУточнение = Истина;
    Исключение
        ЗаписьЖурналаРегистрации("Ошибка.РаботаСФормой", УровеньЖурналаРегистрации.Ошибка,,, 
            ПодробноеОписаниеОшибки(ИнформацияОбОшибке()));
    КонецПопытки;
КонецПроцедуры
#КонецЕсли

Использование #Если Клиент Тогда позволяет объединить условия для Тонкого, Толстого и Веб-клиента, делая ваш общий модуль более универсальным.

Решение 3: Правильная передача контекста формы

Выясним, как правильно взаимодействовать с формой из общего модуля, чтобы код оставался стабильным. Когда мы передаем ЭтаФорма в процедуру общего модуля, мы передаем ссылку на контекст управляемой формы. Посмотрим на правильный вызов из модуля формы:


&НаКлиенте
Процедура аситВыбранаСложнаяШирина(Элемент)
    // Передаем текущий контекст формы в общий клиентский модуль
    РаботыСФормамиКлиент.УстановитьЗначениеРеквизитаЕстьУточнение(ЭтаФорма);
КонецПроцедуры

В общем модуле РаботыСФормамиКлиент (у которого в свойствах стоит только «Клиент»):


Процедура УстановитьЗначениеРеквизитаЕстьУточнение(ЭтаФорма) Экспорт
    // Мы можем обращаться к реквизитам и элементам формы напрямую
    ЭтаФорма.ЕстьУточнение = Истина;
КонецПроцедуры

Если же ваша логика требует обращения к серверу (например, нужно проверить остатки или цены в базе), нельзя передавать форму в серверный модуль. Вместо этого разберем алгоритм разделения ответственности:

  1. На клиенте собираем нужные данные из формы в Структуру.
  2. Передаем Структуру в серверный общий модуль.
  3. Получаем результат с сервера.
  4. На клиенте (в клиентском общем модуле) обновляем реквизиты формы на основе полученных данных.

Архитектурный вопрос: Стоит ли выносить работу с формой в общий модуль?

В сообществе разработчиков существует мнение, что работа с контекстом формы в общем модуле — это «порочная практика». Однако, проанализировав стандарты разработки 1С (БСП), мы увидим обратное. Общие модули с постфиксом Клиент специально созданы для того, чтобы:

Резюмируем: Если код относится исключительно к логике одной конкретной формы, его лучше оставить в модуле этой формы. Если же процедура (например, УстановитьЗначениеРеквизитаЕстьУточнение) вызывается в десяти разных формах — использование общего модуля является единственно верным архитектурным решением.

Итоги и рекомендации

Для устранения ошибки «Переменная не определена» в толстом клиенте выполните следующие действия:

  1. Проверьте флаги в свойствах общего модуля: должен быть активен «Клиент (управляемое приложение)».
  2. Если вы используете специфическое окружение (старые инструменты отладки), попробуйте временно включить флаг «Клиент (обычное приложение)» (может потребоваться включение возможности редактирования конфигурации).
  3. Убедитесь, что вы не пытаетесь вызвать процедуру, работающую с ЭтаФорма, из модуля с флагом «Сервер» или «Вызов сервера».
  4. Используйте #Если Клиент Тогда внутри модуля для явного указания области видимости кода.

Соблюдение этих правил обеспечит стабильную работу вашего приложения во всех типах клиентских сессий и упростит дальнейшую поддержку кода.

← На главную