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