Эмулятор COM-соединения или "объект" ЭтаБаза

Предыстория: был инструмент для работы с другой базой по COM-соединению. Потребовалось использовать этот инструмент для текущей базы (без COM-соединения), но без дублирования кода. Но, к сожалению, 1С не предоставляет объекта ЭтаБаза (ТекущаяБаза и т.п.), который бы позволял обратиться к глобальным перечислениям (менеджерам объектов Справочники, Документы и др.) через точку и создавать новые объекты.
Для этого на скорую руку был создан Эмулятор COM-соединения, который решает 2 вышеуказанные проблемы. Иначе говоря, предоставляет возможность сослаться на текущую базу данных аналогично COM-объекту (с некоторыми ограничениями).

Использование

Далее привожу в сравнении идентичные синтаксически конструкции для COMСоединение ЭмуляторCOMСоединения.

Но прежде — «установка соединения»:

    // COMСоединение
v8 = Новый COMObject("V83.COMConnector");
ДругаяБаза = v8.Connect(СтрокаСоединения);
    // ЭмуляторCOMСоединения

ЭтаБаза = ВнешниеОбработки.Создать(Путь_к_обработкеЭмуляторCOMСоединения.epf);

Либо объект обработки создается иным способом (из справочника внешних обработок, включением обработки в конфигурацию).

Работа с менеджерами объектов:

    // COMСоединение
Ссылка =
ДругаяБаза.Справочники.Номенклатура.НайтиПоНаименованию(Товар);

ВнОбработка =
ДругаяБаза.ВнешниеОбработки.Создать(Путь_к_некоторой_обработке);
    // ЭмуляторCOMСоединения
Ссылка =
ЭтаБаза.Справочники.Номенклатура.НайтиПоНаименованию(Товар);

ВнОбработка =
ЭтаБаза.ВнешниеОбработки.Создать(Путь_к_некоторой_обработке);

 

Создание новых объектов встроенных типов (Запрос и т.п.):

 

    // COMСоединение

Запрос = ДругаяБаза.NewObject("Запрос");
Запрос.Текст = "
|Выбрать
|    Курс КАК Курс
|Из
|    РегистрСведений.КурсыВалют.СрезПоследних(&НаДату,
|        Валюта = &Валюта)
|";

Запрос.УстановитьПараметр("НаДату", НаДату);
Запрос.УстановитьПараметр("Валюта",
ДругаяБаза.Справочники.Валюты.НайтиПоНаименованию(Валюта));

Выборка = Запрос.Выполнить().Выбрать();
    // ЭмуляторCOMСоединения

Запрос = ЭтаБаза.NewObject("Запрос");
Запрос.Текст = "
|Выбрать
|    Курс КАК Курс
|Из
|    РегистрСведений.КурсыВалют.СрезПоследних(&НаДату,
|        Валюта = &Валюта)
|";

Запрос.УстановитьПараметр("НаДату", НаДату);
Запрос.УстановитьПараметр("Валюта",
ЭтаБаза.Справочники.Валюты.НайтиПоНаименованию(Валюта));

Выборка = Запрос.Выполнить().Выбрать();

 

Как можно увидеть, конструкции полностью идентичны.

 

Ограничения

  1. Невозможно вызывать методы глобального контекста/глобальных модулей, такие как XMLСтрока
  2. Можно вызывать методы неглобальных общих модулей (в 8.3), только если изменить слегка саму обработку (см. секреты)

Секреты

  1. Для получения экспортных переменных обработки, имеющих те же названия, что и встроенные переменные глобального контекста, использованы реквизиты обработки с типом «Произвольный»
  2. «Переопределение» функции NewObject COM-объекта возможно лишь потому, что нет одноименного метода глобального контекста. Он называется Новый/New
  3. Обращение к методам неглобальных общих модулей возможно, если создать одноименный реквизит обработки и инициализировать его в модуле обарботки.

Заключение

Т.к. XMLСтрока — это, пожалуй, одна из немногих функций глобального контекста, которую приходится использовать при COM-соединении, то пришлось вынести ее в общий модуль с другим именем (XMLСтрока_). Код имеющегося инструмена, к сожалению, пришлось слегка изменить.

 

P.s. данный вопрос уже поднимался здесь: http://www.forum.mista.ru/topic.php?id=590517

Данный «эмулятор» является частичным решением

7 Comments

  1. script

    Ничего не понял. А накой это нужно?

    Reply
  2. Ibrogim

    Круто. Однако непонятно, почему бы просто поиском и заменой не убрать «ДругаяБаза.» и подобные вещи?

    Вопрос снимается, увидел

    без дублирования кода.
    Reply
  3. Ibrogim

    (1) script,

    А накой это нужно?

    Например есть модуль для получения данных через com и не через com . Чтобы не поддерживать одновременно два модуля, можно воспользоваться этим инструментом

    Reply
  4. LsrGroup

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

    Reply
  5. Yashazz

    Так а что мешало запустить сеанс текущей базы из себя самой по com-коннектору?

    Reply
  6. mikhailv

    (4) LsrGroup, указанный Вами подход имеет право на жизнь. Но Вы ведете речь о коде, который еще не написан, а здесь речь об уже существующем коде, написанном с com-коннектором и обращениями вида ДругаяБаза.NewObject, ДругаяБаза.Справочники и т.д. Хотелось сохранить один вариант кода без существенной переработки, реализовав работу как с com, так и без.

    (5) Yashazz, 1) без com-коннектора быстрее. 2) com не доступен в linux

    Reply
  7. tormozit

    Тоже сталкивался с такой проблемой много раз. Уже давно попросил 1С сделать такое свойство глобального контекста https://partners.v8.1c.ru/forum/t/574489/m/574489, но не был услышан.

    Как правильно заметил LsrGroup, одним из вариантов решения проблемы будет написание кода во внеших обработках, но это накладывает ряд ограничений, например на сложность кода и невозможность его использования в тонком клиенте. Мы довольно широко применяем такой подход в нашем продукте 2iS:Интеграция.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *