В практике разработки на платформе 1С:Предприятие 8 часто возникает ситуация, когда в конфигурации существует несколько общих модулей с идентичным набором экспортных процедур и функций. Например, это могут быть модули интеграции с разными API-сервисами, где каждый модуль отвечает за свою систему, но реализует стандартный набор команд: ПолучитьДанныеПоКоду, ОтправитьЗаказ или ПроверитьСтатус. Проблема заключается в том, что имя нужного модуля становится известным только в момент выполнения кода (в рантайме), и прописывать жесткие условия Если...ИначеЕсли для десятков модулей — решение не самое изящное и трудноподдерживаемое.
В этой статье мы подробно разберем, как реализовать универсальное обращение к общим модулям, используя их строковые имена, и какие архитектурные подходы считаются наиболее правильными.
Самый быстрый и прямой способ получить доступ к функционалу общего модуля, если у вас есть его имя в виде строки — это использование встроенной функции Вычислить. Проанализируем, как это работает на практике. Когда мы передаем имя общего модуля в эту функцию, платформа возвращает ссылку на сам объект модуля, через которую можно вызывать его экспортные методы.
Рассмотрим пример кода:
// Имя модуля получено из настроек или справочника
ИмяМодуля = "Анхель";
ПараметрПоиска = "nnn279";
// Получаем "ссылку" на общий модуль
МодульОбъект = Вычислить(ИмяМодуля);
// Вызываем нужную функцию
Результат = МодульОбъект.ПолучитьДанныеПоКоду(ПараметрПоиска);
Этот метод хорош тем, что он прост в реализации. Однако стоит помнить о безопасности: если переменная ИмяМодуля придет из ненадежного источника, это может привести к ошибкам выполнения. Поэтому всегда рекомендуется оборачивать такие вызовы в блок Попытка...Исключение.
Если ваша конфигурация построена на базе Библиотеки стандартных подсистем (БСП), то в ней уже реализован безопасный механизм для подобных задач. Мы рекомендуем использовать функцию ОбщийМодуль из модуля ОбщегоНазначения. Этот метод по сути является оберткой над Вычислить, но он выполняет дополнительные проверки.
Пример использования БСП:
ИмяМодуля = "Ронус";
// Безопасное получение модуля через стандартную функцию БСП
Модуль = ОбщегоНазначения.ОбщийМодуль(ИмяМодуля);
Данные = Модуль.ПолучитьДанныеПоКоду("nnn279");
Такой подход делает код более читаемым для других разработчиков, знакомых со стандартами разработки 1С, и централизует обработку возможных ошибок доступа к метаданным.
Иногда задача стоит сложнее: динамически нужно определять не только имя модуля, но и имя самой процедуры. В этом случае функция Вычислить не подойдет, так как она возвращает значение, а нам нужно выполнить произвольный кусок кода. Здесь на помощь приходит оператор Выполнить.
Разберем ситуацию, когда и модуль, и метод хранятся в переменных:
ИмяМодуля = "ИнтеграцияСДропшиппингом";
ИмяМетода = "ОбновитьОстатки";
ЗначениеПараметра = 100;
// Формируем строку кода для выполнения
ТекстВызова = СтрШаблон("%1.%2(Параметр)", ИмяМодуля, ИмяМетода);
// Переменная "Параметр" должна быть доступна в текущем контексте
Параметр = ЗначениеПараметра;
Выполнить(ТекстВызова);
Важное замечание: использование Выполнить и Вычислить замедляет работу системы, так как платформе требуется время на компиляцию строки в исполняемый код. Если вы вызываете метод в цикле по тысячам строк, лучше один раз получить ссылку на модуль через Вычислить вне цикла, а внутри цикла уже обращаться к методу через точку.
Если вы хотите избежать «магических» строк и сделать систему максимально прозрачной для отладки, рассмотрим создание модуля-диспетчера. Этот подход позволяет сохранить типизацию и упростить поиск ссылок в конфигураторе. Мы создаем один общий модуль (например, ИнтеграцияДиспетчер), который перенаправляет вызовы.
Проанализируем пример реализации:
Функция ВыполнитьЗапросКСистеме(ИмяСистемы, КодТовара) Экспорт
Если ИмяСистемы = "Анхель" Тогда
Возврат Анхель.ПолучитьДанныеПоКоду(КодТовара);
ИначеЕсли ИмяСистемы = "Ронус" Тогда
Возврат Ронус.ПолучитьДанныеПоКоду(КодТовара);
КонецЕсли;
ВызватьИсключение "Неизвестная система интеграции: " + ИмяСистемы;
КонецФункции
Несмотря на то, что этот способ требует добавления новой строки при появлении нового модуля, он считается наиболее надежным в крупных проектах, так как 1С может автоматически проверять синтаксис и связи между объектами.
Если список внешних программ постоянно растет, и вы не хотите каждый раз обновлять конфигурацию (вносить изменения в метаданные и выгонять пользователей), логично использовать внешние обработки. Мы можем хранить их в справочнике «Дополнительные отчеты и обработки».
Рассмотрим алгоритм действий:
ПолучитьДанныеПоКоду.
// Получаем двоичные данные обработки из справочника или с диска
СсылкаНаОбработку = Справочники.ДополнительныеОтчетыИОбработки.НайтиПоНаименованию("Интеграция_НоваяСистема");
ИмяФайла = ВнешниеОбработки.Создать(СсылкаНаОбработку.ИмяФайла, Ложь);
// Создаем объект и вызываем метод
ОбъектИнтеграции = ВнешниеОбработки.Создать(ИмяФайла);
Результат = ОбъектИнтеграции.ПолучитьДанныеПоКоду("nnn279");
Этот метод обеспечивает максимальную гибкость: вы можете добавить поддержку новой программы, просто загрузив новую обработку в пользовательском режиме.
При использовании динамических вызовов следует учитывать несколько критических моментов:
Вычислить и Выполнить может быть ограничено профилями безопасности.Подводя итог, можно сказать: для простых внутренних задач идеально подходит Вычислить(), для типовых решений на БСП — метод ОбщегоНазначения.ОбщийМодуль(), а для сложных и часто меняющихся систем интеграции лучше выбрать архитектуру с внешними обработками.