|
10 простых настроек для MS Office 97Андрей Колесов, Ольга Павлова
Благодаря VBA у пользователя MS Office появляются почти неограниченные возможности по настройке среды в целях облегчения и ускорения работы. В этой статье мы расскажем о 10 подпрограммах, автоматизирующих некоторые часто используемые операции. Надеемся, что приведенные здесь приемы программирования на VBA помогут пользователям MS Office создавать собственные полезные расширения и макрокоманды. Однако прежде чем приступить к изложению содержательной части, отметим следующие важные моменты.
Данная статья состоит из двух частей. В первой мы создадим четыре простые настройки для двух достаточно часто используемых функций - Find и Replace. Во второй части рассмотрим шесть способов автоматизации работы с документами и папками. Особо хотелось бы отметить последнюю настойку, которая представляет собой довольно поучительный программный пример с использованием файла Реестра (Registry). Ранее мы уже писали, что для хранения пользовательских настроек лучше создавать какие-либо специальные шаблоны (а не Normal). Тогда появляется возможность более гибко обеспечивать настройку среды, загружая в качестве дополнительных глобальных шаблонов только те, что нужны для данной операции. (Конечно, наиболее часто используемые функции можно хранить в Normal.) Однако в данном случае для разработки расширений мы будем иметь дело с шаблоном Normal, так как варианты с дополнительным глобальным или присоединенным шаблоном не подходят (в первом случае его программный код просто недоступен, а во втором мы сможем работать только с одним документом). А вот создав и отладив программный код, мы уже перенесем его из Normal в другой шаблон, например в WordCust. Поскольку мы будем совершать манипуляции с самым главным шаблоном Word, на всякий случай сразу сделаем его копию с именем NormalMy.dot. Далее мы перейдем к созданию макрокоманд, к которым сначала будем обращаться с помощью команды Tools|Macro|Macros (в среде Word) или Tools|Macros (VBA). Напомним, что в список макрокоманд автоматически попадают все процедуры, которые записаны в модуле (а не форме!), и имеют тип Public и пустой список передаваемых в них параметров. Впоследствии (но можно сделать это и сразу) мы создадим специальное меню для более удобного обращения к этим командам из среды Word. Итак, откройте Word - автоматически создастся новый документ на базе шаблона Normal.dot. Далее перейдите в среду редактора VB, нажав Alt+F11. Проверьте, установлен ли у вас флажок Require Variable Declaration во вкладке Editor (команда Tools|Options) для автоматической установки оператора Option Explicit в каждом модуле (о полезности данного режима мы уже неоднократном писали). Создайте новый модуль для шаблона Normal: щелкните правой кнопкой мыши его название в Project Explorer и выберите команду Insert|Module. Поскольку мы сейчас будем иметь дело только с процедурами, сделайте окно кода достаточно большого размера. Для создания подпрограмм в модуле мы будем пользоваться командой Insert|Procedure и окном Add Procedure (рис. 1). Имя процедуры вводится в поле Name. Убедитесь, что у вас установлены переключатели Sub и Public.
В начало статьи
Для начала давайте переименуем стандартное имя модуля Module1 в более содержательное, например FindCust. Именно в нем мы будем формировать программный код, создаваемый в этой части.
В начало статьи Как известно, установки в окне Find and Replace сохраняются между операциями Find и Replace в течение всего сеанса работы в Word (пока вы их не поменяет сами). В большинстве случаев это является полезным. Однако если вам часто приходится искать сложные выражения, например с использованием форматирования и стиля, этот режим может оказаться не таким уж и удобным. Так или иначе, но порой бывает гораздо проще не вводить новое выражение, проходя все поля формы, а сначала очистить их, и лишь потом заполнять только нужные (рис. 2). В этом случае вам могут пригодиться приведенные далее процедуры, которые мы будем создавать в модуле WordCust.
Для функции Find создайте подпрограмму, которая использует метод ClearFormatting для объекта Find, чтобы полностью снять сохранившееся форматирование, а затем вывести на экран вкладку Find диалогового окна Find and Replace:
Public Sub EditFindClean() Selection.Find.ClearFormatting Dialogs(wdDialogEditFind).Show End Sub Для функции Replace нужно снять форматирование с двух объектов - Find и Replacement, а затем вывести вкладку Replace диалогового окна Find and Replace. Здесь можно использовать оператор With...End With, поскольку объект Replacement содержится в объекте Find:
Public Sub EditReplaceClean() With Selection.Find .ClearFormatting .Replacement.ClearFormatting End With Dialogs(wdDialogEditReplace).Show End Sub В начало статьи
Операции поиска достаточно просты, но вы можете сэкономить массу усилий, если создадите подпрограммы FindNextInstance и FindPreviousInstance, которые находят соответственно следующий или предыдущий экземпляр текущего слова или выделенного текста. При работе с документом может оказаться полезной операция поиска следующего или предыдущего фрагмента по выделенному слову или фразе, а если выделение сводится к размеру курсора - то по текущему слову. В этом случае вы не тратите время на выделение слов и активизацию диалогового окна Find and Replace для поиска необходимого текста. Напишем подпрограмму FindNextInstance для поиска вниз по документу. Первый оператор If устанавливает strWord равной первому слову в текущем выделении ("Selection.Words(1)"), если длина свойства Text объекта Selection меньше 2. Такую проверку следует проводить потому, что если выделение сводится к размеру курсора, то Selection.Text имеет длину, равную 1, и возвращает символ, находящийся справа от курсора. Если же длина свойства Text больше или равна 2, strWord устанавливается как значение Selection.Text. Здесь надо обратить внимание на необходимость удаления пробелов из искомого фрагмента в его начале или конце. Если этого не сделать, то функция Find не найдет экземпляр искомого текста, который, например, заканчивается знаком препинания. Проблема заключается в том, что при выполнении данных операций Word работает не совсем так, как описано в документации. Если выделения нет и за текущим словом идет пробел, то он почему-то включается в состав слова (поэтому его нужно убрать). В случае когда выделение имеет пробелы с краев, то при удалении их только из переменной strWord поиск начинается с самого выделения. Следовательно, боковые пробелы нужно убирать с самого выделенного фрагмента. Оператор With задает свойства объекта Find (сбрасывает MatchCase, MatchSoundsLike и MatchWildcards, очищает форматирование и устанавливает Text как strWord), а затем использует метод Execute для выполнения поиска. Если результат метода Execute равен False, подпрограмма выводит окно сообщения о том, что искомый текст не найден. Подпрограмма FindPreviousInstance, которая ищет предыдущий экземпляр искомого текста, имеет совершенно аналогичный код, в нем нужно только установить свойство .Forward как False. ВАЖНОЕ ЗАМЕЧАНИЕ. Многие начинающие программисты могут осуществить операцию создания подпрограммы FindPreviousInstance, казалось бы, самым простым способом: скопировать весь текст подпрограммы FindNextInstance, вставить его в свободное место окна кода, а затем заменить имя подпрограммы на FindPreviousInstance и оператор .Forward = True на .Forward = False. Однако такой вариант является в принципе неверным, хотя, к сожалению, именно он часто приводится в качестве примера в некоторых современных пособиях по программированию. Мы сделаем это по-другому - правильно. Преобразуем подпрограмму FindNextInstance в служебную процедуру FindInstance, для чего откорректируем две строки ее кода:
Public Sub FindInstance(Direction As Boolean) ... .Forward = Direction ... А затем создадим две новые подпрограммы (вторую - на основе копии первой):
Public Sub FindNextInstance() ' поиск следующего фрагмента Call FindInstance(True) End Sub Public Sub FindPreviousInstance() ' поиск предыдущего фрагмента Call FindInstance(False) End Sub Выполненные нами манипуляции с кодом не намного сложнее первого варианта, но приводят к качественно иному результату. Во-первых, мы получаем код меньшего размера. Во-вторых (что самое главное) - закладывается правильная основа для будущей отладки или модернизации кода: вам придется вносить исправление только один раз. Представьте себе, что вам пришлось бы сделать десяток подобных подпрограмм. В
начало статьи При работе с несколькими открытыми документами может появиться необходимость в осуществлении поиска какого-либо текста в любом из этих документов, а не только в активном. В таком случае создадим подпрограмму FindInAnyOpenDocument, выводящую окно для ввода искомого текста (рис. 3) и использующую цикл For Each...Next для выполнения функции Find последовательно для каждого из открытых документов.
Подпрограмма объявляет переменную myDoc как Document для использования в цикле For Each...Next и строковую переменную strWord, содержащую искомый текст. Затем она присваивает текст, получаемый из поля ввода, переменной strWord. Если поле ввода содержит пустую строку, что может произойти, если пользователь щелкнет кнопку Cancel или OK, не вводя никакого текста, то тогда оператор End завершит выполнение подпрограммы. Цикл For Each...Next повторяется для каждого документа, представленного переменной myDoc в коллекции Documents (которая содержит все открытые документы), и прекращает свою работу, если он находит переменную strWord. Данный цикл использует оператор With для работы с документами, идентифицированными при помощи myDoc. Оператор If.Find.Execute осуществляет поиск текущего документа для текста strWord. Если этот оператор находит strWord, подпрограмма активизирует соответствующий документ, перемещает курсор в его начало, а затем выполняет операцию Find, выделяющую первый экземпляр искомого слова. После этого оператор End завершает выполнение подпрограммы. Если же оператор If.Find.Execute не находит strWord, подпрограмма выводит окно сообщения, информирующее пользователя об этом.
В начало статьи Для выполнения операций поиска в документах Word 97 можно использовать новый элемент среды, который называется Select Browse Object. Он размещается в нижней части вертикальной линейки прокрутки (рис. 4). С его помощью можно установить разнообразные варианты перемещения по разным элементам документа - по страницам, таблицам,
полям, комментариям и пр. (рис. 5). Перемещение вверх/вниз выполняется с помощью щелчков мыши по стрелкам, находящимся рядом с изображением объекта Select Browse, или нажатием клавиш Ctrl+PageUp и Ctrl+PageDown. Одним из режимов работы Select Browse является установка варианта текстового поиска Find. Если вы предпочитаете работать с клавиатурой и привыкли использовать комбинации клавиш Ctrl+PageUp и Ctrl+PageDown для выполнения операций Find Previous и Find Next соответственно, вам, вероятно, покажется утомительным переустанавливать с помощью мыши объект Browse как Find после просмотра другими объектами. Чтобы упростить эту процедуру, создайте подпрограмму, состоящую всего из одной строки и переустанавливающую объект Browse как Find:
Public Sub BrowseByFind() Application.Browser.Target = wdBrowseFind End Sub
В начало статьи Создадим для шаблона Normal еще один модуль, в котором мы будем формировать код для настроек второй части статьи. Такое разделение кода в будущем окажется весьма полезным. Переименуем новый модуль в FileCust.
В начало статьи С помощью диалогового окна Properties в Word (команда File|Properties) можно получить разнообразную справочную информацию о документе. Но она разбросана по разным вкладкам, и ее поиск порой бывает не очень удобен. Поэтому вы можете создать собственный вариант выводимого окна с нужными данными, которые берутся из документа и его коллекции BuiltInDocumentProperties. Следующий пример выводит окно сообщения, в котором приводятся полное имя документа; шаблон, на котором этот документ основан; имя автора документа; а также количество слов, содержащихся в документе (рис. 6):
Public Sub FileKeyInfo() Dim strInfo As String With ActiveDocument strInfo = .FullName & vbCr & vbCr strInfo = strInfo & "Шаблон: " & _ .AttachedTemplate & vbCr & vbCr strInfo = strInfo & "Автор: " & _ .BuiltInDocumentProperties(wdPropertyAuthor) _ & vbCr & vbCr strInfo = strInfo & _ .BuiltInDocumentProperties(wdPropertyWords) _ & " слов" End With MsgBox strInfo, vbOKOnly + vbInformation, _ "Ключевая информация о файле" End Sub В начало статьи
Если вы часто открываете документы из списка Most Recently Used (самые последние использованные документы) в нижней части меню File или из Explorer, то вам знакома ситуация, когда открыто сразу несколько документов, хранящихся в различных папках. Теперь представьте, что вам необходимо открыть еще один документ, находящийся в одной из этих папок. Вспомнить его полное имя бывает непросто, обращение к вкладке File|Properties|General требует времени, так же как и блуждание по множеству слоев дисководов и папок в диалоговом окне Open. Можно очень просто автоматизировать эту процедуру с помощью подпрограммы FileOpenFolderOfActiveDocument, которая использует оператор ChangeFileOpenDirectory для замены каталога, выводимого в диалоговом окне Open, на свойство Path объекта ActiveDocument (при условии, что Path не является пустой строкой - иначе это означало бы, что документ никогда не сохранялся). Затем подпрограмма выводит диалоговое окно Open, с помощью которого пользователь может открыть документ.
Public Sub FileOpenFolderOfActiveDocument() If ActiveDocument.Path <> "" Then _ ChangeFileOpenDirectory(ActiveDocument.Path) Dialogs(wdDialogFileOpen).Show End Sub В
начало статьи Вы можете быстро создать новый документ, основанный на том же шаблоне, что и активный документ, не выясняя при этом, что это за шаблон. Просто объявите строковую переменную, в которой будет содержаться имя шаблона, и присвойте этой строке свойство AttachedTemplate объекта ActiveDocument. Используйте метод Add коллекции Documents для создания нового документа и укажите строку в качестве аргумента Template:
Public Sub FileNewTemplateOfCurrentDocument() Dim strTemplate strTemplate = ActiveDocument.AttachedTemplate Documents.Add Template:=strTemplate End Sub В
начало статьи Если вы хотите сохранить неизменным список Most Recently Used (MRU) в нижней части меню File, можете открыть документ для просмотра, дав указание Word не присоединять его к списку MRU. Для этого установите аргумент AddToRecentFiles как False при открытии документа:
Public Sub FileOpenDoNotAddToMRU() ' установка режима открытия файла без занесения в MRU Dialogs(wdDialogFileOpen).AddToMru = False ' открытие документа Dialogs(wdDialogFileOpen).Show End Sub
В начало статьи Удерживая нажатой клавишу Shift, щелкните меню File. Тогда команда Close превратится в Close All, давая тем самым возможность быстро закрыть все открытые документы. Но что делать, если вы хотите оставить текущий документ и закрыть все остальные? Правильно - вам нужна подпрограмма, которая сделает это сама. Подпрограмма FileCloseAllExceptActiveDocument использует цикл For Each...Next для работы поочередно с каждым открытым документом, сравнивая его со строковой переменной strActive, используемой для хранения свойства Name объекта ActiveDocument. Это свойство необходимо хранить в строке, а не проводить непосредственно сравнение If myDoc.Name <> ActiveDocument.Name, поскольку смена активного документа происходит по мере того, как Word поочередно закрывает окна других документов:
Public Sub FileCloseAllExceptActiveDocument() Dim myDoc As Document, strActive As String strActive = ActiveDocument.Name For Each myDoc In Documents If myDoc.Name <> strActive Then Documents(myDoc).Close End If Next End Sub В начало статьи
Если вам приходится много работать с документами, вы, вероятно, уже установили максимальную длину списка Most Recently Used в меню File - 9 файлов. Для тех, кто не знает: такая установка делается в поле Recently Used File List во вкладке Tools|Options|General. Но при работе с большим числом документов списка такого размера бывает недостаточно. Мы приведем пример возможности работы с расширенным списком закрытых документов. На самом деле такой список может быть неограниченным, но для практической работы это тоже неудобно - лучше поставить некоторое разумное ограничение, например 25. Идея реализации такой функции довольно проста - нужно самим формировать и сохранять этот список, а потом выполнять обращение к нему. Для этого нужно создать специальные пользовательские аналоги команд Close и Open. Следует обратить внимание на то, что приведенная ниже макрокоманда работает с операцией Close (закрытие файла), а не с командой Save (Сохранение). Это обеспечивает внесение в список файлов, которые вы открывали и закрывали без сохранения информации, например для просмотра или копирования информации в другой документ. При этом, если вы не хотите, чтобы закрываемый документ был добавлен к списку, можно просто обойти эту подпрограмму, используя стандартную команду Close. В начало статьи Здесь речь пойдет о создании более сложных макрокоманд, в том числе с использованием пользовательской формы. Для написания их кода создадим еще один модуль, который назовем RecentFiles, и форму с именем frmOpenRecentFile (Insert|UserForm). Начнем с создания в модуле RecentFiles подпрограммы FileCloseAddToRecentFiles, которая занимается сопровождением нашего списка закрываемых файлов. В принципе, несложно написать программный код, который будет обеспечивать формирование такого списка в каком-либо файле. Однако гораздо проще воспользоваться объектом System и его свойством PrivateProfileString. Не совсем понятно почему, но данный объект находится в библиотеке Microsoft Word 8.0 Object Library (а не в общих библиотеках VB/VBA). Поэтому, чтобы воспользоваться им в Visual Basic или других приложениях MS Office 97 (например, Excel), нужно подключить эту библиотеку командой Reference. Мы рекомендуем вам изучить справку по свойству PrivateProfileString, но она не содержит многих деталей, поэтому приведем некоторые дополнительные комментарии. Обращение Word$ = System.PrivateProfileString(FileName$, Section$, Key$") выполняет чтение содержимого ключа с именем Key$ из секции Section$ файла FileName$. Если такого ключа (секции, файла) нет, то считывается пустое значение строки. Обращение System.PrivateProfileString(FileName$, Section$, Key$") = Word$ выполняет запись нового значения ключа с именем Key$ из секции Section$ файла FileName$. Если такого ключа (секции, файла) нет, то он (они) создается. Работа ведется с двумя типами файлов:
[Section] Key = KeyName ... Теперь приступим к написанию программного кода. В секции General программного модуля RecentFiles мы зададим три глобальные константы проекта: RegFile$ (имя файла установок), strRegistry (имя секции) и MaxListStart (максимальная длина списка по умолчанию). В нашем примере мы используем обращение к системному файлу Registry, в котором создается новый раздел HKEY_CURRENT_USER\Software\Microsoft\Office\8.0\Word\RecentFiles (посмотрите утилитой REGEDIT - его до этого не было). Хранение различных установок (в том числе и пользовательских настроек) в системном файле Реестра сегодня становится общепринятой практикой. Но лично мы считаем такую концентрацию параметров различных программ в одном месте принципиально неверной. В случае когда речь идет о пользовательских установках, для этого лучше использовать отдельный специальный INI-файл, в котором вы можете делать все что хотите без угрозы испортить системную информацию (такой вариант представлен в виде комментария в листинге 4). Имена последних использованных файлов в виде значений упорядоченного списка ключей: File1, File2 и т.д. В начале подпрограммы FileCloseAddToRecentFiles выполняется проверка свойства Path объекта ActiveDocument. Если оно не является пустой строкой, то подпрограмма присваивает свойство FullName переменной strThisFile (полное имя файла) и закрывает объект ActiveDocument. Если же свойство Path является пустой строкой - означающей, что документ никогда не сохранялся - подпрограмма закрывает объект ActiveDocument и завершает свое выполнение. Если же произошла ошибка 4248 (не было открытого файла), то выдается соответствующее сообщение перед завершением процедуры. Далее идет формирование списка. Сначала с помощью функции LenListProfile определяется максимальная длина списка. Для этого из заданной секции заданного файла читается максимальное число позиций (ключ MaxList) в списке. Если такого ключа нет, то берется тот, что определен по умолчанию константой MaxListStart (такая конструкция нам пригодится в будущем). Затем выполняется коррекция списка. Значение переменной strThisFile записывается в первую позицию, а затем идет смещение содержимого списка вниз до тех пор, пока не будет встречено имя strThisFile (закрываемый документ уже был в списке) или не будет исчерпан весь список. В
начало статьи Активизируйте созданную форму frmOpenRecentFile и задайте ее свойство Caption как "Открыть последний файл". Затем увеличьте форму, чтобы в ней мог расположиться достаточно большой список (например, состоящий из 25 файлов). Разместите на форме список ListBox и измените размеры окна списка, чтобы оно занимало около 80% всей пользовательской формы, оставив только небольшое пространство внизу, куда поместите пару командных кнопок (рис. 7). Для выравнивания расположения кнопок можно выделить их (щелкая мышью при нажатой клавише Shift), а затем использовать команду Format|Align|Tops. Чтобы придвинуть кнопки ближе друг к другу, можно воспользоваться командой Format|Horizontal Spacing|Decrease.
После этого установите свойство Name окна списка как lstFiles. Задайте свойства для кнопок в соответствии со следующей таблицей:
Теперь, когда у нас есть законченный интерфейс, приступим к написанию кода, управляющего пользовательской формой. Он будет состоять из четырех подпрограмм: UserForm_Initialize, которая будет помещать необходимую информацию в окно списка; lstFiles_Click, которая будет делать доступной кнопку Open, когда пользователь выберет какой-либо документ; а также подпрограмм Click для кнопок Cancel и Open. Начнем с самого простого - кода для кнопки Cancel:
Private Sub cmdCancel_Click() ' отмена команды открытия файла End Set frmOpenRecentFile = Nothing End Sub Теперь напишем подпрограмму для кнопки Open:
Private Sub cmdOpen_Click() ' открытие файла: ' 1. убрать форму с экрана frmOpenRecentFile.Hide On Error GoTo Handler ' 2. открыть выбранный файл Documents.Open lstFiles.Value Handler: If Err = 5174 Then ' ошибка MsgBox "Word не может найти документ " & _ lstFiles.Value & ".", vbOKOnly + _ vbCritical, "Ошибка открытия файла" End If Set frmOpenRecentFile = Nothing End Sub Далее создадим процедуру, обрабатывающую событие Click для окна списка (пока пользователь не выделит имя документа в списке, кнопка недоступна):
Private Sub lstFiles_Click() ' кнопка Open становится доступной cmdOpen.Enabled = True End Sub Для выбора нужного файла с помощью двойного щелчка мыши создадим еще одну процедуру:
Private Sub lstFiles_DblClick(ByVal _ Cancel As MSForms.ReturnBoolean) ' открытие файла двойным щелчком Call cmdOpen_Click End Sub И еще одна подпрограмма - UserForm_Initialize - для формирования списка документов. Обратите внимание, что она использует глобальные константы RegFile$ и strRegistry для определения имени файла с установками и нужной секции. Длина списка формируется автоматически. Наконец, последнее - создадим короткую подпрограмму (в модуле RecentFiles !) для вывода пользовательской формы:
Public Sub OpenRecentFile() ' открытие файла из списка последних frmOpenRecentFile.Show End Sub
В начало статьи Мы завершили создание двух макрокоманд, одна из которых открывает файл из пользовательского списка последних использованных документов (OpenRecentFile), а другая - закрывает документ с занесением его в этот список (FileCloseAddToRecentFiles). Поработайте с ними и убедитесь, что все работает как задумано. Если вы задействовали системный Реестр/Registry, то с помощью утилиты REGEDIT убедитесь, что там появился новый раздел, а в нем - список ключей и их значений (рис. 8).
Если же вы решили использовать свой INI-файл, то в нем можете обнаружить примерно такое содержимое:
[RecentFileS] File1=D:\TMP\90127I.DOC File2=D:\PRESS\C-PRESS\CPS99-03\VBA\test1.doc Обратите внимание, что длину списка легко изменить, исправив только значение константы LenListStart. Но если вы хотите предоставить пользователю возможность без разрешения вмешиваться в ваш программный код, то напишите в модуле RecentFiles еще одну макрокоманду - RecentFilesCount. Можно и дальше развивать идею о хранении списка последних использованных документов. Например, можно поддерживать несколько таких списков (для разных пользователей или типов документов, например писем, отчетов и пр.), при этом пользователь будет сам выбирать нужный ему список. В общем, существуют области, где есть возможность подключить свое воображение. Но в данной статье нам пора ставить точку. В начало статьи
До сих пор мы обращались к созданным макрокомандам из диалогового окна Macros. Теперь пора включить их в пользовательский интерфейс в виде команд меню, кнопок панелей инструментов, быстрых клавиш и пр. Здесь вы можете выбрать наиболее удобный для себя вариант. Мы сейчас просто покажем, как с помощью вкладки Tools|Customize|Commands создать новую позицию New Menu в линейке меню (рис. 9).
Затем переименуем название меню в "10 новых настроек Word" и запишем туда все созданные нами макрокоманды. В качестве названий мы использовали имена подпрограмм (в скобках указан номер настройки), вы же можете их поменять, закрепив при необходимости за какими-либо быстрыми клавишами (рис. 10).
В завершение сохраните созданный нами программный код приложения (рис. 11) с помощью команды File|Export в виде внешних файлов - FindCust.bas, FileCust.bas, RecentF.bas и RecentF.frm. Эти файлы могут понадобиться для создания других приложений, и не только в среде Word. Как мы уже подчеркивали, хранить пользовательские макрокоманды в общем шаблоне Normal не стоит. Поэтому создадим новый пользовательский шаблон самым простым способом: переименуем модифицированный нами шаблон Normal.dot в 10WordEx.dot и скопируем NormalMy (мы его создали в самом начале работы) в Normal. Чтобы созданные нами макрокоманды были доступны при работе со всеми
документами, после загрузки Word подключите 10WordEx.dot в качестве глобального шаблона (рис. 12).
Еще одно домашнее задание - попробуйте адаптировать эти команды для Excel.
© Андрей Колесов, Ольга Павлова |
|