COM-объекты в 1С: подключение, вызов методов и освобождение

· 9 мин

Содержание

COM-объект в 1С создаётся одной строкой: Новый COMОбъект("ProgID"), где ProgID — зарегистрированное в Windows имя класса, например Excel.Application или V83.COMConnector. Дальше вы обращаетесь к его свойствам и методам как к обычному объекту встроенного языка, ловите сбои через Попытка, а в конце очищаете ссылку, чтобы внешнее приложение не осталось в памяти.

Через COM 1С умеет вызывать Excel, Word, Outlook, драйверы баз данных и подключаться к другой информационной базе 1С. Ниже — как это подключить, как вызывать методы и свойства, как обрабатывать ошибки интеграции и когда COM лучше заменить штатными средствами платформы.

COM работает только под Windows. На сервере под Linux и в веб-клиенте Новый COMОбъект недоступен — об этом в разделе про ограничения.

Технология COM: 1С как клиент и как сервер

COM (Component Object Model) — механизм Windows, позволяющий одной программе вызывать функции другой через зарегистрированные классы. 1С участвует в этом в двух ролях.

🔹 1С как COM-клиент. Платформа создаёт объект внешнего приложения и управляет им: открывает Excel, формирует письмо в Outlook, обращается к ADO. Это самый частый сценарий автоматизации.

🔹 1С как COM-сервер. Внешняя программа (другая 1С, скрипт, своя утилита) подключается к информационной базе и работает с её объектами. Для этого служат классы V83.COMConnector (внешнее соединение, без интерфейса) и V83.Application (запуск толстого клиента в фоне).

Каждый класс опознаётся по строковому идентификатору ProgID. Он должен быть зарегистрирован в реестре Windows — обычно это делает установщик приложения. Если класса в реестре нет, 1С выдаст ошибку ещё на этапе создания объекта.

Создаём COM-объект: Новый COMОбъект

Основной инструмент — конструктор Новый COMОбъект(<ProgID>). Он возвращает ссылку на внешний объект:

Excel = Новый COMОбъект("Excel.Application");
Excel.Visible = Ложь;  // окно приложения не показываем

Частые ProgID, которые пригодятся на практике:

ProgIDЧто даёт
Excel.Applicationработа с книгами и ячейками Excel
Word.Applicationформирование документов Word
Outlook.Applicationотправка писем через установленный Outlook
ADODB.Connectionподключение к SQL-базам через ADO
Scripting.FileSystemObjectоперации с файлами и папками
V83.COMConnectorвнешнее соединение с базой 1С

Через ADODB.Connection обращаются к внешним SQL-базам напрямую, минуя внешние источники данных, а через Scripting.FileSystemObject выполняют операции с файлами, которых нет во встроенном языке (перебор содержимого папки, проверка свободного места). Выбор ProgID зависит от задачи, но логика работы одинакова для всех классов.

Создание объекта на сервере и на клиенте — разные вещи. Если код с Новый COMОбъект выполняется в серверном контексте, приложение должно быть установлено именно на сервере, а у учётной записи службы 1С должны быть права на его запуск. На практике выгрузку в Excel чаще делают в клиентском контексте, чтобы использовать Office, установленный на машине пользователя.

Для внешнего соединения с базой 1С удобнее не Новый COMОбъект, а глобальный ПолучитьCOMОбъект, но принцип тот же: сначала объект, затем его методы.

Свойства и методы: как обращаться к объекту

После создания объект ведёт себя как обычная переменная встроенного языка. У него есть свойства (читаются и присваиваются) и методы (вызываются со скобками).

Свойство читается и задаётся напрямую:

Excel.Visible = Истина;          // присвоили свойство
ТекущаяВерсия = Excel.Version;   // прочитали свойство

Метод вызывается со скобками, аргументы передаются по порядку:

Книга = Excel.Workbooks.Add();            // метод, возвращает объект
Лист  = Книга.Worksheets(1);              // обращение по индексу
Лист.Cells(1, 1).Value = "Наименование";  // цепочка свойств

Несколько правил, которые экономят часы отладки:

  • 🔸 Регистр имён важен. Внешние COM-объекты чувствительны к регистру: Workbooks, а не workbooks. Имена пишут так, как в документации приложения (обычно английские).
  • 🔸 Индексация со своей базой. У коллекций COM нумерация часто начинается с 1 (Worksheets(1) — первый лист), а не с 0, как в коллекциях 1С. Сверяйтесь с документацией объекта.
  • 🔸 Объекты, возвращаемые методами, — тоже COM. Книга, Лист, Ячейка — отдельные COM-объекты, их тоже желательно освобождать.

Строковые и числовые значения между 1С и COM преобразуются автоматически. Даты и логические значения тоже передаются, но будьте внимательны к форматам: Excel принимает дату как число, поэтому иногда проще присвоить строку в нужном виде.

Соединение с другой базой 1С через V83.COMConnector

Отдельный частый сценарий — программный обмен между базами. Его обеспечивает внешнее соединение:

Коннектор = Новый COMОбъект("V83.COMConnector");
СтрокаСоединения = "File=""C:\Bases\Buh"";Usr=""Обмен"";Pwd=""пароль""";
Соединение = Коннектор.Connect(СтрокаСоединения);

Двойные кавычки внутри строки соединения экранируются удвоением — это видно в примере. Для серверной базы вместо File= указывают Srvr= и Ref=.

Через полученное Соединение доступны объекты чужой базы — справочники, документы, запросы:

Выборка = Соединение.Справочники.Номенклатура.Выбрать();
Пока Выборка.Следующий() Цикл
    Сообщить(Выборка.Наименование);
КонецЦикла;

Чтобы V83.COMConnector заработал, на машине должен быть зарегистрирован comcntr.dll нужной версии и разрядности платформы. Ставится вместе с платформой; при сбое помогает повторная регистрация через regsvr32.

Разрядность здесь критична: 64-разрядная платформа подключается к 64-разрядному коннектору, 32-разрядная — к 32-разрядному. Несовпадение даёт ошибку «Класс не зарегистрирован».

Не путайте V83.COMConnector с V83.Application. Коннектор даёт внешнее соединение без пользовательского интерфейса — оно легче и быстрее, годится для фоновых обменов. V83.Application запускает полноценный толстый клиент в фоне: он тяжелее, но позволяет работать с формами и интерактивными методами. Для чтения и записи данных почти всегда достаточно коннектора.

Полученное соединение — тоже COM-объект, и его желательно обнулить после работы: Соединение = Неопределено. Долго удерживать внешнее соединение не стоит — оно занимает отдельный сеанс в целевой базе.

Ошибки COM и как их поймать

Внешние объекты ведут себя непредсказуемо: приложение может быть не установлено, занято, закрыто пользователем. Поэтому любое обращение к COM оборачивают в Попытка:

Попытка
    Excel = Новый COMОбъект("Excel.Application");
Исключение
    Сообщить("Не удалось запустить Excel: " + ОписаниеОшибки());
    Возврат;
КонецПопытки;

Тексты ошибок COM часто малопонятны, потому что приходят из внешнего приложения. Чтобы получить максимум деталей, используйте ИнформацияОбОшибке() и ПодробноеПредставлениеОшибки() — они покажут исходное COM-сообщение и код.

Самые частые симптомы разобраны в подсказке ниже.

Диагностика: выберите симптом

Освобождение ресурсов: чтобы процессы не висели

Платформа 1С сама освобождает COM-объект, когда переменная выходит из области видимости или ей присваивают Неопределено. Для простых объектов этого достаточно.

Проблема возникает с приложениями-серверами вроде Excel или Word: даже после закрытия процедуры их процесс может остаться в памяти, если на объект ещё есть ссылки. Корректное завершение — два шага.

  1. Вызвать штатный метод закрытия приложения: Excel.Quit().
  2. Очистить все ссылки, включая дочерние объекты (книга, лист, ячейка), присвоив им Неопределено.
Книга.SaveAs("C:\Выгрузка\Отчёт.xlsx");
Excel.Quit();
Лист  = Неопределено;
Книга = Неопределено;
Excel = Неопределено;

Порядок важен: сначала очищайте дочерние объекты (ячейку, лист, книгу), потом само приложение — иначе ссылка «снизу» удержит процесс. Если после прогона в диспетчере задач остаётся лишний EXCEL.EXE, значит какой-то промежуточный объект не обнулён.

Никогда не снимайте зависший процесс офисного приложения на сервере в рабочее время вслепую: вы можете оборвать выгрузку, которую в этот момент делает другой пользователь. Разбирайтесь с источником ссылки в коде.

Рабочие примеры: выгрузка в Excel и письмо через Outlook

Соберём законченную выгрузку таблицы в Excel — типовую задачу автоматизации.

Попытка
    Excel = Новый COMОбъект("Excel.Application");
    Excel.Visible = Ложь;
    Книга = Excel.Workbooks.Add();
    Лист  = Книга.Worksheets(1);

    Лист.Cells(1, 1).Value = "Номенклатура";
    Лист.Cells(1, 2).Value = "Количество";

    Строка = 2;
    Для Каждого ЭлементТЗ Из ТаблицаТоваров Цикл
        Лист.Cells(Строка, 1).Value = ЭлементТЗ.Номенклатура;
        Лист.Cells(Строка, 2).Value = ЭлементТЗ.Количество;
        Строка = Строка + 1;
    КонецЦикла;

    Книга.SaveAs("C:\Выгрузка\Товары.xlsx");
    Excel.Quit();
Исключение
    Сообщить("Ошибка выгрузки: " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;

Лист  = Неопределено;
Книга = Неопределено;
Excel = Неопределено;

Обратите внимание: заголовки пишутся в первую строку, данные — начиная со второй, счётчик Строка увеличивается на каждой итерации. Освобождение объектов вынесено после КонецПопытки, чтобы оно выполнилось при любом исходе.

Второй частый пример — письмо через установленный Outlook:

Outlook = Новый COMОбъект("Outlook.Application");
Письмо  = Outlook.CreateItem(0);   // 0 — почтовое сообщение
Письмо.To      = "buh@example.ru";
Письмо.Subject = "Акт сверки";
Письмо.Body    = "Акт во вложении.";
Письмо.Send();
Outlook = Неопределено;

CreateItem(0) создаёт почтовое сообщение, Send() отправляет. Метод сработает, если на машине настроен профиль Outlook с активной учётной записью.

Формирование документа Word строится так же — через объект приложения, коллекцию документов и диапазоны текста:

Word = Новый COMОбъект("Word.Application");
Word.Visible = Ложь;
Документ = Word.Documents.Add();
Документ.Content.Text = "Договор № 125";
Документ.SaveAs("C:\Выгрузка\Договор.docx");
Word.Quit();
Документ = Неопределено;
Word     = Неопределено;

Прежде чем запускать подобный код в рабочей базе, пройдитесь по короткому списку проверок — он снимает большую часть ошибок интеграции.

Что проверить перед работой с COM
Выполнено: 0 / 6

Ограничения COM и чем его заменить

COM удобен, но несёт зависимости, которые ломают переносимость. Главные ограничения:

  • 🚫 Только Windows. На сервере под Linux COM недоступен совсем. Это главная причина отказа от него при переходе на Linux-серверы.
  • 🚫 Нужно установленное приложение. Excel, Word, Outlook должны быть на той машине, где выполняется код, — на сервере или на клиенте в зависимости от контекста.
  • 🚫 Совпадение разрядности. Для внутрипроцессных компонентов (драйверы, comcntr.dll) разрядность платформы и компоненты обязана совпадать.
  • 🚫 Недоступно в веб-клиенте. Браузерный клиент не может создавать произвольные COM-объекты.
  • 🚫 Нестабильность и утечки. Внешние процессы зависают, оставляют хвосты в памяти, зависят от версии Office.

Во многих случаях COM заменяется штатными, кроссплатформенными средствами платформы:

ЗадачаЗамена COM
Выгрузка/чтение таблицТабличныйДокумент (умеет XLSX без Excel)
HTTP-запросы к сервисамHTTPСоединение и HTTPЗапрос
Чтение и запись XMLЧтениеXML / ЗаписьXML
Обмен между базами 1Свеб-сервисы, OData, планы обмена
Кроссплатформенные компонентывнешние компоненты (Native API)

Выбирайте COM, когда задача действительно требует внешнего приложения Windows и переносимость не важна. Если база живёт на Linux-сервере или код должен работать в веб-клиенте — сразу ориентируйтесь на штатные объекты.

Частые вопросы

Почему объект создаётся, а при вызове метода падает ошибка?
Объект создан, но метод вызван неверно: перепутаны скобки, регистр имени или порядок аргументов. Смотрите исходный текст ошибки через ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()) — там будет сообщение внешнего приложения.
Код работает на моей машине, но не на сервере. В чём дело?
Приложение (например, Excel) установлено у вас, но не на сервере, либо у учётной записи службы 1С нет прав его запускать. Проверьте, в каком контексте выполняется Новый COMОбъект — клиентском или серверном.
Нужно ли освобождать объект вручную, если он локальный?
Для простых объектов нет: платформа освободит их при выходе из процедуры. Приложения-серверы (Excel, Word) закрывайте методом Quit() и обнуляйте ссылки, иначе процесс останется в памяти.
COM-соединение к базе работает в 32-битной платформе и не работает в 64-битной. Почему?
Зарегистрирован comcntr.dll только одной разрядности. Для 64-разрядной платформы нужен 64-разрядный коннектор; зарегистрируйте нужную версию через regsvr32.
Можно ли использовать COM на сервере под Linux?
Нет. COM — технология Windows. Для Linux-серверов используйте штатные средства: ТабличныйДокумент, HTTPСоединение, веб-сервисы, внешние компоненты на Native API.