Объектная модель Microsoft Word

Microsoft Word предоставляет богатую и мощную модель объектов, обеспечивающую высокую степень его программируемости. Надстройка Microsoft Visual Studio Tools for Office позволяет разработчикам обращаться к объектам, поддерживаемым объектной моделью Word, на любом .NET-совместимом языке, например Microsoft Visual Basic .NET или Microsoft Visual C#. Богатейшая функциональность Word полностью доступна из пользовательского кода.

1. Сущность объектной модели Word. Ее основные компоненты: документы, шаблоны

На первый взгляд, объектная модель Word весьма запутанна, так как поначалу кажется, что многие объекты в ее иерархии перекрываются. Например, объекты Document и Selection являются членами объекта Application, но в то же время объект Document — член объекта Selection. Вдобавок и Document, и Selection содержат объекты Bookmarks и Range, как видно на рисунке 1. В следующих разделах кратко рассмотрены объекты верхнего уровня, включая их взаимодействие друг с другом.

элементы объектной библиотеки Word

Рисунок 1 – Основные элементы объектной библиотеки Word

Для корректной работы с объектной моделью Word следует подключить соответствущую объектную ссылку в среде Visual Studio, а также требуемое пространство имен, например, так:

using Word = Microsoft.Office.Interop.Word;

Объект Application

Word-объект Application представляет само приложение Word. Через него можно обращаться к любым другим объектам и наборам (collections), предоставляемым Word, а также к методам и свойствам самого объекта Application.

Если приложение Word уже запущено, объект Application создается автоматически. При работе в среде Visual Studio .NET, можно использовать переменную ThisApplication, которая определяет текущий экземпляр приложения Word.

В случае же, если приложение Word на компьютере не запущено, необходимо явно создать объектную переменную для Wordобъекта Application:

Word.Application appWord = new Word.Application();

Объект Document

Объект Document занимает центральное место в программировании с использованием объектной модели Word. В тех случаях, когда создается новый документ или открывается существующий, генерируется новый объект Document, который добавляется в Word-набор Documents.

Наборы объекта Document по своему составу и назначению соответствуют элементам документов Word:

Characters (символы); Words (слова);

Sentences (предложения); Paragraphs (абзацы); Sections (разделы);

Headers/Footers (верхние и нижние колонтитулы).

На объект Document можно получить ссылку по индексу как на элемент набора Documents. Как и все наборы в Word, индексы отсчитываются от 1. Например, можно присвоить объектной переменной ссылку на первый объект Document в наборе Documents:

Word.Document doc = (Word.Document) ThisApplication. Documents;

Кроме того, на документ можно ссылаться по имени, что обычно удобнее, если нужно работать с определенным документом.

Word.Document doc = (Word.Document) ThisApplication.Documents["MyDoc.doc"];

Если необходимо сослаться на активный документ (документ, находящийся в фокусе), можно использовать свойство ActiveDocument объекта Application либо ссылку ThisDocument. В следующей строке кода показан пример получения имени активного документа:

String str = ThisDocument.Name;

2. Создание, открытие и сохранение документов

Создание нового документа Word

При создании нового документа Word он будет добавлен в набор Documents объекта Application, где хранятся все открытые документы. Для программного создания нового документа следует вызвать метод Add. Это равносильно щелчку кнопки Создать в приложении Word.

// Создание нового документа на основе шаблона Normal.dot Object template = Type.Missing;

Object newTemplate = Type.Missing; Object documentType = Type.Missing; Object visible = Type.Missing; ThisApplication.Documents.Add(ref template, ref newTemplate, ref documentType, ref visible);

Данный метод принимает до четырех необязательных параметров: имя шаблона, имя нового шаблона, тип документа и признак видимости нового документа. Однако в большинстве случае можно оставить им значения по умолчанию. В языке C# для этого нужно передать по ссылке значение Type.Missing.

Необязательный аргумент Template метода Add служит для создания нового документа на основе шаблона, отличного от Normal.dot. В этом случае следует указать путь и имя файла данного шаблона.

// Создание нового документа на основе собственного шаблона Object template = @"C:\Test\MyTemplate.Dot";

Object newTemplate = Type.Missing; Object documentType = Type.Missing; Object visible = Type.Missing; ThisApplication.Documents.Add(ref template, ref newTemplate, ref documentType, ref visible);

Открытие существующего документа

Для этого предназначен метод Open. Его базовый синтаксис предельно прост: необходимо просто указать полный путь и имя файла. Этот метод также принимает ряд необязательных аргументов, например пароль или флаг, сообщающий, что документ должен быть только для чтения. Разумеется, в коде на C# нужно передавать все параметры, но реальное значение требуется только для параметра FileName.

Сохранение документов

Сохранять и закрывать документы можно несколькими способами – в зависимости от того, какого результата нужно добиться. Для сохранения и закрытия документа следует вызвать методы Save и Close соответственно. Они дают разные результаты в зависимости от варианта их использования. Если они применяются к объекту Document, их действие распространяется только на соответствующий документ. А если они применяются к набору Documents – на все открытые документы.

При обычном вызове метода Save для набора Documents пользователю выводится запрос на сохранение всех файлов.

Object noPrompt = Type.Missing; Object originalFormat = Type.Missing;

ThisApplication.Documents.Save(ref noPrompt, ref originalFormat);

Если же в данном коде параметру noPrompt присвоить значение true, то все открытые документы будут сохранены без участия пользователя

Рассмотрим варианты сохранения единственного документа. Следующий фрагмент кода показывает два варианта сохранения активного документа:

// Сохраняем активный документ так… ThisDocument.Save();

// …или так ThisApplication.ActiveDocument.Save();

Если точно не известно, активен ли сохраняемый документ, лучше ссылаться на него по имени. Например:

Object file = "MyNewDocument.docx"; ThisApplication.Documents.get_Item(ref file).Save();

Метод SaveAs позволяет сохранить документ под другим именем файла. Он требует передачи лишь нового имени файла, а остальные аргументы необязательны.

Закрытие документов

Метод Close позволяет не только закрывать документы, но и сохранять их. Закрывать документы можно индивидуально или все сразу.

Применительно к набору Documents метод Close работает аналогично методу Save. При вызове без аргументов он предлагает пользователю сохранить изменения в любых несохраненных документах.

Object saveChanges = Type.Missing; Object originalFormat = Type.Missing; Object routeDocument = Type.Missing;

ThisApplication.Documents.Close(ref saveChanges, ref originalFormat, ref routeDocument);

Как и Save, метод Close принимает необязательный аргумент SaveChanges, у которого есть перечислимое WdSaveOptions с тремя значениями: wdDoNotSaveChanges, wdSaveChanges и wdPromptToSaveChanges.

Следует обратить внимание, что закрытие всех открытых документов не приводит к закрытию приложения Word. Его можно завершить явным образом либо вызовом метода Quit объекта Application

Рассмотрим варианты закрытия единственного документа. Фрагменты кода, приведенные ниже, иллюстрируют, как закрыть активный документ без сохранения изменений и как закрыть док умент «MyNewDocument.docx», автоматически сохранив изменения:

// Закрываем активный документ без сохранения изменений Object saveChanges = Word.WdSaveOptions.wdDoNotSaveChanges; Object originalFormat = Type.Missing;

Object routeDocument = Type.Missing; ThisDocument.Close(ref saveChanges, ref originalFormat, ref routeDocument);

// Закрываем MyNewDocument и "молча" сохраняем изменения Object name = "MyNewDocument.docx";

saveChanges = Word.WdSaveOptions.wdSaveChanges;

Word.Document doc = ThisApplication.Documents.get_Item(ref name);

doc.Close(ref saveChanges, ref originalFormat, ref routeDocument);

3. Вывод текстовой информации, поиск и замена в тексте

Объект Selection

Объект Selection представляет текущую выделенную область документа Word. При выполнении какой-либо операции в пользовательском интерфейсе Word происходит выделение текста, а затем применение нужных параметров форматирования. Аналогичным образом используется в коде объект Selection: определяется выделенный фрагмент и выполняется с ним требуемая операция. Этот объект позволяет выделять, форматировать, манипулировать и печатать текст в документе.

Объект Selection всегда присутствует в документе. Если ничего не выделено, он представляет курсор ввода. Поэтому, прежде чем пытаться выполнять какие-то действия с содержимым документа, важно понять, из чего состоит объект Selection.

Навигация и выделение текста

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

Методы HomeKey и EndKey

Применение этих методов изменяет размеры выделенного фрагмента:

HomeKey([Unit], [Extend]) – действует аналогично нажатию клавиши Home на клавиатуре;

EndKey([Unit], [Extend]) – действует аналогично нажатию клавиши End на клавиатуре.

Для аргумента Unit используется одно из значений перечислимого WdUnits (таблица 1).

Таблица 1 – Значения перечисления WdUnits методов HomeKey и EndKey

Значение Единица перехода

(переход в начало или конец…)

Примечание
wdLine Строка Значение по умолчанию
wdStory Документ
wdColumn Столбец Допустимо только для таблиц
wdRow Строка таблицы Допустимо только для таблиц

В аргументе Extend указывается одно из значений перечислимого WdMovementType:

wdMove Перемещает выделенный фрагмент. При использовании с wdLine перемещает курсор ввода в начало или конец строки, а при использовании с wdStory — в начало или конец документа.

wdExtend Расширяет выделенный фрагмент. Конечный результат заключается в том, что новый объект Selection состоит из диапазона от курсора ввода до конечной позиции. Если начальная позиция не соответствует местонахождению курсора ввода, результат варьируется в зависимости от параметров, переданных методу. Например, если в данный момент выделена строка и метод HomeKey вызван с перечислимыми значениями wdStory и

wdExtend, то строка не включается в новый выделенный фрагмент. Если метод EndKey вызван с перечислимыми значениями wdStory и wdExtend, строка включается в выделенный фрагмент. Такое поведение отражает действие комбинацией клавиш Ctrl+Shift+Home и Ctrl+Shift+End соответственно.

Следующий код перемещает курсор ввода в начало документа вызовом метода HomeKey с wdStory и wdMove. Затем выделение расширяется до конца документа вызовом EndKey с wdExtend:

// Помещаем курсор ввода в начало документа Object unit = Word.WdUnits.wdStory;

Object extend = Word.WdMovementType.wdMove; ThisApplication.Selection.HomeKey(ref unit, ref extend);

// Выделяем текст от курсора ввода до конца документа unit = Word.WdUnits.wdStory;

extend = Word.WdMovementType.wdExtend; ThisApplication.Selection.EndKey(ref unit, ref extend);

Методы, имитирующие действие клавиш со стрелками

Выделенный фрагмент можно изменять также вызовом методов, перечисленных ниже. Каждый из них принимает аргумент Count, который определяет, на сколько единиц следует переместить выделение в данном направлении. Эти методы имитируют действие клавиш со стрелками.

MoveLeft([Unit], [Count], [Extend]);

MoveRight([Unit], [Count], [Extend]);

MoveUp([Unit], [Count], [Extend]);

MoveDown([Unit], [Count], [Extend]).

Возможные значения аргумента Extend приведены в таблице 2.

Метод Move

Метод Move свертывает указанный диапазон или выделенный фрагмент, а затем перемещает свернутый объект на заданное количество единиц. Следующий код свертывает исходный объект Selection и перемещает его на три слова вперед. В итоге курсор ввода оказывается в начале третьего слова:

Obiect unit = Word.WdUnits.wdWord; Object count = 3;

ThisApplication.Selection.Move(ref unit, ref count);

Таблица 2 – Возможные значения аргумента Extend

Значение Перемещение

в единицах…

Применимо

для методов

Примечание
wdCharacter символов MoveLeft,

MoveRight

Значение по умолчанию
wdWord слов
wdCell ячеек Допустимо только для таблиц
wdSentence предложений
wdLine строк MoveUp,

MoveDown

Значение по умолчанию
wdParagraph абзацев
wdWindow окна
wdScreen экрана

Вставка текста

Самый простой способ вставить текст в документ – вызвать метод TypeText объекта Selection. Поведение TypeText зависит от режима вставки текста.

Объект Range

Объект Range представляет непрерывную (последовательную) область в документе и определяется позициями начального и к онечного символов. В одном документе можно определить сразу несколько таких объектов. Ниже перечислены основные характеристики объекта Range:

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

У объекта Range много компонентов, общих с объектом Selection. Основное различие между ними в том, что Selection всегда возвращает ссылку на фрагмент, выделенный в пользовательском интерфейсе Word, а Range позволяет работать с текстом без визуального выделения.

Определение и выделение диапазона

В документе можно определить диапазон вызовом метода Range объекта Document с передачей начального и конечного значений. Следующий код создает новый объект Range, который включает первые семь символов в активном документе, в том числе непечатаемые знаки. Далее он обращается к методу Select объекта Range, чтобы выделить подсветкой полученный диапазон. Если опустить последнюю строку кода, объект Range будет невидим в пользовательском интерфейсе Word, но им все равно можно будет манипулировать программным способом.

Object start = 0; Object end = 7;

Word.Range rng = ThisDocument.Range(ref start, ref end); rng.Select();

Если нужно выделить весь документ, используется метод Range без параметров.

С помощью свойства Content объекта Document можно определить диапазон, охватывающий основную область документа (document’s main story), т. е. его содержимое без колонтитулов и других вспомогательных элементов:

Word.Range rng = ThisDocument.Content

Вставка текста

Свойство Text объекта Range позволяет вставлять или заменять текст в документе. Следующий фрагмент кода задает диапазон, который представляет собой курсор ввода в начале документа, и вставляет текст « new Text » (с пробелами) в позицию курсора ввода. Затем код выделяет подсветкой диапазон, включающий вставленный текст.

string str = " new Text "; Object start = 0;

Object end = 0;

Word.Range rng = ThisDocument.Range(ref start, ref end); rng.Text = str;

rng.Select();

Объект Bookmark

Объект Bookmark (закладка) аналогичен объекту Range в том смысле, что представляет непрерывную область в документе и тоже имеет начальную и конечную позиции. Закладки можно использовать, чтобы помечать какое-либо место в документе, или как контейнер текста в документе. Объект Bookmark может охватывать что угодно – только курсор ввода или весь документ. В документе можно определить несколько закладок.

Следующие характеристики Bookmark отличают его от объекта Range:

  • объекту Bookmark можно присваивать имя;
  • он сохраняется вместе с документом и не уничтожается по завершении породившего его кода или после закрытия документа;
  • по умолчанию он скрыт, но его можно сделать видимым, установив свойство ShowBookmarks объекта View в True.

Поиск и замена текста

Объект типа Find содержится в объектах Selection и Range, поэтому обращаться к нему можно через любой из них.

Если для поиска текста используется объект Selection, любые указанные критерии поиска применяются только к выделенному в данный момент тексту. Однако, если Selection включает лишь курсор ввода, тогда поиск ведется по всему документу.

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

Существует несколько программных способов поиска и замены текста. В типичном варианте объект Find используется для перебора всего документа в поисках нужного текста, параметров форматирования или стиля. Если надо заменить любой из найденных элементов, используется свойство Replacement объекта Find. Оба объекта – Find и Replacement – предоставляют метод ClearFormatting. При выполнении операции поиска и замены следует вызывать методы ClearFormatting обоих объектов. Иначе можно закончить заменой текста с непредсказуемыми параметрами форматирования.

Для замены каждого найденного элемента применяется метод Execute. Он принимает перечислимое WdReplace, в котором определено три значения:

  • wdReplaceAll – заменять всех найденные элементы;
  • wdReplaceNone – не заменять найденные элементы;
  • wdReplaceOne – заменить только первый элемент.

Печать документов

В объектную модель Word встроена богатая функциональность для поддержки печати. С ее помощью очень легко распечатывать целые документы или их части.

Если необходимо вывести документ в режиме просмотра перед печатью, следует установить свойство PrintPreview документа в True:

ThisDocument.PrintPreview = true;

С помощью метода PrintOut осуществляется посылка документа или его части на принтер. Метод можно вызывать из объекта Application или Document.

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

4. Работа с таблицами

Создание таблиц в Word

Набор Tables является компонентом объектов Document, Selection и Range, а это значит, что можно создавать таблицы в любом из этих объектов. Для добавления таблицы к заданному диапазону можно использовать метод Add. Следующий код добавляет таблицу из трех строк и четырех столбцов в начало активного документа:

Object start = 0; Object end = 0;

Word.Range rng = ThisDocument.Range(ref start, ref end);

Object defaultTableBehavior = Type.Missing; Object autoFitBehavior = Type.Missing;

ThisDocument.Tables.Add(rng, 3, 4, ref defaultTableBehavior, ref autoFitBehavior);

Работа с объектом Table

При создании таблицы она автоматически добавляется в набор Tables объекта Document, после чего на нее можно ссылаться по индексу:

Word.Table tbl = ThisDocument.Tables[1];

У каждого объекта Table есть свойство Range, которое позволяет напрямую задавать атрибуты форматирования, и свойство Style для применения одного из встроенных стилей к таблице:

Word.Table tbl = ThisDocument.Tables[1]; tbl.Range.Font.Size = 8;

Object style = "Сетка таблицы1"; tbl.set_Style(ref style);

Набор Cells

Каждый объект Table включает набор Cells, где индивидуальные объекты Cell представляют ячейки таблицы. Следующий код ссылается на ячейку, расположенную на пересечении первой строки с первым столбцом, а затем добавляет в нее текст и форматирует ее:

Word.Range rng = ThisDocument.Tables[1].Cell(1, 1).Range; rng.Text = "Name";

rng.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphRight;

Строки и столбцы

Ячейки в таблице организованы в строки и столбцы. Чтобы добавить в таблицу новую строку, используется метод Add. Единственным необязательным параметром является номер строки, перед которой нужно добавить новую. По умолчанию строка добавляется в конец таблицы.

Word.Table tbl = ThisDocument.Tables[1]; Object beforeRow = Type.Missing; tbl.Rows.Add(ref beforeRow);

Хотя число столбцов обычно определяется при создании таблицы, столбцы можно добавлять методом Add и после ее создания.

Следующий код вставляет в таблицу новый столбец перед первым существующим столбцом, а затем использует метод DistributeWidth, чтобы задать всем столбцам одинаковую ширину:

Word.Table tbl = ThisDocument.Tables[1]; Object beforeColumn = tbl.Columns[1]; tbl.Columns.Add(ref beforeColumn); tbl.Columns.DistributeWidth();

5. Практическое задание. Использование объектной модели Word в бизнес-приложениях

Задание. Дополним функциональность приложения «Телефонный справочник» возможностью генерации различных документов. Предположим, что программа должна формировать в Word приглашение на какое-то событие (день рождения, свадьбу и т. п.) для выбранного из БД человека. Создадим документ, позволяющий передавать в Word информацию о людях, имеющих более одного номера телефона. Данные должны будут отображаться в виде таблицы из трех столбцов: порядковый номер строки, ФИО человека, номер его телефона

5.1. Подключение к приложению объектной модели Word

Чтобы использовать объектную модель Word, в приложение нужно добавить соответствующие ссылки. Выделите в окне Обозреватель решений папку References и выберите в контекстном меню пункт Добавить ссылку… (рисунок 1). Переключитесь на вкладку COM и выберите в ней Microsoft Word 14.0 Object Library (или другую версию).

Добавление ссылки на объектную модель Word

Рисунок 1 – Добавление ссылки на объектную модель Word

5.2. Создание приглашения на событие на основе шаблона

В качестве шаблона, на основе которого будет формироваться документ, будет использоваться файл «приглашение.docx», внешний вид которого приведен на рисунке 2. Создайте этот файл и поместите его в папку docs в каталоге, где находится .exe-файл приложения (папку docs нужно создать самим).

Внешний вид шаблона документа

Рисунок 2 – Внешний вид шаблона документа

Как видно, данный шаблон содержит в себе так называемые метки, заключенные в угловые скобки (<FIO>, <Holiday> и др.).

В дальнейшем при формировании документа эти метки будут заменяться конкретными значениями.

Значение метки <FIO> будет браться из базы данных, т. е. приглашение будет формироваться для выбранного в таблице человека. А данные для всех остальных меток (наименование, дата, время и место проведения мероприятия) должны вводиться в программе отдельно. Это будет делаться в отдельном окне.

Добавьте в проект новую форму Form2. Ее внешний вид показан на рисунке 3.

Форма ввода исходных данных для приглашения

Рисунок 3 – Форма ввода исходных данных для приглашения

Для ввода даты проведения мероприятия использован компонент DateTimePicker, а для ввода времени – компонент MaskedTextBox с настроенным свойством Mask.

Для кнопок OK и Отмена установлено свойство DialogResult в значения OK и Cancel соответственно. После этого никаких дополнительных обработчиков для этих кнопок писать не требуется.

Всем компонентам для ввода данных нужно задать свойство Modifiers как Public, чтобы их значения можно было передавать в главную форму, где и будет формироваться документ.

Дальнейшая работа будет производиться с главной формой программы. Подключите в нее пространство имен Microsoft.Office.Interop.Word, содержащее в себе ядро объектной модели Word:

using Microsoft.Office.Interop.Word;

Для работы с Word нам понадобятся объекты, представляющие приложение и документ Word. Объявите их в классе формы следующим образом:

Microsoft.Office.Interop.Word.Application wordApp; Microsoft.Office.Interop.Word.Document wordDoc;

Для формирования документов будут использоваться несколько дополнительных функций. Первая из них, OpenDocument, предназначена для создания нового документа Word на основе заданного шаблона. Имя файла шаблона передается функции в качестве параметра. Текст метода:

private void OpenDocument(string FileName)

{

//открываем Word wordApp = new

Microsoft.Office.Interop.Word.Application();

//создаем документ на основе шаблона

Object template = System.Windows.Forms.Application.

StartupPath + @"\docs\" + FileName; Object newTemplate = false;

Object documentType = Microsoft.Office.Interop. Word.WdNewDocumentType.wdNewBlankDocument;

Object visible = true;

//добавляем документ в список документов приложения wordDoc = wordApp.Documents.Add(ref template, ref

newTemplate, ref documentType, ref visible);

}

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

public void ReplaceText(string word, string repl)

{

// Смещаем выделение к началу документа

Object unit = Microsoft.Office.Interop. Word.WdUnits. wdStory;

Object extend = Microsoft.Office.Interop. Word.

WdMovementType.wdMove; wordApp.Selection.HomeKey(ref unit, ref extend);

//создаем объект Find для поиска текста Microsoft.Office.Interop. Word.Find fnd = wordApp.Selection.

Find;

//очищаем его настройки fnd.ClearFormatting();

//задаем текст для поиска fnd.Text = word;

//очищаем настройки для замены fnd.Replacement.ClearFormatting();

//задаем текст для замены fnd.Replacement.Text = repl;

//запускаем процесс поиска и замены ExecuteReplace(fnd);

}

private Boolean ExecuteReplace(Microsoft.Office.Interop.Word.

Find find)

{

return ExecuteReplace(find, Microsoft.Office.Interop.Word.

WdReplace.wdReplaceAll);

}

private Boolean ExecuteReplace(Microsoft.Office.Interop.Word.

Find find, Object replaceOption)

{

Object findText = Type.Missing; Object matchCase = Type.Missing; Object matchWholeWord = Type.Missing; Object matchWildcards = Type.Missing; Object matchSoundsLike = Type.Missing;

Object matchAllWordForms = Type.Missing; Object forward = Type.Missing;

Object wrap = Type.Missing; Object format = Type.Missing; Object replaceWith = Type.Missing; Object replace = replaceOption;

Object matchKashida = Type.Missing; Object matchDiacritics = Type.Missing; Object matchAlefHamza = Type.Missing; Object matchControl = Type.Missing;

return find.Execute(ref findText, ref matchCase,

ref matchWholeWord, ref matchWildcards, ref matchSoundsLike,

ref matchAllWordForms, ref forward, ref wrap, ref format, ref replaceWith, ref replace, ref matchKashida,

ref matchDiacritics, ref matchAlefHamza, ref matchControl);

}

Для запуска процесса формирования приглашения поместите на главную форму программы кнопку «Приглашение». Текст ее обработчика с комментариями приведен ниже:

private void InvitationButton_Click(object sender, EventArgs

e)

{

//если выбран человек для формирования приглашения if (dataGridView1.SelectedRows.Count != 0)

{

документ

//создаем форму для ввода доп. информации Form2 form = new Form2();

//если мы ввели данные и нажали ОК, то формируем

if (form.ShowDialog() == DialogResult.OK)

{

//создаем новый документ на основе шаблона OpenDocument("приглашение.docx");

//получаем из БД строку с выбранным человеком DataRow row = dataSet1.Contacts.Rows[RowId];

//получаем его имя и фамилию

string FIO = row["Name"].ToString() + " " + row["Fam"].ToString();

//заменяем метки в шаблоне конкретными значениями ReplaceText("<FIO>", FIO); ReplaceText("<Holiday>", form.textBox1.Text);

ReplaceText("<Date>",

form.dateTimePicker1.Value.ToLongDateString ());

ReplaceText("<Time>", form.maskedTextBox1.Text); ReplaceText("<Place>", @form.textBox2.Text);

//делаем приложение Word видимым wordApp.Visible = true;

}

else

}

}

MessageBox.Show("Выберите человека", "Ошибка");

Внешний вид сформированного программой приглашения будет выглядеть примерно так (рисунок 4):

сформированный в Word документ

Рисунок 4 – Внешний вид сформированного в Word документа

5.3. Создание документа с информацией из телефонного справочника

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

Файл шаблона для этого задания называется «список.docx» и выглядит следующим образом (рисунок 5):

Шаблон документа «список.docx»

Рисунок 5 – Шаблон документа «список.docx»

В данном шаблоне метка <Today> будет заменена на дату формирования документа, а метка <Table> представляет собой место вставки в документ таблицы.

На главной форме программы создается еще одна кнопка для формирования данного документа. Ее обработчик с комментариями приведен ниже:

private void NumbersButton_Click(object sender, EventArgs e)

{

//создаем новый документ на основе шаблона OpenDocument("список.docx");

//заменяем метку <Today> на текущую дату ReplaceText("<Today>",

DateTime.Today.ToShortDateString());

//задаем параметры для поиска метки <Table> Object start = 0;

Object end = wordDoc.Characters.Count;

//диапазон поиска - весь документ Microsoft.Office.Interop.Word.Range rng = wordDoc.Range(ref

start, ref end); rng.TextRetrievalMode.IncludeHiddenText = false; rng.TextRetrievalMode.IncludeFieldCodes = false; string metka = "<Table>";

//ищем в документе метку <Table>

int beginphrase = rng.Text.IndexOf(metka);

//получаем "координаты" начала и конца метки в документе

start = beginphrase;

end = beginphrase + metka.Length;

//если метка <Table> найдена if (beginphrase != -1)

{

//то удаляем ее

rng = wordDoc.Range(ref start, ref end); rng.Text = "";

//и вставляем на ее место таблицу

Object defaultTableBehavior = Type.Missing; Object autoFitBehavior = Type.Missing;

//создаем объект таблицы (изначально - только шапка) Microsoft.Office.Interop. Word.Table tbl =

rng.Tables.Add(rng, 1, 3, ref defaultTableBehavior, ref autoFitBehavior);

//Форматируем таблицу и применяем стиль tbl.Range.Font.Size = 14;

Object style = "Сетка таблицы"; tbl.set_Style(ref style);

//шапка таблицы

tbl.Cell(1, 1).Range.Text = "№пп"; tbl.Cell(1, 2).Range.Text = "ФИО";

tbl.Cell(1, 3).Range.Text = "Номер телефона";

//i - общее количество строк в формируемой таблице int i = 0;

//перебираем всех людей из таблицы БД Contacts foreach (DataRow row in dataSet1.Contacts)

{

//для каждой записи получаем дочерние строки из

// таблицы Phones с номерами телефонов

DataRow[] phones = row.GetChildRows (dataSet1.Relations ["FK_Contacts_Phones"]);

//если количество телефонов > 1 if (phones.Length > 1)

{

//то получаем ФИО этого человека

string FIO = row["Fam"].ToString() + " " + row["Name"].ToString();

//перебираем все его телефоны foreach (DataRow phone in phones)

{

строку

i++;

//добавляем в таблицу документа новую

Object beforeRow = Type.Missing; tbl.Rows.Add(ref beforeRow);

//и заполняем ее столбцы

i.ToString();

tbl.Cell(i + 1,1).Range.Text =

tbl.Cell(i + 1,2).Range.Text = FIO; tbl.Cell(i + 1,3).Range.Text =

phone["Phone"]. ToString();

}

}

}

//шапку таблицы выделяем курсивом tbl.Rows[1].Range.Font.Italic = 1;

//и устанавливаем выравнивание по центру tbl.Rows[1].Range.ParagraphFormat.Alignment =

Microsoft.Office.Interop.Word. WdParagraphAlignment.wdAlignParagraphCenter;

}

else

}

ReplaceText("Table", "");

//отображаем сформированный документ wordApp.Visible = true;

Пример сформированного программой документа показан на рисунке 6:

Пример сформированного документа

Рисунок 6 – Пример сформированного документа