Разработка и Конфигурация · 10 мин
Как проверить наличие общего модуля в 1С
Как проверить наличие общего модуля в 1С: через конфигуратор, кодом с помощью Метаданные, в запросе. Примеры кода, ошибки и ответы на вопросы.
Общий модуль в 1С — это контейнер прикладного кода, процедуры и функции которого доступны из других объектов конфигурации. Проверить его наличие требуется в двух типичных ситуациях: когда вы изучаете чужую или обновлённую конфигурацию и хотите убедиться, что нужный модуль существует, и когда пишете универсальный код, который должен корректно работать в разных конфигурациях — например, в расширении или внешней обработке.
Способ проверки зависит от контекста. Если вы работаете в конфигураторе и просто хотите найти модуль глазами — достаточно дерева метаданных и поиска. Если проверка нужна программно, во время выполнения кода, используется коллекция Метаданные.ОбщиеМодули. Оба подхода имеют свои ограничения: визуальный поиск не подходит для автоматизации, а обращение к метаданным недоступно в некоторых режимах и требует аккуратной работы с регистром имён.
Ниже разобраны оба сценария с примерами кода, типичными ошибками и способами проверить результат. Материал применим к платформе 1С:Предприятие 8.3 в управляемом и обычном приложении.
Проверка через конфигуратор: визуальный способ
Самый простой случай — вам нужно убедиться, что модуль существует в конкретной конфигурации, которую вы открыли в конфигураторе. Откройте дерево конфигурации (меню «Конфигурация» → «Открыть конфигурацию» или сочетание клавиш), разверните ветку «Общие», затем «Общие модули». Все общие модули конфигурации перечислены здесь в алфавитном порядке.
Если модулей много, используйте поиск по дереву метаданных: установите курсор на любой элемент дерева и начните вводить имя — конфигуратор выполнит инкрементный поиск по текущей ветке. Для поиска по всей конфигурации удобнее окно «Поиск» (Ctrl + F в дереве конфигурации) или глобальный поиск по метаданным.
Обратите внимание: модуль может существовать, но быть недоступным из вашего контекста. У общего модуля есть флаги «Сервер», «Клиент (управляемое приложение)», «Клиент (обычное приложение)», «Внешнее соединение». Если вы планируете вызывать его функции, откройте свойства модуля и проверьте, что нужный флаг установлен — иначе получите ошибку «Процедура или функция с указанным именем не определена» уже на этапе выполнения.
Программная проверка через Метаданные.ОбщиеМодули
Когда проверка нужна в коде — например, расширение должно работать с разными конфигурациями, где состав модулей отличается, — используется объектная модель метаданных. Коллекция Метаданные.ОбщиеМодули содержит описания всех общих модулей конфигурации, а метод Найти() ищет модуль по имени.
Базовый вариант проверки выглядит так:
Если Метаданные.ОбщиеМодули.Найти("ОбщегоНазначения") = Неопределено Тогда
// Модуля нет в конфигурации — выполняем обходную логику
Иначе
// Модуль существует, можно обращаться к его экспортным процедурам
КонецЕсли;
Метод Найти() возвращает объект описания метаданного либо Неопределено, если модуль с таким именем не найден. Именно сравнение с Неопределено и есть корректная проверка наличия. Альтернатива — перебор коллекции циклом со сравнением свойства Имя, но для одиночной проверки это избыточно.
Функция ЕстьОбщийМодуль(ИмяМодуля) Экспорт
Возврат Метаданные.ОбщиеМодули.Найти(ИмяМодуля) <> Неопределено;
КонецФункцииБезопасный вызов кода из модуля, которого может не быть
Найти модуль — половина задачи. Вторая половина — обратиться к нему так, чтобы код не упал с ошибкой компиляции в конфигурации, где модуля нет. Прямой вызов вида ОбщегоНазначения.ЗначениеРеквизитаОбъекта() жёстко связывает ваш код с модулем: если его нет, модуль-источник вызова не скомпилируется.
Безопасный приём — вызов через Вычислить() или Выполнить() с предварительной проверкой наличия модуля:
Если Метаданные.ОбщиеМодули.Найти("ОбщегоНазначения") <> Неопределено Тогда
Результат = Вычислить("ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Ссылка, ""Наименование"")");
Иначе
Результат = Неопределено;
КонецЕсли;
У этого подхода есть цена: код внутри Вычислить() — это строка, её не проверяет компилятор, и ошибку в имени метода вы увидите только при выполнении. Поэтому строковые вызовы стоит сосредотачивать в одном адаптерном модуле и покрывать ручной проверкой на каждой целевой конфигурации.
Проверка в расширениях и внешних обработках
Расширения конфигурации — главный потребитель программной проверки модулей. Расширение разрабатывается под конкретную конфигурацию, но часто должно поддерживать несколько её версий или несколько родственных конфигураций, где состав общих модулей различается. Проверка через метаданные позволяет включать нужную ветку логики в зависимости от окружения.
Во внешних обработках и отчётах ситуация похожая: обработка запускается в неизвестной заранее конфигурации. Здесь проверка наличия модуля — обязательный элемент защитного программирования наряду с проверкой наличия справочников, документов и реквизитов через соответствующие коллекции метаданных.
Учтите ограничение: доступ к объекту Метаданные возможен не во всех контекстах. В частности, в некоторых режимах работы внешних компонентов и при определённых настройках безопасного режима обращение к метаданным может быть ограничено. Если обработка работает в безопасном режиме, протестируйте проверку именно в целевом окружении.
Как выбрать действие
Типичные ошибки при проверке и их последствия
Первая ошибка — неправильный регистр или опечатка в имени модуля. Метод Найти() сравнивает имя без учёта регистра, но лишний пробел или опечатка дадут Неопределено, и логика молча уйдёт в ветку «модуля нет». Имя лучше выносить в константу или копировать из конфигуратора.
Вторая ошибка — путать общий модуль с модулем менеджера объекта или модулем объекта. Коллекция Метаданные.ОбщиеМодули содержит только общие модули. Модули объектов и менеджеров справочников и документов ищутся через метаданные соответствующих объектов, и это другая задача.
Третья ошибка — проверять наличие модуля, но не проверять наличие конкретной экспортной процедуры в нём. Модуль может существовать, но нужной функции в данной версии конфигурации ещё (или уже) нет. Универсального метода «найти функцию в модуле» в языке нет, поэтому такие вызовы оборачивают в Попытка...Исключение с осмысленной реакцией на ошибку.
Как убедиться, что проверка работает правильно
После внедрения проверки протестируйте обе ветки логики. Позитивный сценарий: запустите код в конфигурации, где модуль есть, и убедитесь, что выполняется основная ветка и вызов проходит без исключений. Негативный сценарий: временно переименуйте модуль в тестовой копии базы или запустите обработку в конфигурации без этого модуля — должна сработать обходная ветка без ошибок.
Полезный приём — вывести результат проверки в журнал регистрации или в сообщение на этапе отладки. Это позволит быстро понять, какую ветку выбрал код в конкретном окружении, без запуска отладчика.
Как проверить результат
Возвращается объект описания метаданного, значение не равно Неопределено
Возвращается Неопределено — проверьте имя и то, что модуль действительно общий
Функция выполняется и возвращает значение
Ошибка «не определена» — проверьте флаги контекста модуля и ключевое слово Экспорт
Выполняется обходная ветка, исключений нет
Ошибка компиляции или выполнения — прямой вызов не обёрнут в Вычислить()
FAQ: частые вопросы о проверке общих модулей
Можно ли проверить наличие общего модуля в запросе?
Нет. Язык запросов работает с данными информационной базы (таблицами справочников, документов, регистров), а не с метаданными конфигурации. Проверка наличия модуля выполняется только средствами встроенного языка через объект Метаданные.
Учитывает ли Метаданные.ОбщиеМодули модули из расширений?
Метаданные отражают состав конфигурации с учётом подключённых расширений в текущем сеансе. Если расширение добавляет общий модуль и подключено, модуль будет виден через коллекцию. Если расширение отключено или не применено к сеансу, его модули в метаданных не появятся.
Чем Найти() отличается от обращения по индексу?
Метод Найти() ищет по имени и возвращает Неопределено при отсутствии — это безопасный способ. Обращение по строковому индексу (Метаданные.ОбщиеМодули["Имя"]) при отсутствии элемента вызывает исключение, поэтому для проверки наличия оно не подходит.
Как проверить наличие конкретной функции внутри модуля?
Штатного метода перечислить экспортные процедуры модуля во время выполнения нет. Практический подход — обернуть вызов в Попытка...Исключение и при ошибке переключаться на альтернативную реализацию, фиксируя факт в журнале регистрации.
Работает ли проверка через Метаданные на клиенте?
Да, объект Метаданные доступен и на клиенте, и на сервере в управляемом приложении. Однако в тонком и веб-клиенте состав доступных метаданных может отличаться, а в безопасном режиме доступ к метаданным может ограничиваться — проверку стоит тестировать в целевом окружении.
Что делать, если модуль есть, а его процедуры «не видны»?
Проверьте три вещи: установлен ли у процедуры признак Экспорт, включён ли у модуля флаг нужного контекста («Сервер» или «Клиент») и не объявлен ли модуль как привилегированный там, где это не требуется. Также убедитесь, что имя модуля не пересекается с именем другого объекта конфигурации.
Что важно запомнить
Визуально общий модуль ищется в дереве конфигурации: Общие → Общие модули. Программно наличие проверяется выражением Метаданные.ОбщиеМодули.Найти(Имя) <> Неопределено. Для переносимого кода вызовы методов модуля выполняйте через Вычислить() и проверяйте флаги контекста модуля.