Работа с внешними источниками данных через COM-соединение в 1С — это классический, но ресурсоемкий механизм. Основная проблема заключается в том, что каждое такое соединение потребляет значительный объем оперативной памяти и создает отдельный сеанс в целевой базе. Если соединение не закрывать вовремя, это может привести к нехватке лицензий, блокировкам при обновлении конфигурации (ошибка формата потока) и общему замедлению системы. Рассмотрим подробно, как реализовать механизм контроля активности соединения и его автоматического завершения по истечении заданного времени.
Процесс установки соединения через V83.COMConnector является длительным. Именно поэтому разработчики часто стремятся сохранить созданный объект в глобальной переменной, чтобы не тратить время на повторную авторизацию при каждом обращении. Однако "вечное" соединение — это плохая практика. Нам необходимо найти баланс: держать соединение открытым, пока пользователь активно с ним работает, и корректно разрывать его, если обращений не было, например, в течение 30 минут.
Проанализируем техническую сложность: стандартные средства 1С не позволяют напрямую "спросить" у объекта COMConnector, передает ли он данные в текущую секунду. Вызовы методов через COM происходят синхронно — пока выполняется запрос в другой базе, основной поток кода ожидает ответа. Следовательно, проверку нужно строить на логике "времени последнего обращения".
Для решения задачи мы будем использовать встроенный механизм платформы — ПодключитьОбработчикОжидания. Разберем алгоритм: при каждом обращении к внешней базе мы будем "сбрасывать" таймер. Если таймер дотикал до конца — значит, за это время обращений не было, и объект можно уничтожить.
Рассмотрим правильную структуру размещения кода. Важно помнить, что в 1С (особенно в управляемом приложении или при использовании глобальных процедур в обычном приложении) обработчик ожидания имеет жесткие требования к расположению процедуры. Она должна быть экспортируемой и находиться либо в модуле приложения, либо в глобальном общем модуле на стороне клиента.
Выясним причину частой ошибки "Недопустимое значение параметра (параметр номер '1')". Она возникает, если система не может найти указанную процедуру в глобальной области видимости клиента. Рассмотрим пример реализации, который учитывает эти особенности.
Шаг 1. Объявление переменной
В модуле обычного приложения (или в специализированном общем модуле) объявим переменную для хранения соединения:
Перем ОбъектКА Экспорт; // Здесь хранится наше COM-соединение
Шаг 2. Процедура управления соединением
Создадим логику, которая будет запускать или перезапускать отсчет времени при каждом обращении к базе. Проанализируем код:
// Процедура вызывается каждый раз, когда нам нужно COM-соединение
Процедура СтартComСоединения() Экспорт
// Если соединение уже установлено, сначала отключим старый таймер, чтобы начать отсчет заново
Если ОбъектКА <> Неопределено Тогда
ОтключитьОбработчикОжидания("глЗавершениеComСоединения");
КонецЕсли;
// Устанавливаем таймер на 1800 секунд (30 минут)
// Параметр Однократно = Истина, так как нам нужен разовый запуск по истечении времени
ПодключитьОбработчикОжидания("глЗавершениеComСоединения", 1800, Истина);
КонецПроцедуры
Шаг 3. Глобальный модуль-обертка
Чтобы избежать ошибок области видимости, создадим в Глобальном общем модуле (с галочкой "Глобальный" и "Клиент") процедуру-переходник:
Процедура глЗавершениеComСоединения() Экспорт
// Вызываем реальную процедуру очистки из нашего модуля
РаботаСВнешнимиБазами.ЗавершитьСеансCOM();
КонецПроцедуры
Шаг 4. Очистка объекта
В основном модуле (например, РаботаСВнешнимиБазами) пропишем само уничтожение объекта:
Процедура ЗавершитьСеансCOM() Экспорт
// Присваивание Неопределено освобождает ссылку на COM-объект
// Это инициирует закрытие сеанса в удаленной базе
ОбъектКА = Неопределено;
ЗаписьЖурналаРегистрации("COM-соединение",,,,"Сеанс завершен по таймауту неактивности.");
КонецПроцедуры
Проанализируем ситуацию, когда простого присвоения Неопределено недостаточно. В некоторых случаях Windows может удерживать процесс dllhost.exe (в котором работает COM) еще некоторое время. Если вам критично моментальное завершение для выполнения административных задач в другой базе, убедитесь, что в коде не осталось других ссылок на объекты, полученные из этого соединения (выборки, ссылки, документы).
Важный совет: всегда проверяйте состояние соединения перед использованием. Если переменная ОбъектКА равна Неопределено, вызывайте функцию подключения и сразу после этого — СтартComСоединения().
Рассмотрим ситуацию, когда пользователь хочет просто "посмотреть" объект в другой базе. Для этого совсем не обязательно держать тяжелое COM-соединение. Проанализируем механизм Навигационных ссылок.
В современных версиях 1С (8.3) у каждого объекта есть уникальный адрес. Мы можем получить его в целевой базе и передать в текущую. Вместо открытия базы через OLE, можно использовать запуск системы с параметром или метод ПерейтиПоСсылке().
ПолучитьНавигационнуюСсылку(Объект).e1cib/data/Справочник.Номенклатура?ref=...) в основную базу.Такой подход полностью снимает проблему "Ошибка формата потока" и зависших сеансов, так как управление жизненным циклом приложения берет на себя сама платформа и операционная система, а не ваш программный код.
Для надежной работы системы при использовании COM-соединений необходимо: