Почему расширение не видит функции общего модуля и как это исправить?

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

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

Суть проблемы: контекст компиляции

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

Разберем на примере

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


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

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

Решение проблемы: правильное использование директив

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

Выполним следующие шаги:

  1. Откроем модуль менеджера в расширении.
  2. Найдем заимствованный метод.
  3. Обернем код метода (или весь модуль, если необходимо соответствовать структуре основной конфигурации) в директиву #Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда.

Пример исправленного кода в расширении:


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

Альтернативный подход: флаг «Вызов сервера»

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

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

Подведем итоги

Работа в расширениях требует внимательного отношения к контексту исполнения. Запоминайте главные правила:

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

← На главную