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