При формировании печатных форм и отчетов на базе 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.
Посмотрим на правильный вариант вызова метода Range во встроенном языке 1С. Поскольку первым аргументом метода всегда выступает начальная позиция, а вторым — конечная, мы передаем их через запятую в соответствующем порядке:
MSWord = Новый COMОбъект("Word.Application");
MSWord.Visible = Истина;
Документ = MSWord.Documents.Add();
// Задаем область от 0 до 7 символа
Область = Документ.Range(0, 7);
Область.Select();
Если метод принимает большое количество необязательных аргументов, а передать требуется только некоторые из них, промежуточные значения пропускаются разделителями-запятыми:
// Пример пропуска промежуточных аргументов
ОбъектWord.НекийМетод(Значение1, , , Значение4);
При переносе кода макросов разработчики часто сталкиваются с перечислениями вроде wdReplaceAll или wdDoNotSaveChanges. В среде 1С эти константы не определены автоматически, поэтому обращение к ним вызовет ошибку. Выясним причину: 1С не загружает таблицы констант COM-библиотек напрямую.
Разберем по шагам, как решить эту задачу:
Посмотрим на пример замены текста в документе:
// Объявляем числовые эквиваленты констант Word
wdReplaceAll = 2;
wdFindContinue = 1;
Выборка = MSWord.Selection.Find;
Выборка.ClearFormatting();
Выборка.Replacement.ClearFormatting();
// Вызов метода Execute с передачей всех параметров по позициям
Выборка.Execute("[НомерДоговора]", , , , , , , wdFindContinue, , "123/45", wdReplaceAll);
Позиционная передача десятка параметров в метод поиска и замены текста громоздка и легко приводит к ошибкам. Рассмотрим более удобные и надежные способы заполнения шаблонов без использования прямого поиска:
Если Документ.Bookmarks.Exists("НомерДоговора") Тогда
Документ.Bookmarks.Item("НомерДоговора").Range.Text = "№ 123-А";
КонецЕсли;
Документ.ContentControls. Это исключает случайное удаление разметки пользователем шаблона.Если задача требует динамического формирования структуры страницы, разберем базовые операции работы с таблицами и графикой:
// Добавление таблицы: указываем позицию (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");
Проанализируем распространенную ошибку: если при выполнении операций в 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 для серверных приложений. В современных системах стоит рассмотреть альтернативы:
ЧтениеZipФайла и ЗаписьZipФайла платформа 1С может распаковать архив, модифицировать файл word/document.xml и запаковать его обратно. Этот способ полностью кроссплатформенный и работает в десятки раз быстрее.