Имя: Пароль:
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.
Здесь можно обсудить любую тему при этом оставаясь на форуме для 1Сников, который нужен для работы. Ymryn