Имя: Пароль:
1C
1С v8
УФ. Хранение COM-Соединения
0 fisher
 
28.04.12
11:02
Я в УФ не настоящий сварщик.
Надо чтобы отчет на УФ работал в том числе с COM-соединением.
В обычных формах я бы просто инициализировал переменную модуля в теле модуля отчета.
Но в УФ, насколько я понял/вычитал, контекст модуля объекта не сохраняется и модуль создается при каждом серверном вызове (и каждый раз исполняется тело модуля).
Как в случае УФ красиво "удерживать" COM-соединение до закрытия формы отчета?
1 ДенисЧ
 
28.04.12
11:03
Временное хранилище. Туда помещать. Перед использованием - проверять живость, ибо имеет свойство через полчаса дохнуть. В КЗ есть статья Нуф-Нуфа (кажется) на эту тему.
2 fisher
 
28.04.12
11:09
3 fisher
 
28.04.12
11:16
Из статьи: "Первым и самым простым выходом может стать хранение переменных в реквизитах формы, на сервере". Это мне и нужно.
Имеется в виду хранение в реквизите формы адреса объекта во временном хранилище?
Или можно каким-то образом в реквизите формы сохранять серверный объект? Просто формулировка неоднозначная. Просветите плиз.
4 fisher
 
28.04.12
11:24
А реквизиты отчета (не формы) могут содержать серверные типы, и если да - то сохраняются ли они между серверными вызовами?
5 H A D G E H O G s
 
28.04.12
11:26
(3)
&НаСервере
Перем ComОбъект;

//Основная часть кода управляемой формы.
6 H A D G E H O G s
 
28.04.12
11:27
Исправил статью
7 fisher
 
28.04.12
11:27
Спасибо!!
8 fisher
 
28.04.12
11:32
Черт. Наверное так не взлетит.
Мне же нужно из модуля объекта до COM-объекта достучаться.
Из ПриКомпоновкеРезультата() в отчете.
Какой тогда самый красивый вариант остается?
9 H A D G E H O G s
 
28.04.12
11:33
(8) И в чем проблема то?
10 ДенисЧ
 
28.04.12
11:34
ну, я сделал так...
Адреса временных хранилищ - в реквизитах отчета/обработки.
Все вызовы для работы с - серверные. Там через функцию, которая проверяет живость объекта, и при необходимости пересоздаёт переподключает его, получаю сам объект и дальше уже работаю с ним...
11 fisher
 
28.04.12
11:35
(9) В моих пробелах в знаниях. Разве из модуля объекта можно обращаться к переменным формы, пусть даже и серверным? Это фигня какая-то будет. Я ж могу с объектом и без формы работать.
12 H A D G E H O G s
 
28.04.12
11:36
(11) Храни адрес временного хранилища (строка) - в параметре сеанса
13 H A D G E H O G s
 
28.04.12
11:36
И будет щасте.
14 ДенисЧ
 
28.04.12
11:38
(11) Храни в реквизите объекта, а не формы.
Или пользуй РеквизитФормыВЗначение()
15 fisher
 
28.04.12
11:40
(14) Во! Вокруг этого и мыслю. А я могу в реквизит отчета прямо ссылку на соединение запхать? Оно выживет на сервере между серверными вызовами?
16 fisher
 
28.04.12
11:51
Гы! Когда тупо попробовал засунуть COM-соединение в реквизит отчета на сервере, 1С молча свернула коврик :) Ну, надежда и так была слабая.
Попробую аналогичную фигню с временным хранилищем...
17 ДенисЧ
 
28.04.12
11:53
(15) Ссылку - не сможешь
18 fisher
 
28.04.12
11:56
Сейчас через временное хранилище попробую.
А как лучше всего кэш констант (ссылочных типов) хранить для использования в модуле объекта? Прокатит засунуть их в структуру а её запихать в реквизит отчета?
19 fisher
 
28.04.12
11:57
Или аналогично через временное хранилище придется?
20 H A D G E H O G s
 
28.04.12
12:26
(18) Накуа?
21 H A D G E H O G s
 
28.04.12
12:28
Используй ОМ с повторным использованием возвращаемых значений + подпиской на Запись константов и учетных регистров и
методом ОбновитьПовторноИспользуемыеЗначения()
22 fisher
 
28.04.12
12:36
(21) Не. Мне нужен локальный кэш повторно используемых значений в конкретном отчете. Не глобальный.
23 fisher
 
28.04.12
12:40
Исчо фигня... Если пихать во временное хранилище без привязки к форме (я ж из модуля объекта пихаю), то оно еще довольно долго после закрытия формы живет (видать пока сборщик мусора до него не добирается или что-то в этом духе).
А как красиво привести время жизни временного хранилища ко времени жизни объекта?
24 H A D G E H O G s
 
28.04.12
12:41
Пусть живет. Жалко штоле.
25 ДенисЧ
 
28.04.12
12:44
(24) иногда бывает жалко.
26 fisher
 
28.04.12
12:46
Получается нехорошо... Привязки к времени жизни объекта нет... Проверять, подновлять нужно... На форму, что ли, таки завязаться?
27 fisher
 
28.04.12
12:53
Что-то я туплю... А на клиенте вообще доступны реквизиты отчета? Как к ним обратиться?
28 ДенисЧ
 
28.04.12
12:54
(27) Хто? Объект.Что-то?
29 fisher
 
28.04.12
12:57
(28) Пытаюсь в клиентской процедуре УФ отчета набрать "Объект" - контекстная подсказка не дает вариантов. Просто тупит?
30 fisher
 
28.04.12
13:00
Не, не тупит. На клиенте нету такого свойства ни у УФ, ни у расширения УФ отчета.
31 Ахиллес
 
28.04.12
13:05
Недавно аналогичную задачу решал, решение в Книга знаний: Хранение COM Объектов на Сервере ТонкогоКлиента для поддержки соединения не срабатывает. Возможно потому, что использовал cntr = Новый COMObject("V82.COMConnector");  вместо апликейшен.
Сделал себе такую процедурку и вызываю её раз в 10 мин.
Процедура ОбновлениеСоединения() Экспорт
   connection = ПолучитьСоединение(); // COM соединение
   Обновили = connection.String("Обновили");
КонецПроцедуры
32 fisher
 
28.04.12
13:11
Вопрос по реквизитам отчета оформил отдельно: v8: Доступность реквизитов отчета в УФ?
По сабжу, в принципе, расклады ясны.
Всем спасибо!
33 fisher
 
28.04.12
15:18
Попытался поместить во временное хранилище с привязкой к форме, но не из формы (передав идентификатор открытой формы на сервер) и ввел 1С в тягостное недоумение :)
Придется не выёживаться и делать как все :)
34 fisher
 
28.04.12
15:22
Последний вопрос в этой ветке, крест на пузе!
Как красиво проверить, жив ли еще COM-объект во временном хранилище?
35 fisher
 
28.04.12
15:23
Нашел в статье в КЗ. Невнимательно читал...
36 ahachack
 
28.04.12
15:31
К топику темы:
не знаю в тему ли, но у нас делали так:
общий модуль Кеш с параметром "повторное использование"  - на время сеанса.
в нем функция - ПолучитьКомСоединение которая устанавливает соединение.

Далее везде пишем (в начале процедур и обработчиков):
ComОбъект=Кеш.ПолучитьКомСоединение();

Получаем, что на время всего сеанса "на сервере" всегда будет 1 соединение

Удобно было тем, что когда ком соединение при неактивности разрывалось (в доках по-моему минут 15 неактивности указывается), то автоматически где надо соединение переинициализировалось.
37 ДенисЧ
 
28.04.12
15:35
(34) Попытаться вызвать его метод через попытку...
38 ДенисЧ
 
28.04.12
15:35
(36) А код этого модуля показать можешь?
39 fisher
 
28.04.12
15:37
(38) Так это вроде стандартный прием. Я просто не хочу его весь сеанс держать...
40 ahachack
 
28.04.12
15:38
//Работа с подсистемой Истории объектов
Функция ПолучитьСоединениеСБазойИстории() Экспорт
   
   ПутьКБазеИстория = Универсальные.ЛокальнаяКонстанта("СтрокаСоединенияСБазойИстории");
   Если ПустаяСтрока(ПутьКБазеИстория) или ПутьКБазеИстория = Неопределено Тогда
       Возврат Неопределено;
   КонецЕсли;
   
   Попытка
       V8 = Новый COMObject("V82.ComConnector");
       Объект=V8.Connect(ПутьКБазеИстория);
   Исключение
       Объект=Неопределено;
   КонецПопытки;    
   Возврат Объект;
   
КонецФункции
41 ahachack
 
28.04.12
15:40
(39) тогда мой способ не подойдет :-)
42 ahachack
 
28.04.12
15:44
(39) + хотя по моему разумению страшного не случится если соединение повисит еще минут 15 после закрытия формы, а потом закроется само.
43 fisher
 
28.04.12
15:45
(42) Погодь. По методу (40) оно ж должно до закрытия 1С висеть?
44 ahachack
 
28.04.12
15:48
(42) у меня в случае неактивности (т.е. если долго никто не вызывает Кеш.ПолучитьКомСоединение()) com соединение закрывалось (смотрел список подключений в другой базе - вроде на 15 минуте)
45 ДенисЧ
 
28.04.12
15:49
(40) А Объект - это локальная переменная или где-то объявлена?
46 fisher
 
28.04.12
15:51
(44) Видать 1С стандартно так все COM-соединения отстреливает. По методу (2) такая же фигня. Тогда однозначно делаю через общий модуль, ибо проще и красивше.
(45) Локальная. Хранение между вызовами обеспечивает механизм повторного использования возвращаемых значений.
47 ahachack
 
28.04.12
15:52
(43) забыл упомянуть о минусе способа:  коллега использующий кластеры серверов 1с жаловался, что как-то криво этот кеш работает. (ну может это исправили уже - не знаю)
(45) локальная в функции ПолучитьСоединениеСБазойИстории()
48 fisher
 
28.04.12
15:53
(47) Ээээ... А "как-то криво" - что конкретно имеется в виду? У меня на это дело работа правил РИБ завязана (я там разрешения объектов кэширую). Вроде тьфу-тьфу-тьфу...
49 ДенисЧ
 
28.04.12
15:55
(46) (47) понял, спасибо
50 ahachack
 
28.04.12
15:59
(48) точно не скажу. Вроде при динамической балансировке нагрузки между серверами больно часто производилось переподключение к базе com. Для него это проблема была важной из-за того, что лицензий впритык было куплено.
51 fisher
 
28.04.12
16:04
(50) Вроде нестрашно... Дык если ПЕРЕподключение, то не должны же лишние лицензии расходоваться?
52 fisher
 
28.04.12
16:12
Я тут подумал...
Ведь если в (40) по какой-либо причине первая попытка подключения будет неудачной, то он же тупо больше и не будет пытаться подключиться?
53 fisher
 
28.04.12
17:13
Воткнул в случае неудачного подключения ОбновитьПовторноИспользуемыеЗначения();
54 ahachack
 
28.04.12
17:25
(51) это для случаев когда клиент "перепрыгивает" между серверами кластера
(52,53) скорее всего... тогда еще проверку на "Неопределено" добавлять надо - и в случае неуспеха - ОбновитьПовторноИспользуемыеЗначения().
55 Ахиллес
 
28.04.12
17:27
(53) Не поможет. Если соединения нет, то пофигу, что в переменной находится. Грубо говоря между двумя компьютерами кабель ножницами перерезали, что ты там у себя на компе будешь делать уже не важно.
Только заново попытку соединения делать.
56 fisher
 
28.04.12
17:35
(55) Ты не понял. Допустим, в первый раз были неправильные параметры подключения и соединение не удалось. Я исправляю параметры, но функция уже запомнила возвращенное значение Неопределено. И пока я не закрою сеанс 1С уже не будет пытаться реально подключиться. Для этого и нужен сброс повторно используемых значений.
57 fisher
 
28.04.12
17:38
(56) Если передавать параметры подключения через параметры такой функции, то такой бяки ессно не будет... Наверное сделаю в два этапа - так красивше будет. А то ради этого сбрасывать весь кэш тоже некрасиво.
58 ahachack
 
28.04.12
18:02
(56,57) я имел в виду что-то такое сделать(в процедурах формы):
ComОбъект=Кеш.ПолучитьКомСоединение();
Если ComОбъект=Неопределено Тогда
//  Сообщить как нибудь
ОбновитьПовторноИспользуемыеЗначения();
// предпринять что-то дальше - например сделать еще одну попытку              //ComОбъект=Кеш.ПолучитьКомСоединение();
....
КонецЕсли;

но вообще как-то плохо с этой ситуацией, весь кеш сбрасывать в некоторых ситуациях - слишком большая цена
59 Diman000
 
28.04.12
18:04
Тоже делал через повт. исп. в ОМ, как в (40). Вроде работает.
60 Ахиллес
 
28.04.12
18:07
(58) Так тебе нужно держать соединение или закрывать и заново открывать?
61 Diman000
 
28.04.12
18:14
Кстати, V82.ComConnector это как бэ не само соединение. Так что я вообще немного не так делал.
Я возвращал сам объект V82.ComConnector, а дальше метод Connect сам смекал соединятся снова или использовать пул.
Собственно, вот такой вот код:

Функция ПолучитьКОМКоннектор82() Экспорт

   COMConnector = Новый COMОбъект("V82.COMConnector");
   COMConnector.PoolCapacity = 1;
   COMConnector.PoolTimeout = 0;
   COMConnector.MaxConnections = 0;
   
   Возврат COMConnector;
   
КонецФункции // ПолучитьКОМКоннектор82()

Зачем нужно устанавливать PoolCapacity и прочее уже точно не скажу) Вроде без них не взлетало...
62 ahachack
 
28.04.12
18:15
(60) да у меня вроде и в первоначальном виде работает :-)
А в (58) вариант как можно сделать подключение "заново" (например с другим параметрами, к другому серверу и т.д.)... хотя если ножницами по кабелю - тут непонятно что делать
63 Ахиллес
 
28.04.12
18:27
Мне нужно было, что бы соединение устанавливалось при начале работы и не разрывалось до момента пока базу не закроют. Иначе пришлось бы вставлять попытку нового соединения в кучу мест. А соединение не мгновенно устанавливается, меня при отладке это просто вымораживало, я представил, как будут бесится пользователи и просто не допускаю разрыва соединения. Раз в 10 мин. дергаю базу и соединение держится.
64 fisher
 
28.04.12
18:51
Ну а я сделал как в (40), т.е. возвращаю соединение. Но в два захода. В общем модуле с повторным использованием возвращаемых значений разместил функцию, которая в качестве параметра принимает строку соединения.
А функцию без параметров, которая вызывает первую, разместил в обычном общем модуле. В принципе, все то же самое получается, только не нужно сбрасывать кэш после передачи неправильной строки соединения.
Глупец, лишенный способности посмеяться над собой вместе с другими, не сможет долго выносить программирование. Фредерик Брукс-младший