matches();
не буферизует, а find()
- буферы. find()
сначала выполняет поиск в конце строки, индексирует результат и возвращает логическое значение и соответствующий индекс.
Вот почему, когда у вас есть такой код, как
1:Pattern.compile("[a-z]");
2:Pattern.matcher("0a1b1c3d4");
3:int count = 0;
4:while(matcher.find()){
5:count++: }
В 4: механизм регулярных выражений с использованием структуры шаблонов будет читать весь ваш код (индекс для индексации, как указано regex[single character]
, чтобы найти хотя бы одно совпадение. Если такое совпадение найдено, оно будет проиндексировано, тогда цикл будет выполняться на основе индексированного результата else, если он не выполнил вычисления, как matches()
; Оператор while никогда не будет выполняться, так как первый символ совпадающей строки не является алфавитом.
debug.? xxx
вместо debug.print xxx
. enum foo: me=0: end enum
в начало модуля, содержащего любой другой код. Объектная модель VBE (расширяемость Visual Basic) является менее известной и / или недостаточно используемой функцией. Это позволяет вам писать код VBA для управления кодом VBA, модулями и проектами. Однажды я написал проект Excel, который собирал другие проекты Excel из группы файлов модулей.
Объектная модель также работает с VBScript и HTA. Однажды я написал HTA, чтобы помочь мне отслеживать большое количество проектов Word, Excel и Access. Во многих проектах использовались бы модули общего кода, и для модулей было легко «расти» в одной системе, а затем их нужно было перенести в другие системы. Мой HTA позволил бы мне экспортировать все модули в проекте, сравнить их с версиями в общей папке и объединить обновленные подпрограммы (используя BeyondCompare), а затем повторно импортировать обновленные модули.
Объектная модель VBE работает немного по-разному между Word, Excel и Access, и, к сожалению, вообще не работает с Outlook, но все же предоставляет отличные возможности для управления кодом.
Этот трюк работает только в Access VBA, Excel и других не позволят. Но вы можете сделать стандартный модуль скрытым от обозревателя объектов, поставив перед именем модуля знак подчеркивания. Модуль будет виден только в том случае, если вы измените браузер объектов для отображения скрытых объектов.
Этот трюк работает с Enums во всех версиях VBA на основе vb6. Вы можете создать скрытого члена Enum, заключив его имя в квадратные скобки, а затем поставив перед ним подчеркивание. Пример:
Public Enum MyEnum
meDefault = 0
meThing1 = 1
meThing2 = 2
meThing3 = 3
[_Min] = meDefault
[_Max] = meThing3
End Enum
Public Function IsValidOption(ByVal myOption As MyEnum) As Boolean
If myOption >= MyEnum.[_Min] Then IsValidOption myOption <= MyEnum.[_Max]
End Function
В Excel-VBA вы можете ссылаться на ячейки, заключая их в скобки, скобки также функционируют как команда оценки , позволяющая оценить синтаксис формулы:
Public Sub Example()
[A1] = "Foo"
MsgBox [VLOOKUP(A1,A1,1,0)]
End Sub
Также вы можете передавать необработанные данные без использования MemCopy (RtlMoveMemory), комбинируя LSet с пользовательскими типами того же размера:
Public Sub Example()
Dim b() As Byte
b = LongToByteArray(8675309)
MsgBox b(1)
End Sub
Private Function LongToByteArray(ByVal value As Long) As Byte()
Dim tl As TypedLong
Dim bl As ByteLong
tl.value = value
LSet bl = tl
LongToByteArray = bl.value
End Function
Octal & amp; Шестнадцатеричные литералы на самом деле являются беззнаковыми типами, они оба будут выводить -32768:
Public Sub Example()
Debug.Print &H8000
Debug.Print &O100000
End Sub
Как уже упоминалось, передача переменной в круглых скобках приводит к ее передаче ByVal:
Sub PredictTheOutput()
Dim i&, j&, k&
i = 10: j = i: k = i
MySub (i)
MySub j
MySub k + 20
MsgBox Join(Array(i, j, k), vbNewLine), vbQuestion, "Did You Get It Right?"
End Sub
Public Sub MySub(ByRef foo As Long)
foo = 5
End Sub
Вы можете назначить строка непосредственно в байтовый массив и наоборот:
Public Sub Example()
Dim myString As String
Dim myBytArr() As Byte
myBytArr = "I am a string."
myString = myBytArr
MsgBox myString
End Sub
«Mid» также является оператором. Используя его, вы перезаписываете определенные части строк без общеизвестно медленной конкатенации строк VBA:
Public Sub Example1()
''// This takes about 47% of time Example2 does:
Dim myString As String
myString = "I liek pie."
Mid(myString, 5, 2) = "ke"
Mid(myString, 11, 1) = "!"
MsgBox myString
End Sub
Public Sub Example2()
Dim myString As String
myString = "I liek pie."
myString = "I li" & "ke" & " pie" & "!"
MsgBox myString
End Sub
Возможно, наименее документированные функции в VBA - это те, которые вы можете открыть, только выбрав «Показать скрытых участников» в Обозревателе объектов VBA. Скрытые члены - это те функции, которые есть в VBA, но не поддерживаются. Вы можете использовать их, но Microsoft может устранить их в любое время. Ни у одного из них нет документации, но вы можете найти ее в Интернете. Возможно, наиболее обсуждаемые из этих скрытых функций предоставляют доступ к указателям в VBA. Для достойной рецензии, проверьте; Не так легко - Shlwapi.dll
Задокументировано, но, возможно, более неясно (в любом случае в Excel) использует ExecuteExcel4Macro для доступа к скрытому глобальному пространству имен, которое принадлежит всему экземпляру приложения Excel, а не конкретная рабочая тетрадь.
Вы можете реализовать интерфейсы с ключевым словом Implements
.
Если вы наберете VBA.
, появится список всех встроенных функций и констант.
Это не функция, а то, что я много раз видел неправильно в VBA (и VB6): в вызовы методов добавлены скобки, где это изменит семантику:
Sub Foo()
Dim str As String
str = "Hello"
Bar (str)
Debug.Print str 'prints "Hello" because str is evaluated and a copy is passed
Bar str 'or Call Bar(str)
Debug.Print str 'prints "Hello World"
End Sub
Sub Bar(ByRef param As String)
param = param + " World"
End Sub
Есть важная, но почти всегда пропущенная особенность оператора Mid (). Вот где Mid () появляется в левой части назначения, в отличие от функции Mid (), которая появляется в правой части или в выражении.
Правило состоит в том, что если целевая строка не является строковым литералом, и это единственная ссылка на целевую строку, а длина вставляемого сегмента соответствует длине заменяемого сегмента, то строка будет быть обработанным как изменчивый для операции.
Что это значит? Это означает, что если вы создаете большой отчет или огромный список строк в одно строковое значение, то использование этого сделает вашу обработку строк намного быстрее.
Вот простой класс, который выигрывает от этого. Он дает вашему VBA такую же возможность StringBuilder, что и .Net.
' Class: StringBuilder
Option Explicit
Private Const initialLength As Long = 32
Private totalLength As Long ' Length of the buffer
Private curLength As Long ' Length of the string value within the buffer
Private buffer As String ' The buffer
Private Sub Class_Initialize()
' We set the buffer up to it's initial size and the string value ""
totalLength = initialLength
buffer = Space(totalLength)
curLength = 0
End Sub
Public Sub Append(Text As String)
Dim incLen As Long ' The length that the value will be increased by
Dim newLen As Long ' The length of the value after being appended
incLen = Len(Text)
newLen = curLength + incLen
' Will the new value fit in the remaining free space within the current buffer
If newLen <= totalLength Then
' Buffer has room so just insert the new value
Mid(buffer, curLength + 1, incLen) = Text
Else
' Buffer does not have enough room so
' first calculate the new buffer size by doubling until its big enough
' then build the new buffer
While totalLength < newLen
totalLength = totalLength + totalLength
Wend
buffer = Left(buffer, curLength) & Text & Space(totalLength - newLen)
End If
curLength = newLen
End Sub
Public Property Get Length() As Integer
Length = curLength
End Property
Public Property Get Text() As String
Text = Left(buffer, curLength)
End Property
Public Sub Clear()
totalLength = initialLength
buffer = Space(totalLength)
curLength = 0
End Sub
А вот пример того, как его использовать:
Dim i As Long
Dim sb As StringBuilder
Dim result As String
Set sb = New StringBuilder
For i = 1 to 100000
sb.Append CStr( i)
Next i
result = sb.Text
Немного поработав, вы можете перебирать пользовательские коллекции следующим образом:
' Write some text in Word first.'
Sub test()
Dim c As New clsMyCollection
c.AddItems ActiveDocument.Characters(1), _
ActiveDocument.Characters(2), _
ActiveDocument.Characters(3), _
ActiveDocument.Characters(4)
Dim el As Range
For Each el In c
Debug.Print el.Text
Next
Set c = Nothing
End Sub
Код пользовательской коллекции (в классе с именем clsMyCollection
):
Option Explicit
Dim m_myCollection As Collection
Public Property Get NewEnum() As IUnknown
' This property allows you to enumerate
' this collection with the For...Each syntax
' Put the following line in the exported module
' file (.cls)!'
'Attribute NewEnum.VB_UserMemId = -4
Set NewEnum = m_myCollection.[_NewEnum]
End Property
Public Sub AddItems(ParamArray items() As Variant)
Dim i As Variant
On Error Resume Next
For Each i In items
m_myCollection.Add i
Next
On Error GoTo 0
End Sub
Private Sub Class_Initialize()
Set m_myCollection = New Collection
End Sub
Поддержка локализованных версий, которые (по крайней мере, в прошлом веке) поддерживали выражения с использованием локализованных значений. Например, Pravda для True и Fałszywy (не совсем уверен, но, по крайней мере, у него был забавный L) для False на польском ... На самом деле английская версия могла читать макросы на любом языке и конвертировать на лету. Однако другие локализованные версии не справятся с этим.
ОТКАЗ.
Скрытые функции
Сам VBA кажется скрытой функцией. Люди, которых я знаю, которые использовали продукты Office в течение многих лет, понятия не имеют, что это даже часть пакета.
Я опубликовал это по нескольким вопросам здесь, но браузер объектов - мое секретное оружие. Если мне нужно быстро написать код ниндзя, но я не знаком с DLL, Object Browser спасет мне жизнь. Это значительно упрощает изучение структур классов, чем MSDN.
Окно локальных переменных также отлично подходит для отладки. Сделайте паузу в своем коде, и он покажет вам все переменные, их имена, их текущие значения и типы в текущем пространстве имен.
И кто мог забыть нашего хорошего друга Immediate Window? Он не только отлично подходит для стандартного вывода Debug.Print, но вы также можете вводить в него команды.
Dictionaries. Без них VBA практически бесполезен!
Обратитесь к Microsoft Scripting Runtime, используйте Scripting.Dictionary
для любой достаточно сложной задачи и живите долго и счастливо.
Scripting Runtime также предоставляет вам FileSystemObject, который также очень рекомендуется.
Начните здесь, затем немного покопайтесь...
http://msdn.microsoft.com/en-us/library/aa164509%28office.10%29.aspx
VBA поддерживает побитовые операторы для сравнения двоичных цифр (битов) двух значений. Например, выражение 4 And 7 оценивает битовые значения 4 (0100) и 7 (0111) и возвращает 4 (бит, который включен в обоих числах). Аналогично, выражение 4 Or 8 оценивает битовые значения в 4 (0100 ) и 8 (1000) и возвращает 12 (1100), то есть биты, в которых любой из них является истинным.
К сожалению, побитовые операторы имеют те же имена в операторах логического сравнения: And, Eqv, Imp, Not, Or и Xor. Это может привести к неоднозначности и даже противоречивым результатам.
В качестве примера откройте окно немедленного выполнения (Ctrl + G) и введите: ? (2 и 4) Это возвращает ноль, поскольку нет общих битов между 2 (0010) и 4 (0100).