Надеюсь, что кому-то эта небольшая статья сэкономит время.
Что делать, если COM-соединение вылетает?
Для COM-соединения используется два 1С-объекта: V82.Application, V82.COMConnector. Считается, что объект: V82.Application менее эффективен, так как использует интерфейсные библиотеки, при этом объект V82.COMConnector не имеет в своем арсенале ничего из того, что отвечает за интерфейс. Казалось бы всё просто и понятно, но есть одно “НО” – при использовании V82.COMConnector 1С 8.2 теряет ключ защиты или вылетает по Run-time (хотя и не всегда, а при некоторых, одному одинэсу ведомых условиях…).
С обозначенной бедой в полной мере я столкнулся в релизе платформы 8.2.15.319 (хотя, в более ранних релизах беда тоже была). Выглядело это примерно так – при множественных обращениях к информационным базам обработка, которая использовала данные внешних ИБ успешно отрабатывала, а вот при закрытии этой обработки начиналась та самая чехарда. Иногда и не закрывая обработки, а просто попытавшись открыть, скажем, справочник Контрагенты, текущая информационная база радостно вылетала.
Понятно, что первое, что приходит на ум – некорректное закрытие подключений. Но нет, подключение существовало ровно, пока было необходимо. Потом ему присваивалось значение Неопределено. Много еще где копал, но, как выяснилось – искал черную кошку в темной комнате. В конце концов нашел описание ошибки, зарегистрированное на http://users.v8.1c.ru/ там, где платформы скачивают. В релизе 8.2.15.319 ошибка, как следовало из описания, была исправлена. Однако, моя платформа об этом не знала…
Что в результате? В результате отказался от использования объекта V82.COMConnector и вместо него взял V82.Application и COM-соединение стало работать стабильно. Из негатива только такой нюанс: при отключении внешнего соединения, выдавалось окно диалога, с просьбой подтвердить выход из приложения. Окно мне было без надобности, поэтому отключил его вывод на уровне системной записи, под которой происходило подключение к информационной базе.
Такая вот история…
Ниже привожу код для подключения с использованием V82.Application.
Модуль формы обработки.
Перем мТекущееПодключение Экспорт ;
…
Процедура ПодключитьИБСерверныйВариант(ИмяСервера, ИмяБазы, Пользователь, Пароль) Экспорт
мТекущееПодключение = новый COMОбъект("V82.Application");
Состояние(ИмяБазы + "..." + " возможны интерфейсные сообщения...");
Connection = Истина;
Попытка
Connection = мТекущееПодключение.Connect("Srvr="+СокрЛП(ИмяСервера) + ";" + "Ref="+СокрЛП(ИмяБазы) + ";" + "Usr="+СокрЛП(Пользователь) + ";" + "Pwd="+СокрЛП(Пароль));
Исключение
мТекущееПодключение = Неопределено;
Предупреждение("Ошибка открытия информационной базы" + ИмяБазы );
Сообщить(ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
На нюансах работы с объектами внешней ИБ здесь останавливаться не буду, по этому поводу много чего есть, в том числе и на infostart. Напомню, только, что для того, чтобы работать с запросом во внешней базе можно использовать такой код:
Запрос = мТекущееПодключение.NewObject("Query");
Запрос.Текст = “….Текст запроса …”;
Запрос.УстановитьПараметр("НачалоПериода",
НачалоПериода);Запрос.УстановитьПараметр("КонецПериода" , КонецДня(КонецПериода));
Для того, чтобы передать массив субконто, подойдет такой код:
ВидыСубконтоКД = мТекущееПодключение.NewObject("Массив");
ВидыСубконтоКД.Добавить(мТекущееПодключение.ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты);
ВидыСубконтоКД.Добавить(мТекущееПодключение.ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Договоры);
Запрос.УстановитьПараметр("ВидыСубконтоКД", ВидыСубконтоКД);
Обратите внимание, что массив во внешней информационной базе в вышеприведенном примере создается при помощи мТекущееПодключение.NewObject(«Массив»);
надо сказать, что использование V82.Application из негатива несет не только, что могут появляться диалоговые окна при закрытии соединения, а еще жрет памяти больше и медленно загружается, т.к. по сути происходит загрузка всей конфигурации…
минус за то, что пример как бы не совсем к тематики статьи… да и сильного отличия в коде при подключении через ComConnector или Application нет
Речь не про то, что память жрет, это понятно. Речь о том, что V82.COMConnector работает не стабильно. Один-два раза вы сможете подключиться к данным, потом произойдет вылет. Во всяком случае, на 8.2.15. В анонсе я определил цели статьи — экономия времени того несчастного, который столкнется с данной проблемой. Переключение на Application реально спасает, хотя и менее эффективно
Не сталкивался с вылетами в com, можно подробнее описать проблему ?
На разных платформах работал. Все же ком всегда работал. Если и были проблемы, то только с кодом, который был неправильно написан и был источником ошибок.
По этой теме может кому-то пригодится обходной путь:
Замена в 1С:Предприятие 8.2 COM/OLE для доступа из Linux и других операционных систем
Ошибка описана в статье. Я понимаю, что в комментариях звучат некоторые сомнения. Сам бы не поверил. Выгледело примерно так: запускаешь раз пять отчет с разными входными параметрами, потом открываешь, скажем, справочник контрагентов, а эсина вылетает. Либо с сообщением, что потерян ключ защиты, либо по run-time errjr какой-то сишной библиотеки (оную даже админа попросил переставить, не помогло). Еще раз напомню, что речь о 8.2.15. Можно почитать список ошибок платформы на эсовском сайте, там много ошибое с com.
Раньше я то же не сталкивался…
Рад бы, если речь о моей ошибке. Если у кого-то есть абстрактные идеи (код, честно говоря, приводить лень), рад был бы услышать
Хм, в рабочей базе используется отчет, собирающий по ComConnector данные из примерно 5-6 баз. Самим отчетом регулярно пользуются 2-3 человека. Ни единого репорта не было.
Вполне верю автору. От 1С можно такое ожидать.
Сам лично не сталкивался, но и активно моим СОМ-отчетом, намедни написанным, пока не пользовались.
Посему настрожился.
Мне не понятна это предложение:
Можешь расшифровать до уровня элементарных действий? Меня лично это окошко просто выводит из себя.
И еще. Строка типа:
Это просто правило хорошего тона? Просто в мануалах сказано что соединение существует пока существует контекст, в котором оно создано. Или я что-то не тек понял?