Еще раз о COM-соединениях

1. novatrade 02.03.20 22:51 Сейчас в теме
Честно говоря, не думал писать какие-либо заметки. Однако некоторые публикации подтолкнули меня к написанию этой заметки.
Не буду описывать всю последовательность своих шагов, как я к этому пришел. Сформулирую сразу вкратце свое решение:
1. На стороне Базы, которая выступает источником данных, располагаю модуль Обмен. В нем прописываю следующую функцию:

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


В конфигурации, которая производит вызовы, создаю такой алгоритм вызова:
	Подключение = Новый COMОбъект("V83.COMConnector.1");
	Сервер		 = Справочники.ПараметрыПодключения.База.СерверДляПодключения;
	База 		 = Справочники.ПараметрыПодключения.База.ИмяБазы;
	Пользователь = Справочники.ПараметрыПодключения.База.ИмяПользователь;
	Пароль		 = Справочники.ПараметрыПодключения.База.ПарольПользователя;
	База 	 = Подключение.Connect("Srvr='"+Сервер+"'; Ref='"+База+"'; Usr='"+Пользователь+"'; Pwd='"+Пароль+"'");
	ТекстЗапроса =»(Ваш Запрос)»;
	СтруктураПередачи = новый Структура();
	….(создаю структуру, содержащую имена параметров и их значения для запроса)
	Результирующая таблица = ЗначениеИзСтрокиВнутр(База.Обмен. ОбработкаЗапроса (ЗначениеВСтрокуВнутр(ТекстЗапроса), ЗначениеВСтрокуВнутр(СтруктураПередачи)));
	Подключение = Неопределено;	
Показать


Такой подход позволил мне получить очень быстро результаты запроса и обрабатывать их в вызывающей базе, не используя COM-объекты.
Ответы
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
2. duhin 03.03.20 06:05 Сейчас в теме
Не понял в чем профит
1.
>Подключение = Новый COMОбъект("V83.COMConnector.1");
>не используя COM-объекты.
тут противоречие какое то
2.Запрос можно выполнить на вызывающей стороне а затем сериализовать-десериализовать чтоб получить родную таблицу значений. Зачем что-то писать на принимающей стороне-неясно
3. Также непонятно при чем здесь скорость. Вариант в моем втором пункте будет выполнятся ровно столько же, только на стороне- сервере ничего писать не надо, код в одной функции, проще читается и обслуживается.
4. Nadushka74 5 03.03.20 09:06 Сейчас в теме
(2)
>Подключение = Новый COMОбъект("V83.COMConnector.1");
>не используя COM-объекты.
тут противоречие какое то


подключение есть, но вы обрабатываете не ?Com.Объект а родную структуру для вашей базы.

Иногда очень удобный механизм.
5. duhin 03.03.20 13:08 Сейчас в теме
(4)
    ВнешняяБаза = ...//Как у вас
    Запрос = ВнешняяБаза.NewObject("Запрос"); 
    Запрос.Текст= "...";
    тзнКом= Запрос.Выполнить().Выгрузить();
    тзн = ЗначениеИзСтроки(ВнешняяБаза.ЗначениеВСтроку(тзнКом));

И у вас родная структура вашей базы, и все хорошо)) И в базу- источник данных ничего толкать не нужно.
Другое дело с HTTP- WEB сервисами, там действительно достигается огромная экономия за счет того, что не надо стартовать клиента, поскольку создание ком объекта- по сути старт клиента 1с. Чтобы уменьшить расходы на создание КОМ соединения возможно хорошая идея кешировать комобъект- но тогда будет висеть лишнее соединение к серверу. HTTP сервисы(WEB-сервисы для нашей легаси 8.2) реально дают выигрыш в десятки раз, на своей шкуре это уже почувствовали, интенсивно на них переходим.
7. novatrade 03.03.20 20:56 Сейчас в теме
(2)
1. Если вы работали с COM соединением, то должны знать, что получите ответ, содержащий COM объекты, которые надо обрабатывать.
2. Интересно, как? То, что Вы пишете запрос на вызывающей стороне - совсем не значит, что он там выполняется. Выполняется
Насчет сериализации - а Вы пробовали тот алгоритм, который предлагаете?
3. Просто интересно, сколько у вас на объемах в несколько сотен тысяч записей займет времени передача данных и приведение их к таблице значений?
8. duhin 04.03.20 04:35 Сейчас в теме
(7) Передача данных откуда куда? В вашем и моем варианте происходит одно и тоже. Через ком объект создается клиентский сеанс к чужой базе. В нем выполняется запрос и получается таблица значений, в том сеансе. В том же сеансе тзн преобразуется в строку. и передается нам. Откуда, по вашему, появится разнице?
Впрочем, когда найду время, сделаю замер. Но сейчас мне непонятно, откуда появится разнице. Расходы на мой взгляд одинаковые, просто весь код в одном месте и не надо трогать базу источник, что важно, если она на поддержке.
3. xSavantx 23 03.03.20 09:01 Сейчас в теме
Замеры делали? Можете выложить?
6. novatrade 03.03.20 20:41 Сейчас в теме
(3)нет, замеры не делал. Помню, что запрос и перекачка порядка 850 тыс. строк таблицы значений заняла несколько минут. Сейчас особо и проверить не на чем, т.к. ни задач ни баз такого объема под рукой нет. Да и времени как всегда - дефицит.
9. duhin 04.03.20 05:55 Сейчас в теме
И да, по поводу того, работал ли я с ком соединением. Примитивные типы- строки, даты, числа- не надо сериализовать, они и так прекрасно передаются. Это я вот про это
Запрос.Текст = ЗначениеИзСтрокиВнутр(ТекстЗапроса);
10. duhin 04.03.20 06:22 Сейчас в теме
Пример сделал, работает одинаково. На 30 тыщах строчек проверил, возвращает в обоих ваиантах за секунду, плюс минус два процента. 66% времени тратится на метод connect- запуск приложения, как я и писал
Процедура КнопкаВыполнитьНажатие(Кнопка)
	старт=ТекущаяУниверсальнаяДатаВМиллисекундах();
	Подключение = Новый COMОбъект("V83.COMConnector.1");
    База      = Подключение.Connect("File=""C:\001\ТестКОМ_Источник"";");
    ТекстЗапроса = "Выбрать * Из РегистрСведений.РегистрСведений1 как т1";
    РезультирующаяТаблица = ЗначениеИзСтрокиВнутр(База.КомСервер.ОбработкаЗапроса(ТекстЗапроса));
    Подключение = Неопределено;
	Сообщить("Потрачено мс" + (ТекущаяУниверсальнаяДатаВМиллисекундах()-старт));
	ОткрытьЗначение(РезультирующаяТаблица);
КонецПроцедуры

Процедура ОсновныеДействияФормыкнопка2(Кнопка)
	старт=ТекущаяУниверсальнаяДатаВМиллисекундах();
	Подключение = Новый COMОбъект("V83.COMConnector.1");
    База      = Подключение.Connect("File=""C:\001\ТестКОМ_Источник"";");
    ТекстЗапроса = "Выбрать * Из РегистрСведений.РегистрСведений1 как т1";
	Запрос = База.NewObject("Запрос"); 
	Запрос.Текст = ТекстЗапроса;
	РезультирующаяТаблица = ЗначениеИзСтрокиВнутр(База.ЗначениеВСтрокуВнутр(Запрос.Выполнить().Выгрузить()));
    Подключение = Неопределено;
	Сообщить("Потрачено мс" + (ТекущаяУниверсальнаяДатаВМиллисекундах()-старт));
	ОткрытьЗначение(РезультирующаяТаблица);
КонецПроцедуры
Показать
Оставьте свое сообщение
Вакансии
Аналитик 1C
Москва
зарплата от 120 000 руб. до 250 000 руб.
Полный день

Тестировщик 1С
Москва
зарплата от 125 000 руб.
Полный день

Программист 1С
Санкт-Петербург
зарплата от 90 000 руб.
Полный день

Программист/тестировщик
Москва
зарплата от 130 000 руб. до 150 000 руб.
Полный день

Ведущий разработчик 1С / Team lead отдела разработки 1С
Москва
зарплата от 300 000 руб. до 300 000 руб.
Полный день