Интернет-журнал "Домашняя лаборатория", 2007 №3
Шрифт:
В Word 6.0 и Word 95 имелась функция "FileNameInfo$(документ, параметр)", с помощью которой можно было получить имя документа без расширения, путь к документу без имени и путь к документу вместе с именем. Для того, чтобы уз нать одно имя документа, без расширения и пути, значение параметра должно быть равно 4. (Все это подробно описано в справке по WordBasic для Microsoft Word 6.0 и Microsoft Word 95.)
В VBA эта функция будет выглядеть так:
imyadoc = WordBasic.[FileNameInfo$](ActiveDocument.Name, 4)
Она возвращает полное имя документа без расширения
Данная функция просто незаменима при обработке документов с расширениями, состоящими не из трех символов — например, ".html". В то время как в таких случаях с помощью функций "Len", "Mid", "Right" пришлось бы писать огромные фрагменты кода для получения имени документа без расширения, эта функция позволит получить его одной строчкой.
Однако при первой работе с VBA она не будет очевидной, так как узнать о ней, и тем более о ее необходимых параметрах может только тот, кто раньше имел дело с WordBasic. Поэтому в нашей программе будет использоваться предыдущая функция — "imyadoc = Left(ActiveDocument.Name, Len(ActiveDocument.Name) — 4) ".
Вообще говоря, иногда бывает очень полезным воспользоваться старыми командами WordBasic, которые остались в нем от предыдущих версий. К сожалению, в справке не освещено их применение, однако, если на вашем компьютере установлены сразу две версии Word, то вы можете узнать о таких командах в справке предыдущей версии.
* * *
Итак, команда нашей программы "ActiveDocument.SaveAs" должна выглядеть так:
ActiveDocument.SaveAs FileName: = Left(ActiveDocument.Name, Len(ActiveDocument.Name) — 4), FileFormat:=wdFormatRTF, LockComments:=False, Password:="", AddToRecentFiles:=True, WritePassword:="", ReadOnlyRecommended:=False, EmbedTrueTypeFonts:=False, SaveNativePictureFormat:=False, SaveFormsData:=False, SaveAsAOCELetter:= False
Все лишнее можно убрать, хотя это не обязательно:
ActiveDocument.SaveAs FileName: = Left(ActiveDocument.Name,
Len(ActiveDocument.Name) — 4), FileFormat:=wdFormatRTF
He мешало бы еще, чтобы новый документ в формате Rtf сохранялся в той же папке, что и исходный. Для этого добавим к параметру "FileName" информацию о пути к активному документу:
ActiveDocument.SaveAs FileName:=ActiveDocument.Path + "\" +
Left(ActiveDocument.Name, Len(ActiveDocument.Name) — 4),
FileFormat:=wdFormatRTF
Иначе Word будет сохранять документы в той папке, где последний раз был сохранен или открыт како-нибудь документ с помощью диалоговых окон "Сохранить как…" и "Открыть…". А это все же не всегда будет той же самой папкой, где находятся обрабатываемые документы, — к тому же документы для обработки можно открывать в Word и путем перетаскивания иконки файла в окно редактора, а при таком способе открытия папка сохранения документов не меняется.
И, наконец, последняя строчка:
ActiveWindow.Close
End Sub
Вот и конец программы — закрытие активного окна с документом.
Ну, а теперь надо добиться того, чтобы программа могла обрабатывать не один документ, а сразу множество. Можно пойти двумя путями: либо обрабатывать все нужные документы в одной папке,
Как это сделать? Заметим, что готовый документ закрывается после обработки, и в окне Word активизируется следующий документ из всех открытых в редакторе. Следовательно, во-первых, надо обеспечить выполнение макроса над всеми документами, то есть его повторение — после окончания работы макроса он должен быть выполнен сначала… Можно считать, что в момент обработки в окне
Word будут открыты лишь те документы, которые обработать надо — лишние всегда можно закрыть, а если так уж необходимо оставить их открытыми, то ничего не мешает открыть для обработки файлов новое окно Word. Для выполнения макроса сначала нужно заставить VBA перейти в начало программы. Поищем в справке VBA, в Предметном указателе по слову "переход" — есть ли какая команда для этого? Получаем список — "безусловные", "при ошибке", "условные"[5].
Выберем "Безусловные" — ведь в нашей программе надо обязательно перейти к обработке следующего документа. Получаем выбор из двух функций — выберем вторую, название короче — наверняка ее использование проще.
Из справки и примера узнаем, что инструкция (то есть функция, которая не возвращает никаких значений) "Goto" указывает на необходимость перехода к строке, на которой находится установленная нами метка. Поставим метку[6] в начало нашей программы:
Sub Макрос1
' Макрос1 Макрос
metka:
Selection.Wholestory
With Selection.Font
.Name = "Times New Roman"
…
а в ее конец — инструкцию "Goto":
ActiveDocument.SaveAs FileName:=ActiveDocument.Path + "\" +
Left(ActiveDocument.Name, Len(ActiveDocument.Name) — 4),
FileFormat:=wdFormatRTF
ActiveWindow.Close
Goto metka
End Sub
Готово. Теперь наша программа обработает все открытые документы. Но… обработать-то обработала, но в конце выдала сообщение об ошибке. Можно, конечно, оставить и так, но программа, заканчивающая свою работу ошибкой, пусть и после выполнения всех необходимых действий, выглядит некрасиво. Поэтому нужно обеспечить остановку выполнения программы после того, как будут обработаны все документы. Итак, алгоритм действий программы должен быть таков:
1. Выполнить обработку активного документа, сохранить его и закрыть.
2. Посмотреть, есть ли еще открытые документы.
3. Если есть, то перейти к пункту 1, если нет, то завершить работу.
"Если" — по-английски "If". Поищем по этому слову в Предметном указателе справки. Получаем строчку: "Инструкция If", выбрав которую, получаем окно из различных сочетаний слов If, Then, Else и др[7].
Выберем "Инструкция If…Then…Else" — вроде первое слово понятнее. Получаем справку, из которой узнаем синтаксис команды: