Как обратиться к общему модулю в другой конфигурации без ошибки компиляции?

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

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

Выясним причину ошибки платформы

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

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

Способ 1. Динамический вызов с помощью Вычислить() и Выполнить()

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

Разберем различие между ними:

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

Посмотрим на пример применения функции Вычислить() в универсальном коде получения курса валют:


Функция ПолучитьКурсВалюты(Валюта, Дата) Экспорт
    Если УТ_11() Тогда
        Возврат Вычислить("РаботаСКурсамиВалют.ПолучитьКурсВалюты(Валюта, Дата)");
    Иначе
        Возврат Вычислить("МодульВалютногоУчета.ПолучитьКурсВалюты(Валюта, Дата)");
    КонецЕсли;
КонецФункции

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


Функция ПолучитьКурсВалюты(Валюта, Дата) Экспорт
    Структура = Неопределено;
    Если УТ_11() Тогда
        Выполнить("Структура = РаботаСКурсамиВалют.ПолучитьКурсВалюты(Валюта, Дата)");
    Иначе
        Выполнить("Структура = МодульВалютногоУчета.ПолучитьКурсВалюты(Валюта, Дата)");
    КонецЕсли;
    Возврат Структура;
КонецФункции

Важный момент: динамическое выполнение строк имеет свои ограничения. В веб-клиенте оператор Выполнить() не поддерживается, а на платформе iOS в мобильном приложении может вызывать исключения. Учитывайте контекст исполнения вашего кода.

Способ 2. Использование механизмов Библиотеки Стандартных Подсистем (БСП)

Если целевые конфигурации построены на базе БСП (например, «Управление торговлей», «Бухгалтерия предприятия», «ERP»), разберем более технологичный способ обращения к модулям без использования динамических строк Вычислить().

В БСП предусмотрены специальные функции для безопасного получения ссылки на общий модуль и проверки существования подсистем:


// Безопасное получение общего модуля по имени
ИмяМодуля = "РаботаСКурсамиВалют";
Модуль = ОбщегоНазначения.ОбщийМодуль(ИмяМодуля);

Если Модуль <> Неопределено Тогда
    Результат = Модуль.ПолучитьКурсВалюты(Валюта, Дата);
КонецЕсли;

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

Способ 3. Проверка метаданных платформы

Если нужно проверить физическое наличие общего модуля в дереве метаданных без привлечения БСП, проанализируем обращение к свойству Метаданные:


Если Метаданные.ОбщиеМодули.Найти("РаботаСКурсамиВалют") <> Неопределено Тогда
    Возврат Вычислить("РаботаСКурсамиВалют.ПолучитьКурсВалюты(Валюта, Дата)");
ИначеЕсли Метаданные.ОбщиеМодули.Найти("МодульВалютногоУчета") <> Неопределено Тогда
    Возврат Вычислить("МодульВалютногоУчета.ПолучитьКурсВалюты(Валюта, Дата)");
КонецЕсли;

Сочетание проверки через Метаданные.ОбщиеМодули.Найти() и вызова через Вычислить() гарантирует безопасную работу алгоритма в любых конфигурациях 1С.

← На главную