При активной разработке внешних инструментов на платформе 1С:Предприятие 8.3 часто возникает ситуация, когда несколько обработок используют одни и те же алгоритмы, функции или процедуры. Дублирование кода — это всегда риск ошибок при обновлении и избыточная работа для программиста. В этой статье мы подробно разберем, как правильно организовать архитектуру внешних обработок так, чтобы общий код хранился в одном месте, и проанализируем наиболее эффективные подходы.
Этот метод позволяет хранить общие процедуры и функции в отдельном файле .epf и вызывать их из других обработок. Рассмотрим ситуацию, когда у нас есть "Рабочая обработка" и "Обработка-библиотека" (например, с именем ВО_Тест.epf).
Для реализации этого подхода в основной обработке нам потребуется механизм программного подключения. Разберем пример кода, который позволяет инициализировать внешнюю обработку и вызвать её экспортный метод:
&НаКлиенте
Процедура ВыполнитьОбщийКод()
// Помещаем файл во временное хранилище для передачи на сервер
лИмяФайлаВХранилище = "";
лРезультат = ПоместитьФайл(лИмяФайлаВХранилище, "c:\ExternalLibs\CommonLibrary.epf", , Ложь);
Если лРезультат Тогда
ПодключитьИВыполнитьНаСервере(лИмяФайлаВХранилище);
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ПодключитьИВыполнитьНаСервере(пАдресХранилища)
// Регистрируем обработку в системе
ИмяОбработки = ВнешниеОбработки.Подключить(пАдресХранилища, , Ложь);
// Создаем экземпляр объекта
ОбъектБиблиотека = ВнешниеОбработки.Создать(ИмяОбработки);
// Вызываем экспортную процедуру из модуля объекта библиотеки
ОбъектБиблиотека.ПроцедураТест();
КонецПроцедуры
Важный нюанс: Многие разработчики сталкиваются с тем, что ссылка на созданный объект "исчезает" после завершения серверного вызова. Проанализируем причину: объект типа ВнешняяОбработкаОбъект не является сериализуемым, поэтому его нельзя сохранить в реквизите формы. При каждом новом серверном вызове (например, при нажатии кнопки на форме) обработку необходимо создавать заново с помощью метода ВнешниеОбработки.Создать().
Чтобы оптимизировать этот процесс и не считывать файл с диска каждый раз, рекомендуется один раз поместить двоичные данные файла библиотеки в Временное хранилище и сохранять только АдресХранилища в реквизите формы. Это значительно ускорит повторные вызовы.
Если задача позволяет вносить минимальные изменения в информационную базу (без изменения основной конфигурации), использование Расширений является наиболее "чистым" и производительным решением. Мы можем вынести весь общий код в ОбщийМодуль расширения.
Разберем по шагам процесс реализации:
Общий модуль (например, с именем ОбщиеМетодыВнешнихОбработок).Экспорт.Пример кода в общем модуле расширения:
Функция РассчитатьСуммуСУчетомСкидки(Сумма, Процент) Экспорт
Возврат Сумма * (1 - Процент/100);
КонецФункции
Теперь из любой внешней обработки вы можете обращаться к этой функции напрямую, как если бы она была частью основной конфигурации: ОбщиеМетодыВнешнихОбработок.РассчитатьСуммуСУчетомСкидки(100, 5);. Это избавляет от необходимости подключать файлы и следить за путями в файловой системе.
Если ваша конфигурация построена на базе БСП (Библиотека стандартных подсистем), мы можем использовать встроенный справочник для хранения общих модулей. Проанализируем ситуацию: вместо прямого обращения к файлу на диске, мы регистрируем нашу "библиотеку" как дополнительную обработку.
Для вызова кода из такой обработки используется программный интерфейс БСП. Рассмотрим пример вызова:
// Получаем ссылку на дополнительную обработку по наименованию
СсылкаНаБиблиотеку = Справочники.ДополнительныеОтчетыИОбработки.НайтиПоНаименованию("ОбщаяБиблиотека");
// Используем стандартный метод БСП для получения объекта
ОбъектБиблиотека = ДополнительныеОтчетыИОбработки.ОбъектВнешнейОбработки(СсылкаНаБиблиотеку);
// Выполняем нужный метод
ОбъектБиблиотека.ВыполнитьДействие();
Преимущество: Этот метод безопасен, так как файл хранится в базе данных, а не на диске сервера. Система сама управляет правами доступа и временными файлами.
Выясним еще один интересный архитектурный прием. Если две обработки имеют идентичную логику, но разные интерфейсы или стартовые параметры, можно сделать одну "Мастер-обработку", а остальные превратить в "оболочки".
В этом случае вспомогательная обработка при открытии просто вызывает форму основной обработки, передавая ей нужные параметры:
&НаКлиенте
Процедура ПриОткрытии(Отказ)
Отказ = Истина; // Отменяем открытие текущей формы
ПараметрыОткрытия = Новый Структура("РежимРаботы", "Упрощенный");
ОткрытьФорму("ВнешняяОбработка.МастерОбработка.Форма", ПараметрыОткрытия);
КонецПроцедуры
Таким образом, весь код сосредоточен в одном файле МастерОбработка.epf, что максимально упрощает поддержку.
Выясним, какой метод лучше выбрать в зависимости от условий:
ВнешниеОбработки.Подключить() с кэшированием двоичных данных во временном хранилище.При использовании программного подключения всегда помните о параметре БезопасныйРежим. Если вы устанавливаете его в Истина, доступ к файловой системе и некоторым другим функциям внутри общего кода может быть ограничен. Для полноценной работы системных библиотек часто требуется установка этого параметра в значение Ложь.