Переход с платформы 1С 8.2 на 8.3 часто сопровождается трудностями при работе с офисными документами. Старые методы, основанные на типе макета ActiveDocument, перестают работать в клиент-серверном варианте, так как на сервере, как правило, не установлен Microsoft Office. В этой статье мы подробно разберем, как адаптировать формирование документов Word под современные требования платформы, используя двоичные данные, библиотеку стандартных подсистем (БСП) и COM-технологии на стороне клиента.
Рассмотрим ситуацию: при попытке выполнить код Договор.Получить() на сервере система выдает ошибку. Проанализируем причину. Метод Получить() для макета типа Active Document инициирует запуск соответствующего COM-сервера (в данном случае Word). Если код выполняется на сервере, 1С пытается найти установленный MS Word именно на серверной машине. Важно помнить: Microsoft официально не рекомендует устанавливать пакет Office на серверные операционные системы для автоматизации, и в 1С 8.3 это становится критической преградой.
Чтобы решить эту задачу, нам необходимо либо перенести формирование документа на сторону клиента, либо использовать методы, не требующие запуска приложения Word на сервере (например, работу с XML или двоичными данными).
Если вам необходимо сохранить привычную логику работы с объектом Word.Application, но база работает в режиме клиент-сервер, следует использовать следующий алгоритм. Мы получаем двоичные данные макета на сервере, передаем их на клиент, сохраняем во временный файл и открываем его через COM-объект.
Разберем пример кода. Сначала создадим функцию на сервере для получения макета:
&НаСервере
Функция ПолучитьМакетСервер(ИмяМакета)
ДоговорОбъект = РеквизитФормыВЗначение("Объект");
Возврат ДоговорОбъект.ПолучитьМакет(ИмяМакета); // Макет должен быть типа "Двоичные данные"
КонецФункции
Затем на клиенте выполним инициализацию документа:
&НаКлиенте
Процедура Печать_Договора()
// Создаем COM-объект на клиенте, где установлен Word
Попытка
Word = Новый COMОбъект("Word.Application");
Исключение
Сообщить("Microsoft Word не установлен на данном компьютере.");
Возврат;
КонецПопытки;
// Получаем двоичные данные макета с сервера
ДвоичныеДанныеМакета = ПолучитьМакетСервер("МойМакетWord");
// Создаем временный файл
ИмяФайла = ПолучитьИмяВременногоФайла("docx");
ДвоичныеДанныеМакета.Записать(ИмяФайла);
// Открываем документ как шаблон
ДокументWord = Word.Documents.Add(ИмяФайла);
Word.Visible = Истина;
ДокументWord.Activate();
// Дальнейшее заполнение закладок или поиск и замена текста
// ...
КонецПроцедуры
Современный стандарт разработки в 1С предполагает использование подсистемы "Печать" из состава БСП. Этот метод более надежен и позволяет гибко управлять областями документа, аналогично тому, как мы работаем с табличными документами 1С. В этом случае макет хранится как Двоичные данные, но внутри него размещаются специальные теги в фигурных скобках, например {НомерДоговора}.
Для работы нам понадобятся методы модуля УправлениеПечатьюКлиент или УправлениеПечатью. Проанализируем процесс инициализации:
// Инициализация макета
Макет = УправлениеПечатьюКлиент.ИнициализироватьМакетОфисногоДокумента(ДвоичныеДанныеМакета, "DOC", "МакетДоговора");
// Создание печатной формы
ПечатнаяФорма = УправлениеПечатьюКлиент.ИнициализироватьПечатнуюФорму("DOC", Неопределено, Макет);
// Получение области и заполнение параметров
Область = УправлениеПечатьюКлиент.ОбластьМакета(Макет, "Шапка");
ДанныеЗаполнения = Новый Структура("НомерДоговора, ДатаДоговора", "123", ТекущаяДата());
УправлениеПечатьюКлиент.ПрисоединитьОбластьИЗаполнитьПараметры(ПечатнаяФорма, Область, ДанныеЗаполнения);
Этот подход позволяет избежать прямого обращения к методам COM-объекта в прикладном коде, перекладывая рутину на стандартные функции библиотеки.
Часто возникает задача вставить один документ (например, приложение к договору) в середину другого. Если мы используем БСП, то можем вызывать метод ПрисоединитьОбласть последовательно. Рассмотрим, как это реализовать, если приложения хранятся в разных макетах:
ПечатнаяФорма.Проанализируем пример, когда нужно вставить специфический блок в зависимости от условий:
// Выводим основную часть
ОбластьШапка = УправлениеПечатью.ОбластьМакета(МакетОсновной, "Заголовок");
УправлениеПечатью.ПрисоединитьОбластьИЗаполнитьПараметры(ПечатнаяФорма, ОбластьШапка, СтруктураДанных);
// Если выбран определенный тариф, берем область из другого макета
Если Объект.Тариф = ПредопределенноеЗначение("Перечисление.Тарифы.Премиум") Тогда
МакетПриложения = ПолучитьМакет("ПриложениеПремиум");
ОписаниеОбластей = Новый Структура("БлокПриложения", "БлокПриложения");
УправлениеПечатью.ЗагрузитьОбластиИз МакетаОфисногоДокумента(МакетПриложения, ОписаниеОбластей);
ОбластьПриложения = УправлениеПечатью.ОбластьМакета(МакетПриложения, "БлокПриложения");
УправлениеПечатью.ПрисоединитьОбластьИЗаполнитьПараметры(ПечатнаяФорма, ОбластьПриложения, ДанныеТарифа);
КонецЕсли;
В некоторых случаях стандартных средств БСП может быть недостаточно, особенно если требуется динамическое изменение структуры таблиц. Документ .docx представляет собой ZIP-архив с XML-файлами. Мы можем программно изменять содержимое word/document.xml.
Посмотрим на пример из практики, когда нужно дублировать блоки текста в зависимости от коллекции данных:
// Сохраняем исходный текст XML области макета
ИсходныйТекстОбласти = Область.Текст;
Для Каждого СтрокаТовара Из Объект.Товары Цикл
// Восстанавливаем XML разметку для новой итерации
Область.Текст = ИсходныйТекстОбласти;
// Здесь можно выполнить поиск и замену в XML-строке программно
// Например, через СтрЗаменить или регулярные выражения
УправлениеПечатью.ПрисоединитьОбластьИЗаполнитьПараметры(ПечатнаяФорма, Область, СтрокаТовара, Ложь);
КонецЦикла;
Для удобства пользователей рекомендуется отказаться от хранения жестко заданных макетов в конфигураторе. Рассмотрим более гибкий вариант:
ШаблоныДокументов с реквизитом типа ХранилищеЗначения для хранения двоичных данных файла Word.ДвоичныеДанные = СправочникОбъект.ФайлШаблона.Получить();.Это позволит администраторам или юристам самостоятельно вносить правки в текст договоров, не привлекая программиста для изменения конфигурации. Кроме того, при использовании БСП и формата .docx, вы обеспечиваете частичную совместимость с Linux-серверами, так как работа с двоичными данными и XML не зависит от наличия COM-интерфейсов Windows.
Таким образом, переход на двоичные данные и механизмы БСП является наиболее правильным путем развития системы. Это не только решает проблему отсутствия Office на сервере, но и делает код более чистым и масштабируемым.