2 семестр / vba_2002
.pdfЭтот макрос можно сохранить в персональной книге макросов для того, чтобы всегда иметь к нему доступ. Чтобы получить быстрый доступ к макросу, ему следует назначить значок на панели инструментов, определить команду в меню или опцию в контекстном меню. Также макрос можно вызывать определенной комбинации клавиш.
Некоторые примеры, приведенные в части IV, на самом деле являются утилитами (или они легко могут быть преобразованы в утилиты).
Использование VBA для разработки утилит
При изучении бета-верснн Excel 5 многих поразил потенциал VBA, который на светоаые годы опережал встроенный язык Excel для создания макросов XLM и делал Excel лидером среди программ управления электронными таблицами, особенно в вопросах программирования новых возможностей.
В процессе изучения VBA я создал коллекцию утилит Excel, которые были написаны исключительно с использованием VBA. Я понял, что могу изучить язык программирования быстрее, если поставлю перед собой реальную цель. Результатом стало создание пакета Power Utility Pak для Excel.
При изучении языка VBA следует учитывать такие моменты.
•VBA может оказаться трудным в изучении, но со временем его использование упрощается.
•Экспериментирование является основным способом изучения VBA. Проект обычно вырастает из десятка экспериментов по созданию кода, что в итоге приводит к появлению завершенного продукта.
•VBA предоставляет возможность использовать Excel таким образом, который соответствует внешнему виду и поведению Excel, включая меню, панели инструментов и диалогового окна.
•Excel может выполнять любые задачи. Если разработка зашла в тупик, то существует вероятность, что к решению ведет другой путь.
Немногие другие продукты содержат такой богатый набор инструментов, который позволяет конечному пользователю настолько значительно расширить возможности программы
Из чего состоит хорошая утилита
Утилита Excel должна упрощать выполнение задачи, причем делать это более эффективно, чем смог бы произвести вручную пользователь. Если утилита разрабатывается для конечных пользователей, то что же делает ее ценной? Ниже приводится список составляющих хорошей утилиты.
•Утилита добавляет что-либо к Excel. Это может быть и новая возможность, и комбинация существующих функций, и более простой способ использования одного из существующих средств.
•Утилита имеет универсальную природу. В идеальном случае она должна обладать возможностями, которые работают в различных средах. Конечно, создать утилиту общего назначения намного сложнее, чем создать утилиту, работающую в строго определенной среде.
•Утилита обладает гибкостью. Лучшие утилиты предоставляют большое количество параметров, что позволяет использовать их для обработки широкого диапазона ситуаций.
Часть У. Совершенные методы программирования |
419 |
•Утилита выглядит, работает и кажется встроенной командой Excel. Несмотря на то, что зачастую возникает желание добавить собственные штрихи к внешнему виду создаваемых утилит, другие пользователи не будут испытывать трудностей с их использованием {однако утилиты должны выглядеть и вести себя так же, как и встроенные команды Excel).
•Утилита должна предоставлять пользователям необходимую справочную информацию. Другими словами, следует создать документацию, к которой пользователь может обратиться в случае необходимости.
•Утилита отслеживает появление ошибок. Конечный пользователь никогда не должен наблюдать сообщение об ошибке VBA. Любое сообщение об ошибке, которое увидит пользователь, должно создаваться автором утилиты.
•Утилита должна предоставлять способ отмены результата собственных действий.
Пользователи, которых не устроил результат работы утилиты, должны иметь возможность отменить внесенные изменения.
Текстовые инструменты: анатомия утилит
В этом разделе рассматривается утилита Excel, которая была разработана в качестве части пакета Power Utility Pak. Утилита Text Tools позволяет пользователю манипулировать текстом в выделенном диапазоне ячеек. В частности, эта утилита поддерживает такие операции.
•Изменения регистра текста (верхний регистр, нижний регистр или правильный регистр).
•Добавление символов в начале, в конце или в указанной позиции.
•Удаление текста в начале, в конце или в указанной позиции строки.
•Удаление лишних пробелов (или всех пробелов)
Обоснование
Excel содержит ряд текстовых инструментов, позволяющих манипулировать текстовыми строками несколькими способами. Например, можно преобразовать символы в ячейке в верхний регистр или удалить из текста определенный символ. Также существует возможность удалить из строки пробелы и т.д. Но для того чтобы выполнить одну из этих операции, необходимо создавать формулы, копировать их, преобразовывать в значения и вставлять значения вместо первоначального текста. Другими словами, Excel не предоставляет простого способа управления текстом. Было бы неплохо, чтобы Excel имела инструменты работы с текстом, которые не требуют использования формул.
Кстати, многие прогрессивные идеи начинаются с фразы "Если бы...".
Цели проекта утилиты Text Tools
Первым этапом в разработке утилиты является точное определение того, что будет делать утилита. Ниже приведен первоначальный план, представленный в виде десяти целей.
•Утилита должна иметь тот же внешний вид и поведение, что и остальные команды Excel. Другими словами, утилита будет отображать диалоговое окно, которое выглядит так же, как и другие диалоговые окна Excel.
•Утилита должна работать с выделенным диапазоном ячеек (включая множественное выделение) и предоставлять пользователю возможность модифицировать диапазон ячеек до тех лор, пока отображена диалоговое окно.
420 |
Глава 16. Разработка утилит Excel с помощью VBA |
Доступ к утилите можно получить из меню Сервис.
Основные возможности утилиты заключаются в изменении регистра символов, добавлении нового текста в строки, удалении фиксированного количества символов из текста и удалении пробелов из текста в каждой ячейке.
Кроме того, пользователю предоставляется возможность просмотра базовой статистики по выделенным ячейкам.
Пользователь имеет возможность проводить перечисленные изменения как по отношению к текстовым ячейкам, так и по отношению к нетекстовым ячейкам.
Утилита не будет вносить изменения в ячейки, которые содержат формулы.
Утилита должна быть быстрой и эффективной. Например, если пользователь выделит диапазон, утилита должна игнорировать пустые ячейки, которые присутствуют в этом диапазоне.
Пользователю должна предоставляться возможность отмены внесенных изменений. Пользователь может получать справочные сведения из диалогового руководства.
Как работает утилита
Когда открывается рабочая книга утилиты Text Tools, создается новая команда в меню Сервис. Она называется Текстовые инструменты. Выбор этой команды приведет к запуску процедуры S t a r t T e x t T o o l s , которая проверяет состояние рабочей среды Excel (необходимо, чтобы рабочая книга была активна и не была защищена), после чего отображается диалоговое окно Текстовые инструменты.
Пользователь может выбрать необходимые опции для изменения текста и щелкнуть на кнопке Применить для того, чтобы применить их. Изменения сразу же будут представлены в рабочей книге. Диалоговое окно продолжает отображаться на экране. Каждую операцию можно отменить. Пользователь также имеет возможность выполнить некоторые дополнительные действия. Щелчок на кнопке Справка приведет к отображению диалогового окна справочного руководства. Щелчок на кнопке Выход вызывает закрытие диалогового окна.
На рис. 16.1 показан пример использования утилиты Text Tools.
Рис. 16.1. Использованиеутилиты Text Tools для изменения регистра текста
Рабочая книга утилиты Text Tools
Рабочая книга утилиты Text Tools состоит из следующих компонентов.
•Один лист. Каждая рабочая книга должна иметь как минимум один лист. В данном случае этот лист используется для хранения текста справочного руководства.
•Два модуля кода VBA. Один модуль (modMerms) содержит код создания и удаления команды меню. Второй модуль (modMain) содержит код отображения основного
ЧастьV.Совершенныеметодыпрограммирования |
421 |
пользовательского диалогового окна. Код, который выполняет фактическую работу по обработке текста, хранится в модулях кода пользовательского диалогового окна.
Два диалоговых окна UserForm. Одно диалоговое окно (FonciMain) является основным. Второе (FormMenus) используется для отображения текста справочной системы.
Утилита Text Tools доступна на Web-узле издательства. Это отдельная версий инструмента, который входит а состав пакета Power Utility Pak.
Диалоговое окно FormMain
Создание утилиты обычно начинается с разработки пользовательского интерфейса, который в данном случае определяется основным диалоговым окном. Операция по созданию диалогового окна заставляет повторно пересмотреть все концепции проекта.
Диалоговое окно FormMain содержит элемент управления M u l t i P a g e , который включает в себя четыре страницы, соответствующие основным функциям утилиты. На рис. 16.2 показан элемент управления M u l t i P a g e .
Рис. 16.2. Диалоговое окно FormMain содержит элемент управления MultiPage, который состоит из четырех страниц
Элементы управления, которые находятся на страницах элемента управления MultiPage, очень простые, поэтому они рассматриваться не будут (для получения более подробной информации можно обратиться к исходному коду). Диалоговое окно FormMain также содержит до-
полнительные элементы управления за пределами элемента управления M u l t i P a g e . |
|
• Элемент управления R e f E d i t . Процедура U s e r F o r m _ I n i t i a l i z e отображает |
ад- |
рес текущего выделенного диапазона. И конечно, элемент управления R e f E d i t |
по- |
зволяет пользователю выделить другой диапазон в любой момент времени. |
|
Глава 16. Разработка утилит Excel с помощью VBA
• Кнопка Справка. Это элемент управления CommandButton, который содержит изображение. Щелчок на указанной кнопке приводит к отображению диалогового окна FormHelp.
•Кнопка Отменить. Щелчок на данной кнопке приведет к отмене последнего действия.
•Кнопка Стат. Щелчок на данном элементе управления CommandButton приведет к отображению окна сообщения, которое содержит статистические данные о тексте в выделенной:ячейке.
•Кнопка Выход. Щелчок на этом элементе управления CommandButton вызывает аыгрузку из памяти диалогового окна UserForm.
•Кнопка Применить. Щелчок на этом элементе управления CommandButton приводит к применению текстовых параметров, которые установлены на текущей странице элемента управления MultiPage.
Вы можете заметить, что утилита нарушает одно из основных правил разработки, котороеприводилосьранеевэтой главе. Вотличиеот встроенныхдиалоговыхокон Excel, пользовательское окно FormMain не содержит кнопки ОК или Отмена, а по щелчку на кнопке Применить нельзя закрыть диалоговое окно. Первоначальная версия утилиты Text Tools содержала кнопку ОК, и щелчок на ней приводил к выполнениюнеобходимогодействияизакрытиюдиалоговогоокна. Частоеобщениес пользователями доказало целесообразность изменения существующего интерфейса. Большинство людей предпочитают выполнять одновременно несколько операций над текстом в выделенных ячейках. Таким образом, утилита была изменена с целью большего соответствия запросам конечных пользователей.
Модуль modMain
Модуль modMain содержит простую процедуру, которая запускает утилиту.
Объявление данных
Ниже приведены объявления, которые находятся в начале модуля кода modMain. Public Consc APPNAME As S t r i n g = "Text Tools"
"Пользовательский тип данных для отмены действий Type OrigData
OldText As Variant
Address As String End Type
Вначале объявляется глобальная константа, которая содержит строку, хранящую имя приложения. Эта строка используется в окнах сообщений и в качестве заголовка создаваемой команды меню (более подробная информация приводится в разделе "Процедуры создания и удаления команды меню" далее в этой главе).
Кроме того, здесь также создается тип данных, который называется OrigData. Такой тип данных используется для хранения информации, необходимой для отмены выполненной операции.
Процедура StartTextTools
Ниже приведена процедура StartTextTools:
Sub StartTextTools(}
If ValidContext(True, True, False, False, False, True) Then _ FormMain.Show
End Sub
Часть V. Совершенные методы программирования |
42В |
Очевидно, что эта процедура простая. Она вызывает пользовательскую бинарную функцию (ValidContext), которая определяет, подходит ли текущая среда для работы утилиты. Если функция ValidContext возвращает значение True, то отображается диалоговое окно FormMain.
Эта функция принимает шесть аргументов (каждый из которых имеет тип Boolean).
•VisWin. Если имеет значение True, то проверяется отображаемость как минимум одного из окон.
•Wksht. Если имеет значение True, то проверяется активность рабочего листа.
•RngSel. Если имеет значение True, то проверяется присутствие на листе выделенногодиапазона.
•MultiSel. Если имеет значение True, то проверяется содержимое выделенного диапазона.
•Chart. Если имеет значение True, то проверяется выделение диаграммы или листа диаграммы.
•Prot. Если имеет значение True, то проверяется защищенность содержимого активного рабочего листа.
Значения этих аргументов определяют, что же будет проверяться функцией ValidContext. Например, если первый аргумент VisWin имеет значение True, то функция определяет отображаемость как минимум одного окна. Если второй аргумент Wksht имеет значение True, то функция определяет, активен ли рабочий лист. Если одна из указанных проверок завершается неудачно, то функция ValidContext отображает окна сообщения, которое содержит описание возникшей проблемы (рис. 16.3), и возвращает значение False в вызывающую процедуру.
Рис. 16.3, Функция ValidContext отображаетэтоокносообщения, если лист защищен
Утилита Text Tools требует проведения с помощью функции ValidContext следующих проверок.
•Vi sWin. Как минимум одно окно должно отображаться на экране.
•Wksht, Рабочий лист должен быть активен.
•Prot. Лист не должен быть защищен.
Утилита Text Tools не требует наличия выделенного диапазона. Она выполняет процедуру RangeSelection для определения выделенного диапазона в процедуре UserForm_initialize диалогового окна FormMain. Кроме того, утилита абсолютно нормально работает с множественным выделением ячеек,
Функция ValidContext создавалась в качестве универсальной функции, которую можно использовать в других приложениях. Другими словами, в этой функции нет ничего, что гарантировало бы ее выполнение только в утилите Text ToolsВсе утилиты в пакете Power Utility Pak используют данную функцию.
Исходный код функции ValidContext показан в листинге 16.1.
424 Глава 16. РазработкаутилитExcelспомощью VBA
.Листинг 16.1. Проверка возможности запуска утилиты в текущем контексте листа
Function ValidContext(VisWin, Wksht, RngSel, MultSel, _
Chart, Prot) As Boolean
Dim VisWinCnt As Integer
Dim Win As Window
Const MsgVisWin As String = _
"Рабочая книга должна быть активной." Const MsgWksht As String = _
"Рабочая книга должна быть активной." Const MsgRngSel As String = _
"Требуется выделение диапазона." & vbCrLf & _ "Выделите диапазон и попробуйте еше раз."
Const MsgMultSel As String = _
"Эта утилита не приемлет множественного выделения." _ & vtaCrLf & "Выделите всего один диапазон."
Const MsgChart As String = __
"Выделите диаграмму или лист диаграммы." Const MsgProt As String = _
"He допускается использование защищенных рабочих листов." _ & vbCrLf & "Снимите защиту листа и попробуйте еще раз."
ValidContext = True
1Отобращаемость окна If VisWin Then
VisWinCnt = О
For Each Win In Application-Windows
If Win.Visible Then VisWinCnt = VisWinCnt + 1
Next
If VisWinCnt = 0 Then
MsgBox MsgVisWin, vbCritical, APPNAMS
ValidContext = False
Exit Function
End If
End If
' Активный рабочий лист If Wkshc Then
If TypeName(Activesheet) <> "Worksheet" Then MsgBox MsgWksht, vbCritical, АРРШШЕ ValidContext = False
Exit Function End If
End If
1Выделение диапазона If RngSel Then
If TypeName(Selection) <> "Range" Then
MsgBox MsgRngSel, vbCritical, APPNAME
ValidContext = False
Exit Function
End If
End If
'Множественное выделение
Часть V. Совершенные методыпрограммирования |
425 |
If MultSel Then
If TypeName(Selection) = "Range" Then
If Selection.Areas.Count > 1 Then
MsgBox MsgMultSel, vbCritical, APPNAME
Exit Function
End If
End If
End If
1Выделение .диаграммы If Chart Then
|
If ActiveChart Is Nothing Then |
|
|||
|
|
MsgBox MsgChart, vbCritical, |
APPNAME |
||
|
• |
ValidContext = False |
|
||
|
|
Exit |
Function |
|
|
|
End If |
|
|
|
|
|
End If |
|
|
|
|
1 |
Защищенность |
рабочего листа |
|
||
|
If Prot Then |
|
|
|
|
|
If |
ActiveSheet.ProtectContents Then |
|||
|
|
MsgBox MsgProt, |
vbCritical, |
APPNAME |
|
|
|
ValidContext = |
False |
|
|
|
|
Exit Function |
|
|
|
|
End If |
|
|
|
|
|
End If |
|
|
|
|
End |
Function |
|
|
|
Процедура ApplyButton_Click
Работа утилиты Text Tools обеспечивается кодом VBA, который находится в модуле объекта FormMain. Процедура ApplyB\itton_Click из листинга 16.2 выполняется тогда, когда пользователь щелкает на кнопке Применить.
Листинг 16.2. Применение выбранных изменений без закрытия текущего диалогового окна
Private Sub ApplyButton_Click()
1 |
Выполнение указанных операций |
|
|
Dim i As Integer |
|
|
Dim WorkRange As Range |
|
1 |
Проверка ссылки на |
диапазон |
|
If Not ValidReference(RefEditl.Text) Then |
|
|
MsgBox "Диапазон неверен.", vblnformation, APPNAME |
|
|
Application.ScreenUpdating = True |
|
|
• With RefEditl |
|
|
.SelStart = |
0 |
|
.SelLength |
= 100 |
|
.SetFocus |
|
|
End With |
|
|
Exit Sub |
|
|
End If |
1 |
Выяснение выполняемых операций |
426 |
Глава 16. Разработка утилит Excel с помощью VBA |
Application.ScreenUpdating = False
Select Case MultiPagel.Value
Case 0: Call ChangeCaseTab
Case 1: Call AddTextTab
Case 2: Call RemoveTextTab
Case 3: Call RemoveSpacesTab
End Select
Application.ScreenUpdating = True
End Sub
Процедура A p p l y B u t t o n _ C l i c k не вызывает особых трудностей при изучении. Вначале она вызывает функцию ValidRef е г е с е для того, чтобы определить, содержит ли элемент управления Ref E d i t правильный диапазон адресов. Если это не так, то процедура отображает соответствующее сообщение, выделяет текст в элементе управления Ref E d i t и завершает свою работу.
Ниже приведен исходный код функции V a l i d R e f e r e n c e . Эта функция возвращает значение True, если аргумент содержит действительную ссылку на диапазон. В процедуре используется факт, что VBA генерирует сообщение об ошибке при создании недействительного объекта Range.
Function ValidReference(ref As String) As Boolean 'Возвращает True, если RefEdit содержит действительную 'ссылку на диапазон
Dim x As Range
On Error Resume Next Set x = Range(ref)
If Err = 0 Then ValidReference = True _ Else ValidReference = False
End Function
Процедура A p p l y B u t t o n _ C l i c k довольно короткая. Она передает управление другим процедурам в зависимости от значения элемента управления M u l t i P a g e . Значение же элемента управления M u l t i P a g e определяет задачу, выполнение которой затребовано пользователем. (Помните, что первая страница элемента управления M u l t i P a g e соответствует значению 0, а не 1.) Процедуры, выполняющие конкретные задачи, рассматриваются в следующих разделах.
Обратите внимание на то, что процедура A p p l y B u t t o n _ c l i c k не занимается выгрузкой пользовательского диалогового окна. Таким образом, пользователь может выполнить несколько операций над текстом, открыв окно всего один раз. Щелчок на кнопке Выход является единственным способом выгрузки пользовательского окна из памяти. Ниже приведена процедура обработки события щелчка на этой кнопке.
Процедуры выполнения задач
В этом разделе описаны четыре процедуры, которые выполняют операции, возложенные на утилиту Text Tools.
Изменение регистра текста
Первая страница элемента управления M u l t i P a g e (рис. 16.4) предоставляет пользователю возможность изменить регистр текста, находящегося в выделенных ячейках. Текст может быть преобразован в верхний, нижний или в "правильный11 регистр.
ЧастьV.Совершенныеметодыпрограммирования |
427 |
Рис. 16.4. Эта страница позволяет изменятьрегистртекста
Процедура ApplyButton_Click вызывает процедуру ChangeCaseTab в том случае, если значение элемента управления MultiPage равно 0 (т.е. активна первая страница). Листинг 16.3 содержит полный код процедуры ChangeCaseTab.
Листинг16.3.Изменениерегистратекставвыделенныхячейках
Sub ChangeCaseTab(}
Dim WorkRange As Range
Dim Cell As Range
Dim CellCount As Long
Set WorkRange = CreateWorkRange(Range(RefEditl.Text), _
True)
If WorkRange Is Nothing Then Exit Sub
CellCount = 0
ReDim LocalUndo(CellCount)
1Обработать ячейки
For Each Cell In WorkRange
' Сохранить информацию для отмены CellCount = CellCount + 1
ReDim Preserve LocalUndo(CellCount) LocalUndo(CellCount).OldText = Cell.Value LocalUndo(CellCount).Address = Cell.Address
1Изменение регистра Select Case True
|
Case |
ChangeCaseProper |
|
|
|
Cell.Value = Application.Proper(Cell.Value) |
|
|
Case |
ChangeCaseUpper |
|
|
|
Cell.Value = UCase(Cell.Value) |
|
|
Case |
ChangeCaseLower |
|
|
|
Cell.Value = LCase{Cell.Value) |
|
|
End |
Select |
|
|
Next Cell |
|
|
1 |
Обновить состояние |
кнопки Отменить |
|
|
UndoButton.Enabled |
= True |
|
|
UndoButton.Caption = "Undo Case Change" |
||
End Sub |
|
|
Ключевым моментом в этой процедуре являегся создание объекта Range, который называется WorkRange. Объект WorkRange состоит из подмножества ячеек выделенного поль-
428 |
Глава 16. РазработкаутилитExcelспомощью VBA |