Работа с макетами типа ActiveDocument в среде «1С:Предприятие 8.3» является классической задачей, которая, тем не менее, часто вызывает затруднения у начинающих разработчиков. Основная сложность заключается в правильном распределении нагрузки между сервером и клиентом, а также в особенностях работы с технологией COM. В этой статье мы подробно разберем, почему возникают ошибки при попытке вывести макет Word, и как реализовать этот механизм правильно.
Рассмотрим типичную ситуацию: разработчик пытается вызвать метод ПолучитьМакет() и сразу начать работу с ним. Однако в управляемом приложении мы сталкиваемся с жестким разделением контекстов. Давайте проанализируем основные причины неудач:
COMОбъект("Word.Application") на сервере и попытаться вернуть его на клиент как результат функции. Платформа выдаст ошибку передачи данных, так как COM-объект не может быть сериализован.Для успешного решения задачи нам необходимо реализовать схему: Сервер (получение данных) — Временное хранилище — Клиент (создание файла и запуск Word). Рассмотрим этот алгоритм по шагам.
Прежде всего, нам нужно извлечь данные макета из объекта. Поскольку в управляемой форме мы работаем с данными формы, а не с самим объектом, нам придется использовать метод РеквизитФормыВЗначение. Посмотрим на пример серверной функции:
&НаСервере
Функция ПолучитьАдресМакетаНаСервере()
// Преобразуем данные формы в объект обработки или документа
ОбъектОбработки = РеквизитФормыВЗначение("Объект");
// Получаем макет из объекта. Тип возвращаемого значения — ActiveDocument
Макет = ОбъектОбработки.ПолучитьМакет("МойМакетWord");
// Помещаем двоичные данные макета во временное хранилище
// Это позволит передать файл с сервера на клиент в виде ссылки
АдресХранилища = ПоместитьВоВременноеХранилище(Макет, ЭтаФорма.УникальныйИдентификатор);
Возврат АдресХранилища;
КонецФункции
В этом блоке кода мы выполнили критически важную операцию: извлекли макет и превратили его в адрес (строку), который легко передается между контекстами. Важно: используйте УникальныйИдентификатор формы, чтобы данные во временном хранилище жили столько же, сколько открыта сама форма.
Теперь, когда у нас есть адрес данных, мы переходим на сторону клиента. Разберем ситуацию: нам нужно забрать данные из хранилища, сохранить их во временный файл на диске и открыть через Word.Application.
&НаКлиенте
Процедура ПечатьМакет(Команда)
// 1. Получаем адрес макета с сервера
АдресХранилища = ПолучитьАдресМакетаНаСервере();
// 2. Определяем путь для временного файла на локальном диске пользователя
ИмяФайла = ПолучитьИмяВременногоФайла("doc");
// 3. Получаем данные из хранилища и сохраняем в файл
ДанныеМакета = ПолучитьИзВременногоХранилища(АдресХранилища);
ДанныеМакета.Записать(ИмяФайла);
// 4. Инициализируем MS Word
Попытка
MSWord = Новый COMОбъект("Word.Application");
Исключение
Сообщить("Похоже, MS Word не установлен на этом компьютере.");
Возврат;
КонецПопытки;
// 5. Открываем наш временный файл
Документ = MSWord.Documents.Open(ИмяФайла);
MSWord.Visible = Истина;
MSWord.Activate();
// Здесь можно вызвать процедуру заполнения параметров (закладки или поиск/замена)
// ЗаполнитьПараметрыWord(Документ);
КонецПроцедуры
В этом примере мы обеспечили безопасную работу с файловой системой и COM-интерфейсом. Обратите внимание на блок Попытка...Исключение — работа с внешними компонентами всегда должна быть защищена от программных сбоев (например, если Office не установлен или поврежден).
Просто открыть пустой шаблон недостаточно. Выясним причину, по которой ActiveDocument так популярен: он позволяет программно вставлять данные из 1С в текст документа. Разберем два основных способа:
Документ.Bookmarks("ИмяЗакладки").Select(), после чего вставляется текст через MSWord.Selection.TypeText("ВашТекст").[НомерДокумента]. Программа ищет этот текст и заменяет его на реальное значение. Этот способ считается более надежным, так как маркеры нагляднее закладок.Рассмотрим пример кода для поиска и замены:
// Пример функции для замены текста
Selection = MSWord.Selection;
Selection.Find.ClearFormatting();
Selection.Find.Replacement.ClearFormatting();
Selection.Find.Execute("[НомерДокумента]", Ложь, Истина, Ложь, , , Истина, 1, , "№ 123-АФ", 2);
Проанализируем ситуацию с разрядностью приложений. Если вы используете 64-битную версию сервера 1С, но при этом пытаетесь выполнить код с COMОбъект на сервере, вы неизбежно столкнетесь с проблемами совместимости с 32-битным MS Office. Именно поэтому настоятельно рекомендуется выполнять всю визуальную работу с Word строго на клиенте.
Также стоит учитывать работу в веб-клиенте. Технология COM является специфичной для Windows и браузеры ее не поддерживают. Если ваша информационная база предполагает работу через браузер, использование ActiveDocument будет невозможным. В таких случаях следует рассмотреть вариант формирования файлов в формате .docx через программное изменение XML-структуры архива документа на сервере, что не требует наличия установленного Word вовсе.
Подводя итог, можно сказать, что ключ к успеху при работе с макетами Word в 1С — это четкое понимание границ "Сервер-Клиент" и использование временного хранилища как промежуточного звена для передачи двоичных данных.