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