Как передавать аргументы в методы COM-объекта MS Word из 1С?

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

При формировании печатных форм и отчетов на базе MS Word разработчики часто обращаются к официальной документации Microsoft (MSDN) или записывают макросы в редакторе VBA. Однако при попытке перенести готовые примеры кода на встроенный язык 1С возникает синтаксическая ошибка. Разберем, почему синтаксис Visual Basic не работает напрямую в 1С и как правильно передавать параметры в объектную модель Word.

Причина проблемы: именованные параметры против позиционных

Проанализируем пример из документации Word на Visual Basic:


Dim rng As Word.Range = Me.Application.ActiveDocument.Range(Start:=0, End:=7)
rng.Select()

В коде VBA используется конструкция именованных параметров Start:=0, End:=7. Платформа 1С:Предприятие принципиально не поддерживает синтаксис передачи именованных аргументов для COM-объектов. Все аргументы любых методов должны передаваться исключительно позиционно — строго в том порядке, который определен сигнатурой функции в библиотеке типов Word.

Решение 1. Передача параметров через позиционные аргументы

Посмотрим на правильный вариант вызова метода Range во встроенном языке 1С. Поскольку первым аргументом метода всегда выступает начальная позиция, а вторым — конечная, мы передаем их через запятую в соответствующем порядке:


MSWord = Новый COMОбъект("Word.Application");
MSWord.Visible = Истина;

Документ = MSWord.Documents.Add();
// Задаем область от 0 до 7 символа
Область = Документ.Range(0, 7);
Область.Select();

Если метод принимает большое количество необязательных аргументов, а передать требуется только некоторые из них, промежуточные значения пропускаются разделителями-запятыми:


// Пример пропуска промежуточных аргументов
ОбъектWord.НекийМетод(Значение1, , , Значение4);

Решение 2. Замена текстовых констант Word на их числовые коды

При переносе кода макросов разработчики часто сталкиваются с перечислениями вроде wdReplaceAll или wdDoNotSaveChanges. В среде 1С эти константы не определены автоматически, поэтому обращение к ним вызовет ошибку. Выясним причину: 1С не загружает таблицы констант COM-библиотек напрямую.

Разберем по шагам, как решить эту задачу:

  1. Открываем редактор макросов в MS Word (сочетание клавиш Alt + F11).
  2. Нажимаем клавишу F2, открывая Object Browser.
  3. Находим нужную константу и смотрим ее точное целочисленное значение.
  4. Объявляем эти константы переменными во встроенном языке 1С либо подставляем числа напрямую в параметры методов.

Посмотрим на пример замены текста в документе:


// Объявляем числовые эквиваленты констант Word
wdReplaceAll = 2;
wdFindContinue = 1;

Выборка = MSWord.Selection.Find;
Выборка.ClearFormatting();
Выборка.Replacement.ClearFormatting();

// Вызов метода Execute с передачей всех параметров по позициям
Выборка.Execute("[НомерДоговора]", , , , , , , wdFindContinue, , "123/45", wdReplaceAll);

Решение 3. Использование закладок (Bookmarks) и элементов управления

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

  1. Работа с закладками (Bookmarks): в документе создается именованная закладка через меню Word, а из 1С текст устанавливается напрямую по имени без вызова сложных методов:
    
    Если Документ.Bookmarks.Exists("НомерДоговора") Тогда
        Документ.Bookmarks.Item("НомерДоговора").Range.Text = "№ 123-А";
    КонецЕсли;
    
  2. Элементы управления содержимым (Content Controls): в современных версиях Word можно размещать поля через вкладку «Разработчик». 1С обращается к ним по тегу или названию через коллекцию Документ.ContentControls. Это исключает случайное удаление разметки пользователем шаблона.

Решение 4. Создание таблиц и добавление изображений

Если задача требует динамического формирования структуры страницы, разберем базовые операции работы с таблицами и графикой:


// Добавление таблицы: указываем позицию (Range), количество строк и колонок
ДиапазонДляТаблицы = Документ.Range(Документ.Content.End - 1, Документ.Content.End - 1);
Таблица = Документ.Tables.Add(ДиапазонДляТаблицы, 3, 2);

// Заполнение ячеек данными (индексация начинается с 1)
Таблица.Cell(1, 1).Range.Text = "Номенклатура";
Таблица.Cell(1, 2).Range.Text = "Количество";
Таблица.Cell(2, 1).Range.Text = "Товар 1";
Таблица.Cell(2, 2).Range.Text = "10";

// Вставка картинки в документ
ДиапазонДляКартинки = Документ.Range(Документ.Content.End - 1, Документ.Content.End - 1);
ДиапазонДляКартинки.InlineShapes.AddPicture("C:\Images\logo.png");

Решение 5. Корректное завершение работы с COM-объектом

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


MSWord = Неопределено;
Попытка
    MSWord = Новый COMОбъект("Word.Application");
    MSWord.Visible = Ложь;
    
    // Основные действия с документом
    Документ = MSWord.Documents.Add();
    // ...
    Документ.SaveAs2("C:\Reports\Result.docx");
    Документ.Close(0); // 0 = wdDoNotSaveChanges
Исключение
    Сообщить("Ошибка при работе с Word: " + ОписаниеОшибки());
КонецПопытки;

Если MSWord <> Неопределено Тогда
    MSWord.Quit();
    MSWord = Неопределено;
КонецЕсли;

Альтернативные архитектурные решения

COM-автоматизация на стороне сервера 1С имеет существенные ограничения: она работает только под управлением Windows, не поддерживается на Linux-серверах и не рекомендована компанией Microsoft для серверных приложений. В современных системах стоит рассмотреть альтернативы:

  1. Подсистема печати БСП: в «Библиотеке стандартных подсистем» реализован штатный механизм заполнения макетов в формате DOCX без использования COM-соединения. Параметры и списки описываются специальными метками в шаблоне.
  2. Прямая работа с ZIP-архивом: файл DOCX является набором сжатых XML-файлов. С помощью объектов ЧтениеZipФайла и ЗаписьZipФайла платформа 1С может распаковать архив, модифицировать файл word/document.xml и запаковать его обратно. Этот способ полностью кроссплатформенный и работает в десятки раз быстрее.
← На главную