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

В некоторых случаях именно макрос помогает справиться с возникшими затруднениями. Рассмотрим такой пример. На моем ПК все документы, чтобы было удобнее редактировать, оформлены приблизительно одинаково: шрифт — Times New Roman; размер шрифта — 12 пунктов; начертание — «Полужирное» и «Курсивное»; выравнивание — «По ширине», все абзацные отступы равны нулю, а табуляция — 1 см. Кроме того, копии документов я обычно делаю в формате Rtf. Допустим, мне потребовалось скопировать 20 рефератов по вопросам кардиологии. Все они написаны и отформатированы разными людьми в соответствии с их вкусом, поэтому потребуется много времени, чтобы придать документам единообразный вид. Можно, конечно, отформатировать каждый из них, что вполне приемлемо, когда обрабатывается до десяти файлов. Если же документов будет от 40 до 100, то здесь помогут макросы.

Редактор Visual Basic for Applications

Но как написать реальную программу на современном языке программирования, ничего не зная о нем? На Си++ или Delphi это действительно было бы трудно сделать, однако для создания программ с помощью Visual Basic for Applications (VBA) не требуется особых знаний — они появятся в процессе работы. Нужно лишь уметь думать.

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

Менеджер проектов

Я открыл пару документов из общего списка и включил запись макроса, согласившись на его имя по умолчанию — все равно потом буду редактировать. Когда макрос начал записываться, я стал обрабатывать документ, а Word скрупулезно переводил мои действия на язык Visual Basic for Applications. Выбрал «Правка? Выделить все», «Формат?Шрифт» и установил Times New Roman, 12 пунктов, черного цвета. Указал «Формат?Абзац», обнулил все отступы и поставил одинарный межстрочный интервал. Затем выбрал «Правка?Заменить» и, отметив пункты «Формат?Абзац», во вкладке «Отступы и интервалы» для заменяемого текста указал выравнивание «По левому краю», а для заменяющего — «По ширине». В поле «Направление» выбрал «Везде» и провел замену по всему тексту.

По окончании всех этих действий я сохранил документ командой «Файл?Сохранить», затем выбрал «Файл?Сохранить как», отметил «Текст в формате RTF» и сохранил документ уже в этом формате. В заключение я на панели записи макроса нажал кнопку «Остановить»..

В принципе, назначив какую-нибудь кнопку или сочетание клавиш записанному макросу, можно на этом остановиться и последовательно обработать все предварительно открытые в Word документы. Но нажимать кнопку от 40 до 100 раз и ждать, пока все выполнится, — перспектива не слишком приятная. Хотелось бы, чтобы все делалось автоматически, а самому можно было заняться другим делом. Да и опыт в написании макросов пригодился бы в дальнейшем. Итак, посмотрим, как работает редактор Visual Basic for Applications.

Записанный макрос

В левой части экрана Visual Basic есть окно, где отображаются все открытые в данный момент документы и содержащиеся в них программы, — менеджер проектов. (Если почему-либо этого не происходит, то в меню «Вид» редактора Visual Basic нужно выбрать пункт «Окно проекта» или нажать комбинацию клавиш +R.) Все документы, вызванные в менеджере проектов, представлены как папки в Проводнике Windows.

Развернув содержимое папки Normal, т. е. макросов в шаблоне Normal.dot, указываем модуль NewMacros. Именно в него попадают все макросы, записанные пользователем. Поскольку созданный нами макрос — первый, то он сразу и откроется. Вот его содержимое.

Sub Макрос1()
?
? Макрос1 Макрос
? Макрос записан 27.01.00 
?
Selection.WholeStory
With Selection.Font
.Name = ?Times New Roman?
.Size = 12
.ColorIndex = wdBlack
End With
With Selection.ParagraphFormat
.LeftIndent = CentimetersToPoints(0)
.RightIndent = CentimetersToPoints(0)
.SpaceBefore = 0
.SpaceAfter = 0
.LineSpacingRule = wdLineSpaceSingle
.FirstLineIndent = CentimetersToPoints(1.27)
End With
Selection.Find.ClearFormatting
Selection.Find.ParagraphFormat.Alignment
 = wdAlignParagraphLeft
Selection.Find.Replacement.ClearFormatting
Selection.Find.Replacement.ParagraphFormat
.Alignment = wdAlignParagraphJustify
With Selection.Find
.Text = ??
.Replacement.Text = ??
.Forward = True
.Wrap = wdFindContinue
.Format = True
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Selection.Find.Execute Replace:=wdReplaceAll
ActiveDocument.Save
ActiveDocument.SaveAs FileName:=?Доклад1
.rtf?, FileFormat:=wdFormatRTF, _
LockComments:=False, Password:=??
, AddToRecentFiles:=True, WritePassword _
:=??, ReadOnlyRecommended:=False,
 EmbedTrueTypeFonts:=False, _
SaveNativePictureFormat:=False, SaveFormsData
:=False, SaveAsAOCELetter:= _
False
ActiveWindow.Close
End Sub

Разберем строки макроса более подробно.

Sub Макрос1()
?
? Макрос1 Макрос
? Макрос записан 13.01.00 
?

Как легко догадаться, это заголовок макроса. Слово Sub означает начало программы с названием «Макрос1» — уникальное имя, по которому ее можно запустить из других программ данного модуля.

Знаки ? перед строчкой обозначают комментарии (отображаются зеленым цветом), т. е. все, что стоит в той же строке после них, никак не влияет на работу программы.

Selection.WholeStory

Скорее всего, это команда «Выделить все», переведенная на язык Visual Basic при записи макроса. В самом деле, ведь первое действие, выполненное в процессе записи, — именно выделение всего текста. Подтвердить это нетрудно, просто поставив курсор на слово WholeStory и нажав кнопку вызова помощи .

Вот что показывает справка по слову WholeStory

Немножко непонятный текст, но с помощью словаря удастся перевести, что эта команда расширяет выделение на весь текст (см. врезку «Отступление 1»).

With Selection.Font
.Name = «Times New Roman»
.Size = 12
.ColorIndex = wdBlack
End With

Эта часть связана со шрифтом. В самом деле, ведь Font — шрифт, а Selection — выделение. Слово Name задает имя шрифта — Times New Roman, а Size — его размер. Команда, устанавливающая цвет шрифта, — .ColorIndex = wdBlack. Более подробно о составляющих этой команды можно посмотреть в справочной системе.

Справка по слову Selection

Если нажать на подчеркнутое в тексте слово Font, то получим информацию об объекте Font.

Справка по слову Font

Теперь посмотрим вверху окна справки ссылку Properties — список свойств шрифта, которые можно задать в программе.

Справка об объекте Font

Это, кстати, такой же список, как и тот, что появляется в качестве контекстной подсказки, если при наборе текста программы поставить точку после слова Font. Видно, что здесь есть все свойства шрифта, задаваемые в макросе. При желании можно подробно ознакомиться с ними, но, наверное, лучше разобраться с командой With, которая встречается и в нашем макросе, и в справке по слову Font. Ставим на нее курсор и нажимаем .

Список свойств объекта Font

Теперь мы узнаем, что With позволяет выполнить последовательность инструкций над указанным объектом, не повторяя задания его имени. Таким образом, команда позволяет сократить объем текста и облегчить ориентирование в нем программиста — без этой функции рассматриваемый фрагмент текста нашего макроса имел бы вид:

Selection.Font.Name =
 ?Times New Roman?
Selection.Font.Size = 12
Selection.Font.ColorIndex = wdBlack
Примем его к сведению и рассмотрим
 следующую часть макроса.
With Selection.ParagraphFormat
.LeftIndent = CentimetersToPoints(0)
.RightIndent = CentimetersToPoints(0)
.SpaceBefore = 0
.SpaceAfter = 0
.LineSpacingRule = wdLineSpaceSingle
.FirstLineIndent = CentimetersToPoints(1.27)
End With
Справка по слову With

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

Справка по слову ParagraphFormat

Теперь проверим, так ли это. Откроем какой-нибудь документ и запишем новый макрос, выделив пару абзацев, включим запись макроса и поставим этим двум абзацам отступы сверху, снизу, справа и слева по 1 см, а межстрочный интервал сделаем полуторный. Вот что получилось.

Sub Макрос2()
?
? Макрос2 Макрос
? Макрос записан 26.01.00 
?
With Selection.ParagraphFormat
.LeftIndent = CentimetersToPoints(1)
.RightIndent = CentimetersToPoints(1)
.SpaceBefore = 1
.SpaceAfter = 1
.LineSpacingRule = wdLineSpace1pt5
.Alignment = wdAlignParagraphJustify
.WidowControl = True
.KeepWithNext = False
.KeepTogether = False
.PageBreakBefore = False
.NoLineNumber = False
.Hyphenation = True
.FirstLineIndent = CentimetersToPoints(1.27)
.OutlineLevel = wdOutlineLevelBodyText
End With
End Sub

Текст стал больше, а также появилось много новых команд, в частности WidowControl, .KeepWithNext. Почему же исходный текст был гораздо меньше? Сравним оба случая. В первом примере все абзацы документа были оформлены по-разному, во втором — одинаково. Может, в этом дело? И действительно, поэкспериментировав еще, можно прийти к выводу, что в текст записанного макроса попадают те свойства, которые после установки параметров абзацев («Формат?Абзац») оказываются у всех последних одинаковыми (см. врезку «Отступление 2»).

Орлов Антон Александрович,

antorlov@inbox.ru,

http://antorlov.nm.ru

Продолжение в следующем номере.


Отступление 1

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

Язык Visual Basic for Applications из-за особого строения его команд (более подробно см. «Мир ПК», №7/2000, с. 122 и №8/2000, с. 125) называется объектно-ориентированным. Типичная команда Visual Basic имеет вид: <Объект>.<Объект, входящий в первый объект>.<...>.<Тот объект, с которым нужно произвести действие>.<Собственно действие>. Иными словами, каждая команда пишется как бы «с конца»: сначала определяется то, над чем надо произвести действие, т. е. объект, а затем само действие — метод. Разделителями компонентов команды служат знаки «точка». Вот пример такой команды:

Selection.Font.Size = 12
Попытка присвоить значение размера шрифта графическому объекту

Команда устанавливает размер шрифта во всем выделенном тексте, равный 12 пунктам. У объекта Selection (т. е. выделенная в данный момент часть текста) есть подобъект Font — шрифт выделенного текста, а у Font — свойство Size, которое тоже можно считать подобъектом. Знак «=» — это оператор присваивания, в данном случае свойству Size присваивается значение 12. (Если в документе нет выделенного текста, то значение 12 пунктов задается текущему шрифту и следующая набранная буква будет именно такого размера. Если выделен графический объект, то команда будет ошибочной, о чем VBA выдаст соответствующее сообщение.)

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

а = Selection.Font.Size

После ее выполнения переменная «а» будет иметь значение, равное размеру шрифта выделенного текста. (Если в документе нет выделения, то данная переменная будет показывать значение размера шрифта, следующего за символом курсора. Когда части выделенного текста оформлены разными шрифтами, «а» будет иметь значение 9999999. При выделении графического объекта команда будет ошибочной, о чем Visual Basic выдаст соответствующее сообщение.)

вернуться


Отступление 2

Средство записи макросов VBA отслеживает не столько действия пользователя, сколько изменения параметров текста. Поэтому при введении свойств абзаца с помощью соответствующего диалогового окна «Формат?Абзац» в макрос скрупулезно записываются все заданные в этом диалоговом окне параметры. Если абзацы имели разное оформление, то в диалоговом окне «Абзац» характеристики, отличающиеся у выделенных абзацев, будут иметь неопределенное значение, а средство записи макросов не сможет поместить их в текст. В самом же диалоговом окне подобные неопределенные опции будут отображаться включенной функцией на сером фоне, а в полях указания размеров отступов значений не будет.

Диалоговое окно установки параметров абзаца с неопределенными опциями

Если же все выделенные абзацы были оформлены одинаково, то и параметры в диалоговом окне «Абзац» будут определены и попадут в текст макроса. Чтобы сократить размер программы и исключить излишние свойства, рекомендуется удалить ненужные команды задания свойств, которые оказались в тексте макроса при его записи, — программа должна изменять лишь те свойства текста, для работы с которыми она создавалась.

Параметры этого окна всегда установлены

Если во время записи макроса при вызове диалогового окна «Абзац» или «Шрифт» в документе не было выделений, то будут определены все параметры окна и в макрос попадут указанные в нем свойства, а установленные параметры будут использоваться для вновь вводимого текста.

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

вернуться