- •Создание динамических структур данных
- •Встроенный динамический класс Collection
- •Создание собственных динамических классов
- •Обертывание коллекции vba
- •Несколько слов об api, Win32, dll
- •Вызов функций и оператор Declare
- •Две кодировки ansi и Unicode
- •Два языка: c и vb. Различия при вызове функций
- •Соответствие между простыми типами данных
- •Структуры языка c и тип, определенный пользователем, в языке vba
- •Об описателях языка c и объектах Windows
- •Void функции языка c
- •Вызов аргументов по ссылке ByRef и по значению ByVal
- •Строковые аргументы при вызове функций Win32 api
- •Примеры работы с Win32 api функциями
- •Работа с окнами
- •Характеристики окружения
- •Вызов функций Win32 api, работающих в Unicode кодировке
- •Обработка ошибок, возникающих при вызове функций Win32 api
- •Функции api и вызов Callback функций
- •Функции высших порядков и конструкция AddressOf
- •Функции перечисления Win32 api
- •Функция EnumWindows
- •Еще один пример работы с функцией EnumWindows
- •Функции Win32 api для работы с таймером
- •Функция SetTimer
- •Функция обратного вызова TimerProc
- •Функция KillTimer
- •Пример создания, работы и удаления таймера
- •Классы как обертка вызовов функций Win32 api
- •Построение класса "ВашТаймер"
- •Использование класса ВашТаймер
- •Операторы
- •Операторы и строки
- •Оператор комментария
- •Присваивание
- •Оператор Let
- •Оператор lSet
- •Оператор rSet
- •Оператор Set
- •Управляющие операторы
- •Условный оператор If Then Else End If
- •Оператор выбора Select Case
- •Цикл For Next
- •Цикл Do...Loop
- •Цикл While...Wend
- •Цикл For Each...Next
- •Работа с каталогами, папками и файлами
- •Изменение текущего диска: оператор ChDrive
- •Изменение текущего каталога (папки): оператор ChDir
- •Создание каталога (папки): оператор MkDir
- •Переименование каталогов (папок) и файлов: оператор Name
- •Удаление каталога (папки): оператор RmDir
- •Установка атрибутов файла: оператор SetAttr
- •Копирование файлов: оператор FileCopy
- •Удаление файлов: оператор Kill
- •Прочие операторы
- •Операции с одним объектом. Оператор With
- •Операции
- •Работа с числовыми данными
- •Математические функции
- •Работа со строками
- •Сравнение строк
- •Сравнение с образцом
- •Основные операции над строками
- •Новые функции для работы со строками
- •Функция InStrRev - поиск последнего вхождения подстроки
- •Функция Replace - замена всех вхождений подстроки
- •Удаление подстроки
- •Разбор строки. Функции Split, Join и Filter
- •Преобразование строки в массив. Функция Split
- •Сборка элементов массива в строку. Функция Join
- •Фильтрация элементов массива. Функция Filter
- •Несколько модификаций встроенных функций
- •Замена, основанная на шаблоне. Функция WildReplace
- •Замена разных символов строки. Функция CharSetReplace
- •Фильтрация, основанная на шаблоне. Функция WildFilter
- •Разбор строки, допускающей разные разделители ее элементов. Функция WildSplit
- •Работа с датами и временем
- •Присваивание значений
- •Встроенные функции для работы с датами
- •Определение текущей даты или времени.
- •Вычисления над датами
- •Функция Timer и хронометраж вычислений
- •Некоторые встроенные функции
- •Функции проверки типов данных
- •Преобразование типов данных
- •Форматирование данных. Функции группы Format
- •Функция Format.
- •Другие функции форматирования
- •Описание и создание процедур
- •Классификация процедур
- •Синтаксис процедур и функций
- •Функции с побочным эффектом
- •Создание процедуры
- •Создание процедур обработки событий
- •Вызовы процедур и функций Вызовы процедур Sub
- •Вызовы функций
- •Использование именованных аргументов
- •Аргументы, являющиеся массивами
- •Конструкция ParamArray
- •Задача о медиане
- •Пользовательские функции, принимающие сложный объект Range
- •Рекурсивные процедуры
- •Деревья поиска
- •Класс TreeNode
- •Класс BinTree
- •Работа со словарем
- •Отладка
- •Написание надежных программ
- •Искусство отладки
- •Средства отладки
- •Панель отладки и команды меню
- •Окна наблюдения
- •Окно локальных переменных - Locals
- •Окно проверки - Immediate
- •Окно контрольных выражений - Watch
Новые функции для работы со строками
В VBA 2000, как мы уже говорили, добавлены полезные функции для работы со строками.
Функция InStrRev - поиск последнего вхождения подстроки
Функция InStrRev симметрично дополняет функцию InStr, аналогично тому, как функция Right дополняет функцию Left. Эта функция ищет вхождение подстроки в строку, но начинает свою работу с правого конца строки. Ее использование может существенно ускорить работу, если заранее известно, что искомая подстрока находится где- то в конце строки - источника. Если вхождение искомой подстроки единственно, то обе функции дают один и тот же результат. При множественном вхождении функция InStr возвращает первое вхождение, в то время как InStrRev - последнее. Ее синтаксис:
InstrRev(stringcheck, stringmatch[, start[, compare]])
Ее параметры имеют тот же смысл, что и у функции InStr, но, заметьте, порядок их задания изменен. Необязательный параметр Start теперь задается третьим по счету. Когда он опущен, то по умолчанию, его значение равно "-1", и поиск начинается с последнего символа. Если вернуться к нашему последнему примеру, то для решения нашей содержательной задачи требовалось определить первое и последнее вхождение символа "\" в строке, задающей путь к файлу. Поэтому обе функции были весьма кстати. Нужно отметить, что это весьма типичная ситуация при разборах текста.
Функция Replace - замена всех вхождений подстроки
Это удивительно, что в наборе встроенных функций не было до сих пор функции Replace. Замена одной подстроки на другую - это одна из основных операций при работе со строками. Поэтому в арсенале практически каждого из программистов была своя версия функции Replace. Теперь можно пользоваться стандартной реализацией. Ее несомненным достоинством является то, что она позволяет заменить не только первое вхождение искомой подстроки, но и все такие вхождения, не требуя организации цикла. С другой стороны, можно ограничиться только заменой первого или нескольких первых вхождений. Рассмотрим синтаксис появившейся функции:
Replace(expression, find, replace[, start[, count[, compare]]])
Первый аргумент expression задает строковое выражение, результат которого определяет строку - источник, в которой осуществляется замена. Аргументы find и Replace задают заменяемую подстроку и ее новое значение. Аргумент Count определяет число замен. Обычно он равен 1, когда речь идет о замене первого вхождения, или опускается, - в этом случае его значение по умолчанию равно "-1", означающее замену всех вхождений. Аргумент compare имеет обычный смысл.
В качестве примера приведем функцию Rep, которую мы постоянно используем в нашей работе в процессе работы над этой книгой. Все примеры в нашей книге проверены в реальной работе, они копируются из модулей VBA. При копировании программного текста в документ Word появляются последовательности пробелов, отражающие структурную запись процедур и функций. Но появление в документах Word двух пробелов подряд считается смертельным грехом. Заменять пробелы табуляцией можно и руками, но, конечно же, лучше написать макрос, решающий эту и другие задачи по приведению текста в форму, требуемую редакцией. Вот текст функции, используемой для этих целей:
Public Sub Rep()
'Эта процедура преобразует выделенный программный текст
'Заменяя пробелы табуляцией и конец абзаца мягким концом строки
Dim TxtRange As String
TxtRange = Selection.Range.Text
'Замена пробелов: 4-х, 3-х и 2-х символом табуляции
TxtRange = Replace(TxtRange, " ", vbTab)
TxtRange = Replace(TxtRange, " ", vbTab)
TxtRange = Replace(TxtRange, " ", vbTab)
'Замена концов абзаца
Selection.Range.Text = Replace(TxtRange, VBA.Chr(13), VBA.Chr(11))
End Sub
Несмотря на всю полезность функции Replace нам пришлось написать еще одну собственную модификацию этой функции. Дело в том, что у Replace есть одна особенность, на которую следует обратить внимание, - возвращаемый ею результат, начинается не с первой позиции, а с позиции, заданной аргументом Start. Так что помимо своей основной роли она еще обрубает голову строки, если только Start, отличается от 1. Поскольку замену зачастую нужно производить не с самого начала, а получать хочется полную строку, то мы написали свой вариант этой функции. Приведем его текст:
Public Function MyReplace(ByVal Expr As String, ByVal find As String, _
ByVal rep As String, Optional ByVal start As Long = 1, Optional
ByVal count As Long = -1, _
Optional ByVal compare As VbCompareMethod = vbBinaryCompare) As String
'Вызов стандартной функции Replace
If start = 1 Then
MyReplace = replace(Expr, find, rep, start, count, compare)
Else
MyReplace = VBA.Left(Expr, start - 1) & replace(Expr, find,
rep, start, count, compare)
End If
End Function
Вот результаты нескольких вызовов Replace и MyReplace в окне отладки:
? Replace("A+B *(D*B +B)","B","C",4,1)
*(D*C +B)
? MyReplace("A+B *(D*B +B)","B","C",4,1)
A+B *(D*C +B)
? MyReplace("A+B *(D*B +B)","B","C",4)
A+B *(D*C +C)