Как подключиться к базе 1С 7.7 через COM из 1С 8.3 и найти контрагента?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Интеграция между современными конфигурациями 1С 8.3 и устаревшими базами 1С 7.7 через COM-соединение (OLE Automation) — распространенная задача при поэтапном переходе или синхронизации данных. Однако на практике разработчики регулярно сталкиваются с двумя проблемами: метод Initialize возвращает 0 при попытке подключиться к уже открытой базе, а поиск элементов в справочниках 7.7 вызывает исключительные ситуации. Разберем по шагам причины этих ошибок и рассмотрим правильные варианты реализации.

Анализ строки подключения и инициализация COM-соединения

Выясним причину, почему соединение может не устанавливаться изначально. В исходном коде часто встречается передача пути к исполняемому файлу программы прямо в строку параметров команды инициализации:


Каталог77 = "C:\Users\******\Desktop\1cv77\BIN\1cv7.exe";
Стр = """" + Каталог77 + """" + "enterprise /d""" + Каталог + """";
Открыта = V77.Initialize(V77.RMTrade, Стр, "NO_SPLASH_SHOW");

Это распространенная ошибка. Метод Initialize не является вызовом командной строки Windows, он вызывается у уже созданного COM-объекта приложения. Передавать путь к 1cv7.exe в строке параметров категорически не требуется. Строка должна содержать только параметры запуска режима 1С:Предприятие.

Посмотрим на корректный синтаксис вызова метода инициализации:


ПараметрыПодключения = "Enterprise /d""" + ПутьКБазе + """ /n""" + ИмяПользователя + """ /p""" + Пароль + """";
Открыта = V77.Initialize(V77.RMTrade, ПараметрыПодключения, "NO_SPLASH_SHOW");

Почему 1С 7.7 не открывается, если база уже запущена?

Проанализируем ситуацию, когда база закрыта — соединение устанавливается штатно, но если хотя бы один пользователь уже работает в 7.7, метод Initialize возвращает 0 («Базу данных открыть не удалось»).

Выделим основные причины такого поведения:

  1. Локальная (однопользовательская) версия платформы 7.7. Если используется ключ защиты на одно рабочее место, платформа физически блокирует запуск второго сеанса. Проверить это просто: попробуйте запустить второй сеанс 1С 7.7 вручную через ярлык под другим пользователем. Если программа выдает предупреждение об ограничении лицензии или открывается только монопольно — OLE-сервер также не сможет войти.
  2. Занятый каталог пользователя. В 1С 7.7 каждому пользователю в конфигураторе может быть назначен персональный рабочий каталог. Если в этот каталог уже вошел интерактивный сеанс, второй процесс (включая OLE) не сможет заблокировать внутренние системные файлы. Для OLE-подключения рекомендуется завести отдельного служебного пользователя без привязки персонального каталога либо передавать специальный каталог через ключ /u.
  3. Монопольный режим. Если кто-либо из пользователей запустил базу с установленным флагом «Монопольно» (или с ключом /m), ни одно разделенное подключение выполнено быть не может.
  4. Всплывающие модальные окна. Параметр "NO_SPLASH_SHOW" отключает только экранную заставку. Если при запуске базы появляется любое диалоговое окно (сообщение о некорректном завершении работы, требование переиндексации, несовпадение кодовой страницы порядка сортировки или модальные окна из модуля ПриНачалеРаботыСистемы), OLE-сеанс не может отобразить диалог интерактивно и аварийно завершает инициализацию с возвратом 0.

Правила поиска элементов справочника через COM в 1С 7.7

После успешного вызова CreateObject("Справочник.Контрагенты") разработчики часто забывают об отличиях объектной модели 7.7 от 8.3. Рассмотрим особенности работы с методами поиска:

  1. Возвращаемое значение. В платформе 1С 7.7 методы НайтиПоНаименованию(), НайтиПоКоду() и НайтиПоРеквизиту() возвращают не ссылку на элемент и не булево значение, а число: 1 — элемент успешно найден, 0 — элемент не найден.
  2. Синтаксис метода НайтиПоРеквизиту(). Метод принимает три параметра: НайтиПоРеквизиту(ИмяРеквизита, Значение, ФлагГлобальногоПоиска). Передавать просто значение нельзя — платформа не сможет определить, по какому полю строить поиск, и выдаст исключение «Неверное имя реквизита!».
  3. Ограничение метаданных на отбор. Метод НайтиПоРеквизиту() в 1С 7.7 работает исключительно по тем реквизитам, для которых в конфигураторе включено свойство «Сортировка» или «Отбор по реквизиту». В типовых базах (например, «Торговля и Склад 7.7») реквизит ИНН часто не имеет такого признака, поэтому прямой вызов метода вызовет ошибку.

Работа с найденным объектом и закрытие OLE-сессии

Нельзя напрямую присвоить COM-объект в реквизит объекта информационной базы 1С 8.3, имеющий ссылочный тип. Объект V77.CreateObject существует только в контексте запущенного процесса семерки. Из него необходимо извлечь базовые примитивные типы (наименование, код, ИНН) и выполнить поиск соответствующей ссылки уже внутри базы 1С 8.3.

Также важно корректно освобождать память. Процесс 1cv7.exe останется висеть в диспетчере задач до тех пор, пока переменная COM-соединения не будет очищена сборщиком мусора.

Разберем готовый итоговый пример процедуры для 1С 8.3:


&НаКлиенте
Процедура НайтиКонтрагентаВ77(Команда)
    
    // Создаем экземпляр OLE-сервера
    Попытка
        V77 = Новый COMОбъект("V77.Application");
    Исключение
        Сообщить("Не удалось запустить COM-сервер 1С 7.7: " + ОписаниеОшибки());
        Возврат;
    КонецПопытки;
    
    ПутьКБазе = "C:\Users\Виталий\Desktop\1Cbase\1sbdb\";
    СлужебныйПользователь = "OleUser";
    Пароль = "123";
    
    // Формируем чистую командную строку
    ПараметрыЗапуска = "Enterprise /d""" + ПутьКБазе + """ /n""" + СлужебныйПользователь + """ /p""" + Пароль + """";
    
    Открыта = V77.Initialize(V77.RMTrade, ПараметрыЗапуска, "NO_SPLASH_SHOW");
    Если Открыта = 0 Тогда
        Сообщить("Базу данных открыть не удалось! Проверьте лицензию, занятость базы и права пользователя.");
        V77 = Неопределено;
        Возврат;
    КонецЕсли;
    
    Попытка
        СпрКонтр77 = V77.CreateObject("Справочник.Контрагенты");
        
        ИскомыйИНН = СокрЛП(Объект.ИНН);
        
        // Поиск по реквизиту (реквизит "ИНН" должен иметь включенный отбор в 7.7)
        Если СпрКонтр77.НайтиПоРеквизиту("ИНН", ИскомыйИНН, 1) = 1 Тогда
            
            Наименование77 = СокрЛП(СпрКонтр77.Наименование);
            Код77          = СокрЛП(СпрКонтр77.Код);
            
            Сообщить("Найден контрагент: " + Наименование77 + " (Код: " + Код77 + ")");
            
            // Заполняем реквизит 8.3 строковым значением либо ищем ссылку в 8.3
            Объект.ЗаказчикНаименование = Наименование77;
            
        Иначе
            Сообщить("Контрагент с ИНН " + ИскомыйИНН + " в базе 7.7 не найден.");
        КонецЕсли;
        
    Исключение
        Сообщить("Ошибка при чтении данных из 7.7: " + ОписаниеОшибки());
    КонецПопытки;
    
    // Обязательно освобождаем COM-объект для завершения процесса 1cv7.exe
    V77 = Неопределено;

КонецПроцедуры

Если в вашей конфигурации 7.7 реквизит ИНН не проиндексирован и метод НайтиПоРеквизиту() завершается с ошибкой, для поиска следует использовать объект Запрос через OLE либо метод последовательного обхода элементов ВыбратьЭлементы().

← На главную