Опубликован: 13.09.2006 | Уровень: для всех | Доступ: свободно | ВУЗ: Тверской государственный университет
Лекция 2:

Программная работа с документами Word

Аннотация: Примеры работы с текстовыми документами: работа с буфером, трансляция символов, работа с текстовыми базами данных.

Программная работа с документами Word

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

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

Конечно, опытные программисты не примут эту фразу всерьез.

Примеры работы с текстовыми документами

Чтобы эффективно работать с текстовыми документами, необходимо хорошо знать объекты Word, описанные в предыдущей лекции. Без знания основных коллекций, задающих структуру документа, - абзацев, предложений, слов, символов, без знания объектов Range и Selection, не обойтись. С другой стороны необходимо владение встроенными функциями VBA для работы со строковыми переменными. Умение работы с объектами Word и функциями VBA позволяет достаточно просто решать самые разнообразные задачи, возникающие в ходе работы с текстовыми документами. В предыдущей лекции, где я рассматривал объекты Word, я приводил большое число примеров, иллюстрирующих работу с теми или иными объектами. Но там рассмотрение шло от "объектов", теперь же я хочу идти от "задач", которые могут возникать при работе с текстовыми документами. Давайте перейдем к рассмотрению некоторых примеров.

Вариации на тему "буфера"

Я начну с самой простой задачи - написания собственных макросов, реализующих известные функции Word "Copy" и "Paste". Пожалуй, при создании любого из документов Word кнопки, реализующие эти функции, нажимаются чаще всего. Всегда полезно понимать, как реализованы стандартные функции, а, кроме того, иногда желательно иметь собственную реализацию, отличающуюся от стандартной. В разумности такого подхода можно будет убедиться даже на этом простом примере.

Копирование текста

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

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

Каждая из этих задач решается в одну строчку. Поэтому давайте взглянем на программный текст, а затем я приведу краткий комментарий:

'Текстовый буфер задается обычной строкой
Public TextBuffer As String

Public Sub CopyText()
	'Этот макрос копирует выделенный текст в буфер
	TextBuffer = Selection.Text
End Sub

Public Sub PasteText()
	'Этот макрос выполняет операцию, обратную копированию
	'Текст из буфера вставляется в точку, заданную курсором
	Selection.Text = TextBuffer
End Sub
Листинг 2.1.

Как видите, буфер задается обычной текстовой переменной VBA. Выделенный текст задается свойством Text объекта Selection. Точка вставки, заданная курсором, также представляется объектом Selection.

Несмотря на простоту этих макросов, я часто использую их наряду со стандартными реализациями Copy - Paste. Дело в том, что при вставке скопированного текста в новое местоположение всегда возникает вопрос, как должен быть отформатирован вставляемый текст (шрифт, размер, курсив и другие свойства), - должно ли использоваться форматирование копируемого текста или форматирование, определяемое контекстом точки вставки. В стандартной реализации при вставке используется форматирование копируемого текста, но во многих случаях предпочтительным является контекст точки вставки. В тех ситуациях, когда необходимо вставлять только текст, сохраняя особенности стиля точки вставки, наши простые макросы предпочтительнее стандартной реализации.

Копирование текста и шрифта

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

'Буфер, сохраняющий текст и шрифт
Public Type TextAndFont
	 BufText As String
	 BufFont As Font
End Type

Public TaFBuffer As TextAndFont
Листинг 2.2.

Как видите, вначале дано определение пользовательского типа, содержащего два поля для хранения текста и объекта класса Font. Сам буфер описывается переменной введенного типа TextAndFont.

Чуть усложняются и тексты макросов, решающие задачу копирования и вставки:

Public Sub CopyTextAndFont()
	'Этот макрос копирует выделенный текст и шрифт в буфер
	Set TaFBuffer.BufFont = Selection.Font
	TaFBuffer.BufText = Selection.Text
End Sub

Public Sub PasteTextAndFont()
	'Этот макрос выполняет операцию, обратную копированию
	
		'К сожалению, такое присваивание свойства Font
		'для объекта Selection не проходит?!
		'Selection.Font = TaFBuffer.BufFont
	'Но можно присвоить свойства объекту Font
	Selection.Font.Name = TaFBuffer.BufFont.Name
	Selection.Font.Bold = TaFBuffer.BufFont.Bold
	Selection.Font.Italic = TaFBuffer.BufFont.Italic
	Selection.Font.Size = TaFBuffer.BufFont.Size
	'Текст из буфера с указанными параметрами шрифта	
	'вставляется в точку, заданную курсором.
	Selection.Text = TaFBuffer.BufText
End Sub
Листинг 2.3.

Первый из этих макросов не нуждается в особых комментариях. Объект Selection имеет наряду со свойством Text и свойство Font, возвращающее объект данного класса. Эти свойства и передаются в поля переменной, определяющей наш буфер. Казалось бы, что второй макрос должен быть симметричным, поскольку необходимо выполнить такое же присваивание, но в другую сторону. Однако объекты Range и Selection обладают одной особенностью, - их свойству Font нельзя присвоить объект класса Font. Можно, однако, задать характеристики этого объекта, чем я и воспользовался.

Повторяю, этот пример интересен скорее, как программистский прием. Практического значения он не имеет, так как стандартная реализация Copy - Paste решает эту же задачу, обладая при этом дополнительными преимуществами. Заметьте, что эта пара макросов неявно предполагает, что выделенный текст записан одним шрифтом, параметры которого постоянны для всего текста. Если же это не так, то будут использованы параметры конечного участка текста. В то же время стандартная реализация при вставке текста будет сохранять все изменения шрифта выделенного участка текста, что, конечно, представляется более разумным.

Копирование объекта

До сих пор я говорил о копировании выделенного текста. И делал я это потому, что копирование текста это наиболее типичная задача, возникающая при работе с документом Word. Однако понятно, что реально в документе Word выделяется не текст, а некоторая область документа, - объект Range, если говорить в терминах объектов. Я напомню, что объект Range может быть устроен столь же сложно, как и сам документ, и, наряду с текстом, содержать самые разные компоненты, например, рисунки. Стандартная реализация Copy - Paste фактически работает именно с объектом Range. Давайте напишем и мы такую же реализацию. Вот как задается буфер и макросы в подобной реализации:

'Буфер, позволяющий сохранять объект
Public ObjectBuffer As Range

Public Sub CopyObject()
	'Этот макрос копирует выделенный объект в буфер
	Set ObjectBuffer = Selection.Range
End Sub

Public Sub PasteObject()
	'Этот макрос выполняет операцию, обратную копированию.
	'Объект из буфера вставляется в точку, заданную курсором.
	'Поскольку объект может быть сложным и содержать, например,
	'рисунки, то используется техника копирования через стандартный буфер!
	 ObjectBuffer.Copy
	 Selection.PasteSpecial
	 
End Sub
Листинг 2.4.

Реализация макросов в этом случае даже более проста, чем в предыдущем случае. Однако, заметьте, она построена на использовании возможностей стандартного буфера и таких мощных методов работы с ним, как методы Copy и PasteSpecial. Стоит обратить внимание на то, что побочным эффектом этой реализации является изменение содержимого буфера. Конечно, можно было бы запоминать и восстанавливать его содержимое, но вряд ли стоит этим заниматься, поскольку данная реализация вряд ли имеет преимущества по сравнению со стандартной реализацией. Так что из трех пар приведенных макросов, практическую пользу может иметь самая первая и самая простая пара макросов, работающих с простым текстом.

Сергей Дмитриев
Сергей Дмитриев
Россия, Москва