Форум 1С
Программистам, бухгалтерам, администраторам, пользователям
Задай вопрос - получи решение проблемы
08 дек 2022, 03:29

Создание и настройка макета WORD.

Автор TurboGetBoi, 13 окт 2022, 12:05

0 Пользователей и 1 гость просматривают эту тему.

TurboGetBoi

Добрый день всем, у меня есть пара макетов в ворде, в них мне нужно вывести данные получаемые из запроса. места для их заполнения обозначены в тексте по типу - *какаятопеременная*. Суть в том, что если я несколько раз укажу одну и туже переменную в разных местах шаблона она заполнить только первую из них остальные она проигнорирует и выведет на печать незаполненную строку.
Вот код моей функции с заполнением переменных:
код:
Функция ЗаполнениеДанныхРасторжения(ПараметрКоманды)

ДанныеРастожения = Новый Соответствие;
   
    ДанныеРастожения = Новый Соответствие;
        ДанныеРастожения.Вставить("*ОрганизацияПолное*",ПараметрКоманды.ДоговорКуплиПродажи.Организация.НаименованиеПолное);
        ДанныеРастожения.Вставить("*Дата*",Left(ПараметрКоманды.ДоговорКуплиПродажи.Дата,10));
        ДанныеРастожения.Вставить("*НомерДоговора*",ПараметрКоманды.ДоговорКуплиПродажи.Номер);
        ДанныеРастожения.Вставить("*ДатаДоговора*",ПараметрКоманды.ДоговорКуплиПродажи.Дата);
        ДанныеРастожения.Вставить("*ФИО*",Строка(Строка(ПараметрКоманды.ДоговорКуплиПродажи.ПодписантПокупатель.Фамилия) + " " +
        Строка(ПараметрКоманды.ДоговорКуплиПродажи.ПодписантПокупатель.Имя) + " " +
        Строка(ПараметрКоманды.ДоговорКуплиПродажи.ПодписантПокупатель.Отчество)));
       
КонецФункции

Кусок шаблона:

     Прошу расторгнуть договор купли-продажи № *НомерДоговора*, заключенный между мной и *ОрганизацияПолное*, и
     возвратить мне сумму внесенного задатка.
     Претензий к *ОрганизацияПолное*, в том числе в части исполнения обязательств по Договору, не имею.

Что я получаю на печати:

     Прошу расторгнуть договор купли-продажи № 0000000002, заключенный между мной и ИМЯКОНТОРЫ и
     возвратить мне сумму внесенного задатка.
     Претензий к *ОрганизацияПолное*, в том числе в части исполнения обязательств по Договору, не имею.

ПС:
Вероятно что-то нужно засунуть в цикл, но я ума не приложу что должно быть( :trhregerhg:  :trhregerhg:  :trhregerhg:

TurboGetBoi

Решено.

То что нужно было мне реализовать, находится здесь:

https://infostart.ru/1c/articles/488556/

Работа с MS Word из 1С "для самых маленьких"

Данная статья - попытка собрать сведения по работе (на начальном уровне) с MS Word в одном месте. На infostart.ru и других сайтах полно похожего материала, и при наличии должной усидчивости это все можно найти. Хотелось собрать основные моменты в одном месте.

Публикация - своего рода памятка, содержащая примеры кода для:

1. заполнение шаблона Word данными из 1С;
2. заполнение колонтитулов Word данными из 1С;
3. заполнение таблицы в Word данными из 1С;

Начало работы

В большинстве случаев перед нами ставится следующая задача:
Нужно открыть документ Word, заполненный данными из 1С.

Для этого нам нужно подготовить шаблон документа Word. Не путайте это с Word Template, специальные файлы Word, которые содержат настройки документов для многократного использования. Нам нужен обычный вордовский документ с расширениеми *.docx или *.doc. А далее поместить этот документ в макет с двоичными данными.


Попытка
//Получаем макет из двоичных данных
Шаблон = ПолучитьМакет(ДополнительныеПараметры.ВидДоговора);
ИмяФайла = ПолучитьИмяВременногоФайла(".docx");
Шаблон.Записать(ИмяФайла);
//Создаем COM-объект для работы с Word
ОбъектВорд = Новый COMОбъект("Word.Application");
ОбъектВорд.Documents.add(ИмяФайла);
//В Word можно открывать в одном приложении несколько документов, поэтому ОбъектВорд.Application.Documents - это коллекция открытых документов.
//В нашем случае документ открыт всегда один
ДокументВорд = ОбъектВорд.Application.Documents(1);
ДокументВорд.Activate();
Исключение Сообщить("Ошибка при запуске приложения "+ОписаниеОшибки());
КонецПопытки;
//Разумеется, получение COM-объекта нужно поместить в попытку. Мало ли, что-то пойдет не так.

Читатель может справедливо заметить, что используется модальный вызов, и погрозить автору пальцем. И будет прав.


//Создадим структуру параметров документа
ПараметрыДокумента = ПодготовитьСтрукутруПараметров();
//Заполним структуру параметров документа
ЗаполнитьСтруктуруПараметров(ПараметрыДокумента);

Далее я обычно создаю структуру полей, которые будут заполняться в шаблоне. Такой подход позволяет унифицировать процедуру заполнения шаблона, а также упростить последующее его изменение.

Углубимся немножко в принципы работы Word...

Каждый документ Word разделен на разделы, которые состоят из страниц.

Для каждого раздела есть возможность создавать свою нумерацию элементов, уникальные колонтитулы и настройки параметров страницы. Так, например, чтобы повернуть одну из страниц (вывести на печать как альбомную), нужно создать под неё отдельный раздел.


Каждая страница Word разделена на несколько областей:

  • Верхний колонтитул
  • Основной текст
  • Нижний колонтитул

Нужно заметить, что в каждом разделе может быть уникальный колонтитул для первой страницы.


//Объект, содержит весь основный текст из всех разделов
ДокументВорд.Content
//Объект содержит коллекцию разделов документа
ДокументВорд.Sections
//В каждом разделе есть своя коллекция для верхних колонтитулов
ДокументВорд.Sections(1).Headers
//И своя коллекция для нижних колонтитулов
ДокументВорд.Sections(1).Footers
//При этом, если стоит галочка "Уникальный колонтитул для первой страницы", то коллекции Headers и Footers будут содержать два элемента

Заполнение пользовательских параметров

При обращении к этим коллекциям мы можем выполнять в них поиск и получать встроенные объекты, например, таблицы.

Теперь мы более-менее поняли, как обращаться к областям Word, можем в них пошуровать и выполнить замену наших параметров:


//Переберем все параметры и заменим их в документе
Для каждого Параметр Из ПараметрыДокумента Цикл
ВыполнитьЗамену(ДокументВорд.Content, Параметр.Ключ, Параметр.Значение);
//Ищим вхождения параметра в верхнем колонтитуле
ВыполнитьЗамену(ДокументВорд.Sections(1).Headers.Item(1).Range(), Параметр.Ключ, Параметр.Значение);
//Ищим вхождения параметра в нижнем колонтитуле первой и последующих страниц
ВыполнитьЗамену(ДокументВорд.Sections(1).Footers.Item(1).Range(), Параметр.Ключ, Параметр.Значение);
ВыполнитьЗамену(ДокументВорд.Sections(1).Footers.Item(2).Range(), Параметр.Ключ, Параметр.Значение);
КонецЦикла;

//Выполнить поиск и замену Функция
ВыполнитьЗамену(знач Object, Параметр, Значение)
Object.Find.Execute(Параметр,,,,,,,,,Значение,2)
КонецФункции

Рассмотри подробнее метод Execute. Его параметры идентичны диалоговуму окну при замене/поиске непоседресвенно из MS Word:

А вот и основные параметры (вольный перевод справки MSDN):

  1. Искомый текст - Строка - Текст для замены. Текст может содержать специальные параметры. Например, ^p - абзац, ^t - табуляция
  2. Чувствительность к регистру - Булево - Если истина, то поиск будет осуществляться с учетом регистра
  3. Слова целиком - Булево - Если истина, то ищутся слова целиком. Вхождение слов не учитываются. Например, при поиске слова дом будет пропущено слово домашний
  4. Использовать подстановочные знаки - Булево - Если истина, то используются встроенные регулярные выражения.
  5. Искать похожие - Булево - Если истина, то результат поиска будет содержать похожие слова
  6. Искать все формы - Булево - Если истина, то результат поиска будет содержать различные формы слов.
  7. Поиск сначала - Булево - Если истина, то будет осуществляться с начала до конца документа
  8. Охват - WdFindWrap - Опредяляет направление поиска
  9. Формат - Format - Формат искомого текста
  10. Строка замены - Строка - Строка, на которую будет заменен исходный текст
  11. Количество замен - WdReplace - Определяет сколько раз выполнять замену
  12. и т.д.

WdReplace - Constant Value:
wdReplaceAll 2
wdReplaceNone 0
wdReplaceOne 1

Данный метод не позволяет получить "Строка замены" как выделенную область, но он работает где-то в 10 раз медленнее. Для получения выделенной области можно воспользоваться немножко откорректированной типовой функцией:


//УправлениеПечатьюMSWordКлиент c незначительными изменениями для конфигурации УПП 1.3
Функция ВыполнитьЗамену(знач Object, Параметр, Значение)
СтрокаПоиска = "[" + Параметр + "]";
СтрокаЗамены = Строка(Значение);
//Необходимо выделить областей, в которой мы осуществляем замену
Object.Select();
//Получаем выделенную область
Selection = Object.Application.Selection;
//Найдем все вхождения параметра и заменим его на нужное нам значение
FindObject = Selection.Find;
FindObject.ClearFormatting();
Пока FindObject.Execute(СтрокаПоиска) Цикл
Если ПустаяСтрока(СтрокаЗамены) Тогда
Selection.Delete();
Иначе
Selection.TypeText(СтрокаЗамены);
КонецЕсли;
КонецЦикла;
//Отменим выделение
Selection.Collapse();
КонецФункции

Уже получив выделенную область можно отредактировать стиль текста, шрифт и т.д.


//Редактирование шрифта
Selection.Font
//Редактирование цвета
Selection.HighlightColorIndex

Также есть второй подход, использующий такой объект Word, как поля. Мне он не очень нравится, т.к. в больших документах, порядка 100 страниц, эти поля начинают глючить (исчезать, не подставлять нужные значения) и прочая ерунда. Ну по крайней мере в Word 2007. Но я его все равно приведу:

При подготовке шаблона в тело документа необходимо навставлять полей с типом DOCVARIABLE (можно вставлять горячими клавишими Ctrl+F9).

Доступ к таким полям можно получить следующим нехитрым образом:


ДокументВорд.Variables.Item(НазваниеПараметра).Values

Заполнение таблиц по шаблону

Итак, мы заполнили параметры в основном тексте документа, заменили параметры в колонтитулах, но у нас еще есть одна неприятность - нужно заполнить таблицу.

Подход, описанный ниже, годится только для таблиц с заранее известным форматом. Т.е. мы можем как угодно отформатировать таблицу и её строки изначально. Но потом изменять довольно-таки проблематично.

К таблицам можно получить доступ через области документа.


//Получаем доступ к первой таблице в основном тексте
Таблица = ДокументВорд.Content.Tables(1)

Далее, получив таблицу, мы работаем с ней по привычной схеме - строки, столбцы.

Для задания форматирования легче в шаблоне создать таблицу с пустой первой строкой, которую мы в последующем удалим.


//Данные для заполнения
ПараметрыТЧ = ПараметрыДокумента.ПриложениеТЧ;
//Нужно оставить шапку и первую строку нетронутой Итератор = 2;
Таблица = ДокументВорд.Content.Tables(3);
Для каждого Строка Из ПараметрыТЧ Цикл
//По умолчанию добавляет строку выше первой
Таблица.Rows.Add();
ЗаполнитьСтрокуТаблицы(Таблица, Итератор, Строка,"ПП,НоменклатураНаименование,ЕдИзмерения,ЦенаСтрокой",ПараметрыТЧ );
Итератор = Итератор + 1;
КонецЦикла;
//Структура шаблонов содержит Наименование колонок и их порядок
Процедура ЗаполнитьСтрокуТаблицы(Таблица, НомерСтроки, ЗначениеЗаполнения, СтруктураШаблонов,ТаблицаЗначений)
МассивСтрок = ОбщегоНазначения.РазложитьСтрокуВМассивПодстрок(СтруктураШаблонов,",");
Итератор = 1;
Для каждого Строка Из МассивСтрок Цикл
Если ТаблицаЗначений.Колонки.Найти(Строка) = Неопределено И Строка <> "ПП" Тогда
Итератор = Итератор + 1;
Продолжить;
//Не забываем, что Шапка тоже строка, а при нумерации нам нужно её исключить
ИначеЕсли Строка = "ПП" Тогда
Таблица.Cell(НомерСтроки, Итератор).Range().Text = Строка(НомерСтроки-1);
Итератор = Итератор + 1;
Продолжить;
КонецЕсли;
Таблица.Cell(НомерСтроки, Итератор).Range().Text = Строка(ЗначениеЗаполнения[Строка]);
Итератор = Итератор + 1;
КонецЦикла;
КонецПроцедуры

Вот, в принципе, и все. Основные вопросы, возникающие при работе с Word, я постарался осветить. Надеюсь, данный обзор поможет вам в работе =)

Спасибо за советы и комментарии:
v3rter, monkbest

Критика только приветствуется. Чем больше замечаний, тем лучше будет гайд =)




Теги: Word макет docx 

Похожие темы (5)

Рейтинг@Mail.ru Rambler's Top100

Поиск