Имя: Пароль:
1C
1С v8
v8.2: хранение com-объекта
,
0 jenyanorilsk
 
21.11.12
05:42
Добрый день.
Есть необходимость из одной конфигурации подключаться к другой с помощью com-объекта и тянуть нужные данные по запросу пользователя.

Если объявляю переменную на клиенте:
+ переменная сохраняет значение, пока открыта обработка, что нам и требуется
- переменная недоступна в процедурах контекста сервера(&НаСервере), которые нужны нам для создания копий объектов, подтягивания  значений реквизитов в объекты своей конфигурации

Если объявляю на сервере:
+ переменная доступна в контексте сервера
- переменная не сохраняет значение при смене контекста (клиент-сервер-клиент)

Упрощённый пример: пользователь вбивает инвентарный номер, обработка подключается в другую конфигурацию, ищет основные средства с таким или похожим инвентарником, выводит пользователю. И так несколько раз - разные инвентарные номера.

Идея в том, что нужно подключиться один раз, при первом поиске, при последующих использовать это подключение, при закрытии формы подключение разрывать.

Единственный способ реализовать задуманое, который я вижу - объявление переменной на клиенте и передача её в процедуры контекста сервера.

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

//---------- пример кода, который будет дублироваться

Функция Подключиться(СтрокаПодключения) Экспорт
   Подключение = Неопределено;
   Если СтрДлина(СтрокаПодключения) = 0 Тогда
       КомОбъект1С82 = Новый COMОбъект("V82.COMConnector");
       Подключение = КомОбъект1С82.Connect(СтрокаПодключения);
   КонецЕсли;
   Возврат Подключение;
КонецФункции

//------------------ конец примера

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

т.е., если в 8.1 такой код в общем модуле был легитимным, то в 8.2 - уже нет

Функция УИД(Подключение, ОбъектИлиСсылка) Экспорт
   Возврат Подключение.XMLСтрока(ОбъектИлиСсылка.Ссылка.УникальныйИдентификатор());
КонецФункции

собственно вопросы:

1. где хранить com-объект?
2. куда вынести процедуры подключения, взятия УИДа и прочие?
3. может быть я вообще всё неправильно понимаю и делаю и описаную ситуацию нужно решать другим образом?
1 1C-band
 
21.11.12
05:46
1. COM-объект нигде не хранится, поскольку является экземпляром класса. Объекты некоторых классов могут сериализоваться (быть записанными и прочитанными), если такое предусмотрено методами класса.
2 Jolly Roger
 
21.11.12
05:55
(0) юзай вебсервис...
3 jenyanorilsk
 
21.11.12
07:12
(1) не может такого быть
во-первых, он хранится в памяти, во вторых, если я делаю
во-вторых, переменная хранит указатель на com-объект
например:
КомОбъект1С82 = Новый COMОбъект("V82.COMConnector");

(2) конфигурация, к которой подключаемся - переведённая с 8.1 на 8.2, не управляемое приложение, соответственно веб-сервисов там нет

ну и, всё-таки, хотелось увидеть ответ на вопрос - как решить задачу в указанных рамках, а не ответы в духе "читай всё напрямую из sql-сервера" или "используй веб-сервис"
4 WebberNSK
 
21.11.12
07:24
(3) почитайте что такое веб-сервис
5 jenyanorilsk
 
21.11.12
07:34
(4) повторюсь: требуется решить задачу в установленых рамках, т.е. без использования веб-сервисов, только com-объект.

требуется решить задачу не изменяя сторонние конфигурации, потому что, помимо базы на 8.2, есть ещё чужая база на 7.7, из которой тоже нужно брать данные.
Мне и там веб-сервис создавать?))
6 ДенисЧ
 
21.11.12
07:48
временное хранилище тебе поможет.
Только одна особенность - оно имеет обыкновение протухать со временем (гдето полчаса). Поэтому перед использованием - проверяй на живость и пересоздавай при умертвии.
7 MSII
 
21.11.12
07:55
Создавай ком каждый раз, но процедуру создания вынеси в модуль с флагом "Повторное использование возвращаемых значений".
8 Defender aka LINN
 
21.11.12
08:10
(0) "если в 8.1 такой код в общем модуле был легитимным, то в 8.2 - уже нет" - скуяли?
9 milan
 
21.11.12
08:13
(7) +1
ТС путается в определениях и показаниях
10 Defender aka LINN
 
21.11.12
08:21
(7) И что будешь делать, когда COM-объект отвалится и потребуется его пересоздать?
11 MSII
 
21.11.12
08:25
(10) Я думаю, ТС догадается проверять живость ком-объекта перед использованием. Главное, что в (7) решается задача, описанная в (0).
12 jenyanorilsk
 
21.11.12
08:27
(8) параметрами методов общего модуля не могут быть мутабельные значения. com-объект мутабелен. Та же история для передачи между клиентом-сервером через параметры.

(7)(10) - согласен, не тот случай
13 Defender aka LINN
 
21.11.12
08:30
(12) "параметрами методов общего модуля не могут быть мутабельные значения" - скуяли?
14 jenyanorilsk
 
21.11.12
08:30
(11) вызов получения ком-объекта в разных обработках опять будет обрастать повторяющимся кодом, только теперь уже проверок?)
15 milan
 
21.11.12
08:32
(12)  ты ком с сервера хочешь обрабатывать на клиенте ? кто то  в этой ветке не понимает того, о чем говорит
16 jenyanorilsk
 
21.11.12
08:34
(12) пардон, напутал, мой косяк. общий модуль "на сервере", а вызов делаю с клиента, получаю ошибку передачи мутабельного значения, но тут дело в смене контекстов, а не в параметре. спасибо)
17 MSII
 
21.11.12
08:41
(14) Да, после строки, в которой ты будешь получать ком, нужно будет добавить еще одну строку, в которой будет вызываться функция проверки живости соединения. Это проблема?
18 milan
 
21.11.12
08:44
(17) сопсно можно все это обернуть в процедуру общего модуля без флажка и получать 1-й строкой
19 vde69
 
21.11.12
08:44
(12) COM объект - по факту - это DLL зарегистрировавшая свой интерфейс на конкретном компьютере, по этому использовать его вне компа на котором он зарегестрирован - НЕЛЬЗЯ.

есть DCOM, упрощенно это DLL которая регистрирует не только интерфейс внутри но и в спец оболочке которая позволяет ее использовать с других машин, но сама DLL все равно выполняется только на родном компе!

есть Navie - это dll которая не публикует ничего пока ее не вызовут, но она выполняется только на родной машине

по существу один обьект не может существовать и на клиенте и на сервере, тебе нужно 2 копии объекта, одна для клиента другая для сервера.

ИХМО ты идешь неправильной дорогой
20 MSII
 
21.11.12
08:47
(18) Да, это так.
21 Rovan
 
гуру
21.11.12
08:50
(0) прочитал... не понял зачем нужен этот КОМ на сервере ?
22 jenyanorilsk
 
21.11.12
08:56
(19) Спасибо, всё понял, буду менять подход
23 Serginio1
 
21.11.12
10:34
24 Ork
 
21.11.12
10:40
Присоединюсь к (21).

"Идея в том, что нужно подключиться один раз, при первом поиске, при последующих использовать это подключение, при закрытии формы подключение разрывать.

Единственный способ реализовать задуманое, который я вижу - объявление переменной на клиенте и передача её в процедуры контекста сервера."

Зачем на сервер передавать переменную? Весь разбор "оттуда" производить на клиенте. Серверу отдавать команды на отработку по уже разобранным данным.
25 jenyanorilsk
 
21.11.12
12:48
(24) всё началось с того, что в какой-то из книг по 8.2 я прочитал, что частая смена контекста - очень плохо и нужно стараться её всеми силами избегать

после (19) до меня дошло, что я занимаюсь ерундой )

теперь буду брать нужные данные через com НаКлиенте, заносить их, например, в структуру и передавать процедуре НаСервере для последующей обработки

надеюсь я всё правильно понял)
26 jenyanorilsk
 
21.11.12
12:51
(25) в структуру, само собой, не буду заносить никаких com-объектов или чего-то стороннего

только примитивные типы и ссылки на экземпляры объектов родной конфигурации
27 vde69
 
21.11.12
13:55
(25) вот пример подобной реализации http://code.google.com/p/restoration-base-1c8/downloads/list

есть и другой подход

файл передаем на сервер, и там на сервере запускаем COM которая умеет работать с этим файлом. Примеры есть в типовых (работа с торговым оборудованием).

минус первого подхода
COM должен быть зарегистрирован на всех клиентских тачках

минус второго подхода
иногда нельзя источник передать на сервер (например нужна только 1 строка из терабайтного файла)
30 renowka
 
10.12.12
09:22
Дабы не плодить тем прошу помощи.

В общем модуле (Сервер, Вызов сервера, Повторное использование - На время сеанса), Описываю Функцию по установке соединения с базой

Функция УстановитьСоединение() Экспорт
   
   V8 = Новый COMОбъект("V82.Application");
   
   СтрПодключения = "параметры подключения"    
   Соединение = Неопределено;
   
   Попытка                
       Соединение = V8.Connect(СтрПодключения);
   Исключение    
       Сообщить("Ошибка открытия информационной базы");
       Возврат ложь;
   КонецПопытки;
       
   V8.visible = false;    

   ПараметрыСеанса.АдресCOMОбъекта= ПоместитьВоВременноеХранилище(V8, Новый УникальныйИдентификатор());    
   
   Возврат ПараметрыСеанса.АдресCOMОбъекта;
   
КонецФункции

В модуле Справочника НаКлиенте
Вызываю это функцию и пытаюсь получить из временного хранилища ComОбъект

ВнешнееПодключение.УстановитьСоединение();
Соединение = ПолучитьИзВременногоХранилища(ПараметрыСеанса.АдресCOMОбъекта);

ПараметрыСеанса.АдресCOMОбъектаСодержит ссылку на временно хранилище, но при вызове метода  ПолучитьИзВременногоХранилища(ПараметрыСеанса.АдресCOMОбъекта) возвращается неопределено, как на клиенте получить этот COM?
31 vde69
 
10.12.12
09:31
(30) ты писатель? можно было-бы и прочитать сначало...

ком можно использовать только на том компе где создан обьект. передать НЕЛЬЗЯ!!! ни какими ухищрениями!
32 Serginio1
 
10.12.12
10:46
(30) Вот если ты вызовешь на сервере то должно быть все в порядке
Книга знаний: Хранение COM Объектов на Сервере ТонкогоКлиента
Это для того, что бы пережить время между серверными  вызовами. Ты можешь дергать этот КОМ только через сервер
33 renowka
 
10.12.12
10:58
На сервере все работает, в том-то и дело что нуно было на клиента все передать, например форму справочника открыть
34 ДенисЧ
 
10.12.12
11:01
(33) Не нуно тебе ком-объект на клиента передавать. Не нуно.
А представь, что оный клиент - есть веб-клиент, работающий на телефоне. Кто там будет оный ком отрабатывать?
35 Serginio1
 
10.12.12
11:03
(33) А зачем? Получи данные на сервере и передай на клиента.
36 vde69
 
10.12.12
11:05
(32) ты не внимателен...

НЕЛЬЗЯ КОМ дернуть на сервере если он создан на клиенте!!! НУ НЕЛЬЗЯ!!!!
37 Serginio1
 
10.12.12
11:22
(36) Можно через серверную процедуру еще раз смотри Книга знаний: Хранение COM Объектов на Сервере ТонкогоКлиента
Это ты невнимателен он на клиенте вызывает
ВнешнееПодключение.УстановитьСоединение();
Соединение = ПолучитьИзВременногоХранилища(ПараметрыСеанса.АдресCOMОбъекта);


Если вы он на сервере вызвал
Соединение = ПолучитьИзВременногоХранилища(ПараметрыСеанса.АдресCOMОбъекта);
то было бы все нормально.
38 vde69
 
10.12.12
16:47
(37) в примере ВСЕ выполняется на сервере!!! на клиенте ты не получишь доступ к кому созданому на сервере...
39 Serginio1
 
10.12.12
16:59
(38) Я и пишу, что на клиенте доступа нет, нужно вызвать на сервере и данные передавать на клиента. Вызвать серверную процедуру дергающую СОМ ведь нет никаких проблем. Он же хочет получить доступ на клиенте. См 30.
Закон Брукера: Даже маленькая практика стоит большой теории.