Как исправить ошибку «Переменная не определена» при вызове общего модуля из расширения в 1С:Предприятие

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

При разработке в среде 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда при попытке вызвать процедуру или функцию из вновь созданного общего модуля в расширении система выдает ошибку компиляции: «Переменная не определена (ИмяОбщегоМодуля)». Эта проблема особенно коварна, поскольку визуально модуль существует, имя написано без ошибок, а ключевое слово Экспорт присутствует на своем месте. Давайте подробно разберем, почему возникает эта ошибка, проанализируем механизмы работы платформы с расширениями и выясним, как правильно настроить систему для корректной работы.

Причина 1. Неверно выбрано назначение расширения конфигурации

Самым частым и неочевидным фактором, из-за которого платформа отказывается видеть общий модуль расширения, является свойство самого расширения под названием «Назначение». Рассмотрим подробнее, как этот параметр влияет на компиляцию кода.

В платформе 1С существует три основных типа назначения расширений:

  1. Исправление (Patch): Предназначено исключительно для быстрой сборки и наложения хотфиксов (исправления ошибок) в существующем коде основной конфигурации. Расширения с этим типом компилируются первыми, имеют жесткие ограничения и не рассчитаны на добавление новой масштабной бизнес-логики. При создании нового общего модуля в таком расширении платформа на этапе инициализации клиентского сеанса часто просто игнорирует его регистрацию в глобальном контексте. В результате в модуле формы при попытке вызвать этот модуль мы получаем ошибку о неопределенной переменной.
  2. Адаптация: Это стандартный и наиболее гибкий режим, разработанный специально для кастомизации и доработки прикладных решений под нужды конкретного внедрения. В этом режиме платформа полноценно регистрирует все новые объекты метаданных, включая общие модули, и делает их доступными во всех объявленных контекстах.
  3. Дополнение: Используется для создания обособленных, независимых функциональных блоков, которые работают «параллельно» основной конфигурации.

Для решения проблемы нам необходимо проверить и изменить назначение нашего расширения. Разберем этот процесс по шагам:

  1. Откроем конфигуратор и перейдем в меню Конфигурация — Расширения конфигурации.
  2. В открывшемся списке найдем наше рабочее расширение.
  3. Обратим внимание на колонку «Назначение». Если там установлено значение «Исправление», его обязательно нужно изменить.
  4. Откроем палитру свойств расширения (нажав правой кнопкой мыши и выбрав «Свойства»).
  5. В строке «Назначение» выберем вариант «Адаптация».
  6. Сохраним изменения и обновим базу данных.

Причина 2. Ошибочное использование директив компиляции в общем модуле

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

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

Если нам требуется разделить выполнение кода внутри одного общего модуля на клиентскую и серверную части, мы должны использовать инструкции препроцессора (начинающиеся с символа решетки «#»). Посмотрим на правильный пример реализации кода внутри общего модуля расширения:


#Если Клиент Тогда

Функция db_Сообщить() Экспорт
    Сообщить("Вызов процедуры общего модуля на стороне клиента");
КонецФункции

#КонецЕсли

В данном примере препроцессор при компиляции клиентского приложения оставит эту функцию доступной, а при компиляции на сервере — проигнорирует её, что исключит возникновение конфликтов сред выполнения.

Причина 3. Неправильно настроенные клиент-серверные свойства общего модуля

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

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


&НаКлиенте
Процедура db_ПослеЗаписиПосле(ПараметрыЗаписи)
    db_ПроцедурыИФункции.db_Сообщить();
КонецПроцедуры

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

  1. Найдем наш общий модуль в дереве метаданных расширения.
  2. Откроем его палитру свойств.
  3. Если вызов происходит из процедуры с директивой &НаКлиенте (как в нашем примере), в свойствах модуля обязательно должен стоять флаг «Клиент (управляемое приложение)».
  4. Если процедура общего модуля должна выполняться на сервере, но вызываться с клиента, нам необходимо установить флаг «Сервер» и обязательно включить флаг «Вызов сервера». Без флага «Вызов сервера» тонкий или веб-клиент не смогут инициировать выполнение серверного метода напрямую.
  5. Убедимся, что у самой процедуры или функции в общем модуле в конце сигнатуры указано ключевое слово Экспорт, иначе метод останется локальным для модуля.

Причина 4. Влияние безопасного режима расширения

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

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

  1. Зайдем в режим «1С:Предприятие» под пользователем с правами Администратора.
  2. Откроем список установленных расширений (в типовых конфигурациях это обычно раздел НСИ и администрирование — Печатные формы, отчеты и обработки — Расширения).
  3. Найдем наше расширение в списке.
  4. Снимем флажок «Безопасный режим» (для этого у текущего пользователя должны быть полные права).
  5. Перезапустим сеанс работы программы.

Альтернативное решение: Динамический вызов через Библиотеку стандартных подсистем (БСП)

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

Рассмотрим пример получения общего модуля динамическим путем на стороне клиента:


&НаКлиенте
Процедура db_ПослеЗаписиПосле(ПараметрыЗаписи)
    
    // Динамическое получение клиентского общего модуля через БСП
    МодульКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("db_ПроцедурыИФункции");
    МодульКлиент.db_Сообщить();
    
КонецПроцедуры

Если же вызов планируется на стороне сервера, мы используем серверный аналог функции:


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

Такой подход позволяет избежать жестких ошибок компиляции «Переменная не определена» на этапе сохранения конфигурации, перенося проверку существования модуля на этап выполнения (Runtime). Однако использовать его следует осознанно, отдавая предпочтение штатной статической типизации и правильной настройке свойств расширения, описанной в первых разделах нашей статьи.

← На главную