На текущем месте работы я занимаюсь разработкой как раз такой внешней обработки, предназначенной для интеграции сервиса компании с различными конфигурациями клиентов. Это и типовые семейства ERP/КА2/УТ11, и их более старые версии на обычных формах УТ10/КА1.1, семейство УНФ/Розница, а также другие решения, основанные на перечисленных типовых и оригинальных тиражных решениях. Поддерживается даже работа с собственными уникальными конфигурациями (нетленки) с возможностью реализовать интеграцию самостоятельно.
Под спойлером делюсь сложностями при разработке этого решения
И как же реализуется интеграция с такими разными конфигурациями? Ведь они имеют не только разную структуру и программное окружение, но и работают на разных платформах! Для этого приходится ограничивать набор используемых методов, например, нельзя использовать СтрШаблон() или аналогичные методы из БСП. Это регулируется в нашей команде специальным соглашением о разработке.
Взаимодействие с базой при этом реализуется через вызов кусочков кода методом Выполнить(), что нарушает стандарт #std669. Сам код при этом хранится в текстовом макете обработки с разбивкой по областям под каждый метод интеграции соответствующей конфигурации. Это хорошее решение, потому что оно работает. Все методы интеграции находятся в одном месте, в основном коде реализован механизм обращения к ним. Но! Для разработки или отладки каждого такого метода интеграции приходится копировать код из макета в место его выполнения и потом не забыть вернуть обратно. Можно, конечно, что-то доработать и непосредственно в макете, но там не будет подсказок и других прелестей редактора кода. Хотя бы подсветку синтаксиса можно включить :)

Необходимость постоянного переноса кода туда-сюда приносит множество неудобств. Что будет, если забыть убрать код, написанный для УТ10 из основного кода обработки, и запустить её не под УТ11? Ошибка! А что если забудешь перенести в макет всё, что сделал за день, а в месте вызова уже код удален? Потеря-потерь...
Как паттерны нам могут помочь при разработке внешней обработки с интеграцией под разные конфигурации?
Вспомним паттерн Стратегия. Он позволяет для одного и того же Контекста реализовать различные Стратегии. Верно?
Давайте представим нашу внешнюю обработку Контестом (я не стал выделять Контекст в отдельную сущность для упрощения). Наша обработка знает, что хочет сделать в базе. Например, создать Заказ клиента. Но она может позволить себе не знать, что в конкретной конфигурации этот документ называется _ДемоСчетНаОплатуПокупателю. Ей это и не интересно.
Тогда интеграция с каждой конфигурацией - это Стратегия. Каждая Стратегия интеграции может реализовать создание Заказа клиента в своей конкретной конфигурации, потому что именно для этого и создана.
Мы разрабатываем внешнюю обработку, поэтому стратегии мы тоже можем реализовать на внешних обработках. Эти стратегии можно хранить в макетах двоичных данных нашей основной обработки.
Итак, познакомимся с нашей внешней обработкой СозданиеЗаказов.epf
В ней есть две формы: Форма (обычная) и ФормаУправляемая, назначенные соответственно основной и дополнительной формами.
Обработка содержит реквизиты Отладка и ПараметрыКонтекста - служебные для нашего контекста. Реквизиты Контрагенты, ДатаДокумента и СсылкаНаСозданныйЗаказ, а также табличная часть Товары - прикладные. Все они (кроме Отладки) служат для подготовки данных контекста, чтобы передать их в нужную стратегию.

Самое интересное для нас то, что в макетах ИнтеграцияКаркаснойКонфигурации, ИнтеграцияДемоБСП и ИнтеграцияЗаказыКлиентовОФ хранятся внешние обработки для интеграции с конфигурациями.
В табличном макете МанифестОбъектов хранится описание для всех макетов обработки. Он очень важен. С его помощью обработка определяет какую стратегию использовать и из какого макета её взять.
Логика работы форм простая.
Кнопка Новый заказ очищает Контрагента, Ссылку на созданный заказ и табличную чать Товары. После заполнения пользователем всех данных кнопкой Записать заказ на основе введённой информации создаётся документ, и ссылка на него отображается в соответствующем реквизите. При этом снова становятся не доступными кнопка Записать заказ и поля для ввода данных.
При установке флага Отладка появляется возможность выбрать, куда сохранить обработки с нашими стратегиями для их отладки. Тут нужно обязательно упомянуть, что для отладки обработок интеграции они должны находиться в одном каталоге с основной обработкой. Этот каталог должен быть доступен с сервера 1С при работе в клиент-серверном варианте в тонком клиенте.
Создание заказа из обработки
Посмотрим как происходит обращение к нашим стратегиям.
При открытии обработки в событиях ПриСозданииНаСервере() в управляемых или ПередОткрытием() в обычных формах выполняется подготовка контекста обработки: восстанавливаются сохраненные настройки (значение флага Отладка) и инициализируются параметры контекста. Помните про реквизит ПараметрыКонтекста? Как раз в нем мы запоминаем АдресМодуляИнтеграции, подключенного как внешняя обработка из макета или сохраненного в одном каталоге с главной обработкой.
Первое обращение к модулю интеграции (нашей стратегии)
Тут же вызывается первый метод нашей стратегии для получения типов данных. Наша основная обработка не знает в каком справочнике конфигурации хранятся Контрагенты и Номенклатура. Как и не имеет ни малейшего понятия о виде документа. Поэтому реквизит обработки Контрагент и реквизит ТЧ Номенклатура имеют тип СправочникСсылка, а реквизит обработки СсылкаНаСозданныйЗаказ - ДокументСсылка.
Точные типы данных нам и сообщает наша Стратегия. При этом она имеет доступ к Контексту через переменную своего модуля ГлавныйКонтекст, в котором хранится объект нашей основной обработки.
А значит, может напрямую изменять реквизит обработки ПараметрыКонтекста(тип Структура), в частности, заполнив его свойство ТипыДанныхДляРеквизитов.
Определение типов данных из модуля интеграции
После инициализации параметров контекста в событии формы ПриОткрытии() устанавливаются соответствующие ограничения типов для элементов формы.
Применение типов полученных из интеграции для реквизитов формы
Второе обращение к стратегии
После нажатия кнопки Создать заказ на сервере вызывается метод обработки СоздатьЗаказВИнтеграции(), в котором происходит обращение к методу нашей стратегии СоздатьЗаказ(). После успешного создания документа стратегия (модуль интеграции) передаёт ссылку через вызов процедуры ЗавершитьСозданиеЗаказа() нашего контекста (главной обработки).
Цепочка вызовов для создания заказа в базе данных
Как это добро отлаживать и дорабатывать?
Главное, что нужно - это заранее включить Отладку в обработке и выгрузить обработки из макетов.
В Конфигураторе ничего особенного настраивать не нужно.
Открываем основную обработку и обработку, сохраненную из Макета - наш модуль интеграции. Расставляем точки останова и выполняем отладку. Кстати, благодаря тому, что открыт конфигуратор с базой, под которую мы разрабатываем интеграцию, нам доступен контекст этой конфигурации.

Из модуля формы попадаем в модуль обработки. В отладчике видно, что в МодульИнтеграции содержится наша стратегия из внешней обработки.

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

Потом мы возвращаемся в модуль основной обработки и, в конечном счете, снова в форму.

Если в Конфигураторе были внесены изменения в обработки и требуется продолжить разработку в EDT, то нужно импортировать изменения в соответствующие проекты.


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

Затем добавляем проекты внешних обработок. Для всех устанавливаем флаг Включить автоматическую генерацию выгрузок (*.epf или *.erf) и указываем путь к общему каталогу. У меня эти обработки сохраняются в каталоге локального git-репозитория, добавленном в проекте обработки СозданиеЗаказов как папка epf. Модули интеграции добавлены в отдельные проекты, чтобы можно было для каждого из них указать в качестве базового проект соответствующей конфигурации.

Для автоматической сборки обработки в файл epf и запуска отладки очень важно, чтобы в проекте обработки версия платформы совпадала с версией в проекте конфигурации. Если случайно они получились разными, можно пересоздать проект обработки или изменить его непосредственно в файлах проекта с помощью текстового редактора.
Для проекта основной обработки базовый проект выбирать не нужно, так что проблемы быть не должно. Для сборки будет использоваться платформа, указанная в проекте СозданиеЗаказов.
Однако, для отладки нужно настроить варианты запуска.

Отладка интеграции для обычных форм возможна только в Конфигураторе, потому что у конфигурации ЗаказыКлиентовОбычныеФормы установлен режим совместимости ниже поддерживаемых платформ текущей версии EDT. Но при этом разрабатывать модуль интеграции можно и в EDT. Доступен как контекст конфигурации через базовый проект, так и все возможности среды, включая 1С:Напарник.
Проекты под более свежие платформы можно отлаживать в EDT. Открываем модули и расставляем точки останова, где нам нужно. Открываем нужную конфигурацию запуска отладки. Например, в методе интеграции ЗаполнитьТипыДанныхДляРеквизитов(). После остановки выполнения кода в отладчике видно содержание переменной модуля интеграции ГлавныйКонтекст.

Как добавить новый модуль интеграции для ещё одной конфигурации?
Нужно всего лишь добавить копированием новый макет двоичных данных. Затем добавить строку в табличный макет МанифестОбъектов, указав ИмяМакета (на скриншоте ИнтеграцияНовойКонффигурации), которое будет использоваться при выгрузке обработки и для поиска макета, а также ТипМакета="Обработка". Наконец, обязательно заполнить ИмяКонфигурацииИнтеграции = Имя конфигурации. По нему будет определяться из какого макета брать обработку.

Затем можно сохранить обработку в файл с соответствующим именем рядом с основной обработкой или скопировать ранее выгруженный файл любого модуля интеграции, переименовав его.

Какие выгоды мы получаем от такой реализации?
- Теперь мы не нарушаем стандарт #std669.
- Легко дорабатывать и отлаживать интеграции.
- Просто добавить интеграцию с новой конфигурацией.
- Можно вести параллельную разработку разных интеграций (с использованием различных систем контроля версий).
- При необходимости модули интеграции (Стратегии) можно использовать в другой обработке (Контексте). Например, обработка для загрузки заказов из внешней системы, которая работает в регламентном задании.
- Для каждого модуля интеграции можно написать отдельные юнит-тесты.
- Если основная обработка должна поставляться без исходных кодов или с обфускацией, то модули интеграции можно оставить открытыми для доработки и даже добавлять новые под конкретную конфигурацию.
- Проще перейти на разработку в EDT, но и в Конфигураторе разрабатывать удобней.
- Использование EDT открывает дополнительные возможности в виде проверки на лету, строгой типизации и доступа к 1С:Напарник.
Известные проблемы и их решение
- В модуле обработки нельзя использовать конструкторы некоторых объектов в безопасном режиме (5.5.4.3. Безопасный режим работы Руководства разработчика). Например, нельзя использовать Новый Файл(). Решить эту проблему можно, переписав код без использования этого объекта либо отключив безопасный режим. Отключить его можно в настройках пользователя или для всей платформы. В конфигурациях на базе БСП есть ещё возможность отключить безопасный режим или настроить нужные разрешения при добавлении обработки в Дополнительные отчеты и обработки. Подробнее в документации.
- Обработки в макеты сейчас я собираю вручную, но этот процесс можно автоматизировать. Например, в проекте EDT нужно просто заменить файл "\СозданиеЗаказов\Templates\ИнтеграцияДемоБСП\Template.bin" на файл соответствующей обработки "\ИнтеграцияДемоБСП.epf" и все остальные по аналогии. Нужно только переименовать их в Template.bin, а затем пересобрать основную обработку. Если делать это из EDT, то сначала нужно обновить проект обработки СозданиеЗаказов.
- Приходится учитывать, что основная обработка может выполняться под различными платформами и с разными режимами совместимости. Поэтому нужно использовать платформенные методы, доступные в различном окружении и разрабатывать свои методы вместо типовых (из БСП или конфигураций). Но, благодаря переносу ответственности за взаимодействие с базой в модули интеграции, это становится делать проще.
- Не реализован вызов клиентских методов управляемых форм. В данном примере это не совсем проблема, потому что всё выполняется на сервере. Но я могу предложить, как решить и её. Можно добавить в модули интеграции управляемые формы, разместить в них экспортные клиентские методы (нельзя, но если надо, то можно), создавать форму нужной обработки и дёргать её методы на клиенте. Тут нужно избежать появления новых окон, но с справиться не сложно, я думаю.
Проект и все обработки, а также выгрузку базы крутейшейтестовой конфигурации ЗаказыКлиентовОбычныеФормы можно скачать на GitHub.
Скриншот ветки master репозитория проекта на GitHub
Если данная статья будет вам полезна и захочется меня поддержать, можете сделать это скачиванием файлов.