При формировании печатных документов в формате MS Word из 1С разработчики часто сталкиваются со следующей проблемой: метод поиска и замены Find.Execute в OLE-объекте Word выводит ошибку или сбой, если длина подставляемого текста превышает 255 символов. В этой статье мы разберем причину этого ограничения и рассмотрим несколько эффективных способов его обхода.
В объектной модели Microsoft Word (VBA/COM) параметр ReplaceWith метода Find.Execute имеет жесткое внутреннее ограничение на длину строки в 255 символов. Если передать в него значение большего объема, система возвращает синтаксическую ошибку либо зацикливает процесс выполнения.
Попытки разбить строку на части и последовательно вызывать метод Find.Execute в цикле часто приводят к рекурсивному зависанию и некорректной замене. Рассмотрим проверенные способы, которые позволяют полностью снять это ограничение.
Наиболее простое и надежное решение — использовать закладки Word вместо обычного поиска текстовых меток. В шаблоне документа Word в месте, куда необходимо вывести значение, устанавливается закладка. Из 1С мы обращаемся напрямую к этой закладке и присваиваем текст ее диапазону.
Разберем по шагам порядок действий:
Достижения).Bookmarks.Рассмотрим пример кода 1С:
КодТекста = ЭтотОбъект.ДопГлавныеДостижения;
ИмяЗакладки = "Достижения";
Если Документ.Bookmarks.Exists(ИмяЗакладки) Тогда
Закладка = Документ.Bookmarks(ИмяЗакладки);
Закладка.Range.Text = КодТекста;
КонецЕсли;
При прямом присвоении значения свойству Range.Text ограничение в 255 символов не действует, и весь текст подставляется целиком.
Если менять шаблон документа и создавать закладки нежелательно, можно сохранить привычные текстовые метки (например, {v8 Достижения}), но изменить логику работы метода Find.Execute. Вместо замены текста внутри самого метода мы выполняем только поиск метки, после чего меняем текст найденной области.
Разберем пример реализации этого подхода:
ИскомаяМетка = "{v8 Достижения}";
ДлинныйТекст = ЭтотОбъект.ДопГлавныеДостижения;
Поиск = Документ.Content.Find;
Поиск.ClearFormatting();
Поиск.Text = ИскомаяМетка;
// Выполняем поиск без автоматической замены
Пока Поиск.Execute() Цикл
// Заменяем текст непосредственно в найденном диапазоне
Поиск.Parent.Text = ДлинныйТекст;
КонецЦикла;
В данном случае свойство Parent объекта поиска возвращает диапазон Range, для которого прямое присвоение текста также снимает лимит длины.
Другой удобный вариант — использование полей переменных документа Word.
DOCVARIABLE ИмяПеременной.Variables объекта Document.Проанализируем пример кода:
Документ.Variables("Достижения").Value = ЭтотОбъект.ДопГлавныеДостижения;
Документ.Fields.Update();
Коллекция Variables не имеет ограничения на 255 символов и отлично подходит для передачи больших объемов текста.
Если заполнение документов выполняется на сервере Linux или на клиенте без установленного Microsoft Office, работы через COM/OLE недоступны. В таком случае файл .docx можно обработать как обычный ZIP-архив.
Выясним алгоритм работы:
.docx файл с помощью объекта ЧтениеZipФайла.word/document.xml.СтрЗаменить.ЗаписьZipФайла.Этот способ является полностью кроссплатформенным, работает существенно быстрее COM-соединения и не зависит от наличия сторонних программ на сервере.