В процессе работы с учетными системами часто возникает необходимость автоматизировать вывод на печать договоров или актов, созданных в формате Microsoft Word. Типичная задача для программиста 1С 7.7 — организовать пакетную печать нескольких документов нажатием одной кнопки, при этом обеспечив специфические требования: двустороннюю печать, удаление определенных элементов (например, факсимильных печатей) и предотвращение зависаний системы. Рассмотрим подробно, как реализовать этот функционал через механизмы COM-соединения.
Для начала взаимодействия с Microsoft Word нам необходимо создать объект Word.Application. Проанализируем типичный алгоритм запуска процесса: мы создаем экземпляр приложения, делаем его невидимым для пользователя (чтобы избежать лишнего мерцания окон) и открываем нужный файл. Важно помнить о корректном закрытии объекта после завершения работы, чтобы в диспетчере задач не скапливались «зависшие» процессы WINWORD.EXE.
Разберем пример кода для инициализации:
// Создаем объект связи с Word
Попытка
Ворд = СоздатьОбъект("Word.Application");
Исключение
Сообщить("Microsoft Word не установлен на данном компьютере!");
Возврат;
КонецПопытки;
// Настраиваем режим видимости
Ворд.Visible = 0; // 0 - невидимо, 1 - видимо
Ворд.DisplayAlerts = 0; // Отключаем все предупреждения и диалоговые окна
Программное управление параметром двусторонней печати (Duplex) напрямую через COM-объект Word в связке с 1С 7.7 часто бывает нестабильным, так как эти настройки сильно зависят от драйвера конкретного принтера. Проанализируем наиболее надежный способ решения этой задачи.
Самый эффективный метод — создание копии принтера в операционной системе. Вы можете установить тот же самый принтер второй раз, назвав его, например, «HP_Duplex», и в его системных свойствах по умолчанию выставить «Двусторонняя печать». Тогда из 1С нам останется только переключить активный принтер перед отправкой на печать.
// Запоминаем текущий принтер, чтобы вернуть его позже
СтарыйПринтер = Ворд.ActivePrinter;
// Переключаемся на принтер с предустановленным дуплексом
Ворд.ActivePrinter = "HP_Duplex";
// Открываем документ
Док = Ворд.Documents.Open(ПутьКФайлу);
// Печать документа
Док.PrintOut(0); // Параметр 0 означает Background = False (ждем завершения отправки)
// Возвращаем настройки принтера обратно
Ворд.ActivePrinter = СтарыйПринтер;
Часто в шаблонах договоров присутствуют рисунки печатей или подписей, которые нужно удалить перед печатью на оригинальном бланке. Выясним причину, почему стандартный перебор коллекции рисунков иногда не работает.
В объектной модели Word изображения делятся на две категории:
Чтобы гарантированно очистить документ от всех печатей, нам нужно перебрать обе коллекции. Рассмотрим правильный способ удаления объектов в цикле (всегда используйте обратный порядок, чтобы не сбивались индексы):
// Удаляем встроенные рисунки (InlineShapes)
Колво = Док.InlineShapes.Count;
Для Ном = -Колво По -1 Цикл
Док.InlineShapes.Item(-Ном).Delete();
КонецЦикла;
// Удаляем плавающие рисунки (Shapes) - именно здесь обычно прячутся печати "за текстом"
КолвоShapes = Док.Shapes.Count;
Для Ном = -КолвоShapes По -1 Цикл
Док.Shapes.Item(-Ном).Delete();
КонецЦикла;
Рассмотрим ситуацию, когда процесс пакетной печати прерывается невидимым для пользователя окном Word. Например, если поля документа выходят за область печати принтера, Word выдает предупреждение: «Поля раздела 1 выходят за границы области печати. Продолжить?». В режиме автоматизации это окно блокирует работу 1С.
Для решения этой проблемы мы используем свойство DisplayAlerts. Установка значения 0 (или константы wdAlertsNone) заставляет Word автоматически принимать решение по умолчанию (в данном случае — «Продолжить»).
Также обратим внимание на метод PrintOut. У него есть важный параметр Background. Если установить его в значение True (1), Word начнет печать в фоновом режиме и сразу вернет управление в 1С. Если вы после этого сразу попытаетесь закрыть документ командой Close(), возникнет ошибка. Поэтому для пакетной печати рекомендуется использовать Background = False (0), чтобы 1С дождалась постановки задания в очередь печати Windows.
Иногда требуется проверить, совпадает ли дата в Word-файле с датой документа в 1С. Поскольку текст в Word может быть отформатирован произвольно (с пробелами, подчеркиваниями), простым поиском подстроки обойтись сложно. Посмотрим на возможные подходы:
Вариант 1: Использование регулярных выражений (RegExp). В 1С 7.7 можно подключить объект VBScript.RegExp для поиска дат по шаблонам. Это позволит найти даже такие варианты, как «01 11 2021» или «01.11.2021».
Вариант 2: Использование закладок (Bookmarks). Это наиболее профессиональный метод. Если вы сами создаете шаблоны, расставьте в них именованные закладки. Тогда вместо поиска текста вы сможете обращаться напрямую к объекту:
Если Док.Bookmarks.Exists("ДатаДоговора") = 1 Тогда
ТекстДаты = Док.Bookmarks.Item("ДатаДоговора").Range.Text;
// Сравнение с датой из 1С
КонецЕсли;
После того как печать завершена, необходимо правильно освободить память. Проанализируем финальные шаги:
// Закрываем документ без сохранения изменений
Док.Close(0);
// Выходим из приложения Word
Ворд.Quit();
// Очищаем переменную для разрыва COM-соединения
Ворд = "";
Применяя эти методы, мы получаем надежный инструмент автоматизации, который корректно обрабатывает графику, не «зависает» на системных сообщениях и позволяет гибко управлять настройками принтера даже в условиях ограничений платформы 1С 7.7.