Почему расширение в толстом клиенте 1С не видит общие модули и как это исправить?

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

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

Разберем причины возникновения проблемы

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

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

Шаг 1: Проверка флагов доступности общего модуля

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

  1. Клиент (управляемое приложение): Для работы в толстом клиенте управляемого приложения этот флаг обязателен. Если он снят, клиентская часть толстого клиента не будет знать о существовании модуля.
  2. Сервер: Этот флаг должен стоять практически всегда, если логика модуля предполагает работу с данными.
  3. Толстый клиент, обычное приложение: Если ваша база поддерживает работу в режиме обычного приложения или вы используете специфические инструменты отладки, этот флаг также должен быть включен.

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

Шаг 2: Анализ директив препроцессора

Часто код "исчезает" из-за неправильного использования инструкций препроцессора внутри самого модуля. Чтобы быстро локализовать все места использования подобных процедур, можно применить автоматизированный поиск вызовов общих модулей. Проанализируем следующий пример:


#Если Сервер Тогда
Процедура ВыполнитьДействиеНаСервере() Экспорт
    // Код процедуры
КонецПроцедуры
#КонецЕсли

В тонком клиенте этот код будет доступен через серверный вызов. Однако в толстом клиенте, если контекст выполнения определен как клиентский, данный блок кода будет проигнорирован компилятором. Чтобы процедура была видна везде, где это допустимо, следует использовать комбинированные условия:


#Если Сервер Или ТолстыйКлиентУправляемоеПриложение Или ВнешнееСоединение Тогда
Процедура УниверсальнаяПроцедура() Экспорт
    // Этот код будет доступен в толстом клиенте
КонецПроцедуры
#КонецЕсли

Шаг 3: Решение проблемы вызова из модуля менеджера

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

Для решения этой проблемы применим метод создания "промежуточного" модуля. Выполним следующие действия:

  1. Создадим в расширении новый общий модуль, например, с именем Р_ОбщийМодульСервер.
  2. В свойствах этого модуля установим флаги Сервер и Вызов сервера.
  3. Перенесем логику обращения к нужному функционалу в этот модуль.

Пример кода в модуле менеджера расширения:


&Вместо("ОбработкаПолученияДанныхВыбора")
Процедура Р_ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка)
    // Вместо прямого вызова проблемного модуля, вызываем наш промежуточный
    Р_ОбщийМодульСервер.ВызватьНужнуюФункцию();
КонецПроцедуры

Флаг Вызов сервера принудительно регистрирует модуль в экспортном контексте, что делает его "видимым" для всех участков кода расширения.

Шаг 4: Особенности работы в обычном приложении

Существует заблуждение, что расширения не работают в обычном приложении. На самом деле, начиная с платформы 8.3.13, расширения поддерживаются и там. Если ваша задача связана с обычными формами, убедитесь, что в свойствах модуля расширения стоит флаг Клиент (обычное приложение).

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

Шаг 5: Очистка кэша и обновление конфигурации

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

Попробуйте выполнить следующие действия:

Подводя итог, можно сказать, что решение проблемы видимости в толстом клиенте сводится к правильной настройке контекста исполнения. Использование промежуточного модуля с Вызовом сервера — это наиболее надежный способ "прокинуть" управление в нужную точку, когда стандартные механизмы поиска имен в расширении дают сбой.

← На главную