При разработке в обычном приложении на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией: при попытке вызвать экспортную процедуру или функцию общего модуля из формы обработки возникает ошибка «Переменная не определена <ИмяМодуля>». Проблема проявляется именно тогда, когда у общего модуля устанавливается флаг «Привилегированный».
Рассмотрим подробно причины такого поведения платформы 1С, выясним, почему имя модуля пропадает из контекста клиента, и разберем проверенные способы решения этой проблемы.
Разберем по шагам, что происходит в платформе 1С при настройке свойств общего модуля:
Привилегированный, платформа автоматический снимает флаги компиляции для клиента (например, Клиент (обычное приложение)). Модуль начинает компилироваться исключительно на стороне сервера.Вызов сервера, платформа не регистрирует имя этого модуля в глобальном клиентском контексте. В результате клиентский код на этапе синтаксического контроля и компиляции просто не «видит» имя модуля и выдает ошибку «Переменная не определена».Самый простой и быстрый способ вернуть видимость модулю на клиенте — настроить правильно свойства метаданных общего модуля.
Выясним, какие флаги должны быть включены у общего модуля в дереве метаданных:
После установки флага Вызов сервера имя модуля экспортируется в контекст клиента, и вызов процедур вида МодульСервер.ВыполнитьПроцедуру() из модуля формы начинает работать корректно.
Важное ограничение: При использовании флага Вызов сервера функции модуля становятся границей между клиентом и сервером. Через эту границу запрещено передавать и возвращать мутабельные объекты (такие как СправочникОбъект, ДокументОбъект, ТаблицаЗначений, ДеревоЗначений). Допустимо использовать только немутабельные типы: ссылки (например, СправочникСсылка.Номенклатура), примитивные типы (число, строка, дата, булево) и структуры/массивы из них.
Согласно стандартам разработки 1С, делать весь модуль одновременно доступным для вызова с клиента и привилегированным небезопасно с точки зрения безопасности данных. Любой клиентский код сможет обратиться к серверным функциям в обход встроенной системы прав доступа.
Более надежный подход — оставить модуль обычным серверным с флагом Вызов сервера (без флага Привилегированный в метаданных), а в коде процедуры включать повышенные права точечно с помощью метода УстановитьПривилегированныйРежим().
Посмотрим на пример реализации в коде общего модуля:
Процедура ВыполнитьОперациюПовышеннойСложности(Параметры) Экспорт
// Включаем привилегированный режим для выполнения операции без проверки прав
УстановитьПривилегированныйРежим(Истина);
// Выполнение действий, требующих повышенных прав
// ...
// Отключаем привилегированный режим (или он отключится автоматически при завершении вызова)
УстановитьПривилегированныйРежим(Ложь);
КонецПроцедуры
При использовании этого метода привилегированный режим действует только внутри конкретного участка кода, что полностью соответствует стандартам безопасной разработки.
Если серверный logic достаточно объемен, проанализируем архитектурное решение с разделением на два модуля:
Сервер и Вызов сервера, но НЕ имеет флага Привилегированный. Этот модуль принимаем вызовы от клиента, проверяет параметры и права пользователя.Сервер и Привилегированный, но НЕ имеет флага Вызов сервера. Этот модуль недоступен напрямую с клиента, но вызывается из первого публичного модуля на стороне сервера.Такой подход гарантирует полное разделение клиентского интерфейса и служебных алгоритмов, работающих с привилегированными правами.
Если все флаги (включая Вызов сервера) установлены, но ошибка «Переменная не определена» сохраняется, проанализируем синтаксическую корректность самого модуля.
Если внутри общего модуля есть синтаксическая ошибка (например, обращение к несуществующей переменной или неверное имя функции), платформа 1С при старте или компиляции модуля не может зарегистрировать его имя в контексте приложения. Выполните синтаксический контроль модуля (сочетание клавиш Ctrl + F7 в конфигураторе), чтобы убедиться в отсутствии внутренних ошибок.