При выгрузке печатных форм и отчетов во внешние шаблоны табличных процессоров OpenOffice или LibreOffice Calc часто возникает задача заменить специальные текстовые метки (например, <Итого> или <НомерДокумента>) на актуальные данные из базы 1С. В отличие от Microsoft Excel, где можно напрямую обратиться к методу Find диапазона ячеек, в OpenOffice используется объектная модель UNO API, работающая через специальные дескрипторы поиска и замены.
Разберем подробно, как реализовать замену данных как во всем документе, так и внутри конкретного именованного диапазона ячеек.
Если требуется выполнить автозамену шаблонных меток по всей книге или активному листу без ограничения областью, используется метод createReplaceDescriptor. Проанализируем пример кода:
// Открываем документ через UNO сервис Desktop
ТекстовыйПроцессор = Desktop.LoadComponentFromURL(ПреобразоватьВURL(ИмяФайла), "_blank", 0, Args);
// Создаем дескриптор замены
Replace = ТекстовыйПроцессор.createReplaceDescriptor();
// Заменяем ключевые поля на нужные значения
Для Каждого Стр Из ТаблицаЗамен Цикл
Replace.SearchString = Стр.Что;
Replace.ReplaceString = Стр.Чем;
ТекстовыйПроцессор.replaceAll(Replace);
КонецЦикла;
Рассмотрим особенности этого механизма:
createReplaceDescriptor() создает специализированный объект, содержащий параметры поиска.SearchString и ReplaceString принимают исходную подстроку и текст для подстановки.replaceAll() производит пакетную замену всех вхождений в документе.Объект диапазона ячеек (CellRange), полученный через метод листа getCellRangeByName, также реализует интерфейс XReplaceable. Это позволяет вызывать дескриптор замены непосредственно для ограниченной области таблицы, не затрагивая остальные ячейки листа.
Посмотрим на пример заполнения области шапки или подвала отчета:
ШапкаОтчета = Sheet.getCellRangeByName("Шапка");
Дескриптор = ШапкаОтчета.createReplaceDescriptor();
Дескриптор.SearchString = "<Итого>";
Дескриптор.ReplaceString = Формат(Список.Итог("Сумма"), "ЧГ=0");
ШапкаОтчета.replaceAll(Дескриптор);
Метод replaceAll всегда вставляет строковые данные (тип String). Если в ячейку необходимо передать число для последующего расчета по формулам Calc, строковая замена не подойдет, так как значение будет распознано табличным процессором как текст. В этом случае требуется найти нужную ячейку и записать в нее число через метод setValue.
Разберем по шагам, как выполнить точечный поиск и запись числового значения:
// Получаем диапазон
ШапкаОтчета = Sheet.getCellRangeByName("Подвал");
// Создаем дескриптор поиска
ДескрипторПоиска = ШапкаОтчета.createSearchDescriptor();
ДескрипторПоиска.SearchString = "<Итого>";
// Ищем первое вхождение ячейки с шаблоном
НайденнаяЯчейка = ШапкаОтчета.findFirst(ДескрипторПоиска);
Если НайденнаяЯчейка <> Неопределено Тогда
НайденнаяЯчейка.setValue(Список.Итог("Сумма"));
КонецЕсли;
Для более точного сопоставления шаблонов дескрипторы createSearchDescriptor и createReplaceDescriptor поддерживают настройку управляющих свойств:
Важно: При работе через COM-соединение с OpenOffice (com.sun.star.ServiceManager) следует строго соблюдать регистр в названиях методов и свойств API (например, createReplaceDescriptor, findFirst, setValue).