Separate Visual Basic into VB.NET, VBA/VB6 and VBScript (#4725)
* Fix for #2418 (WIP) * Fix for #2418 (WIP) * Remove mistaken aliases * Sort language names; add/move samples * Fix language order; update VBScipt color * Update colors * Update VBA/VB6 color * Reorder languages * PR fixes * Rename VBA to Visual Basic for Applications * Update language IDs; go back to acronym * Fixes for failing tests
This commit is contained in:
Родитель
38a2219f41
Коммит
7fa8ca2836
|
@ -462,7 +462,7 @@ disambiguations:
|
|||
rules:
|
||||
- language: Vim script
|
||||
pattern: '^UseVimball'
|
||||
- language: Visual Basic
|
||||
- language: VBA
|
||||
- extensions: ['.w']
|
||||
rules:
|
||||
- language: OpenEdge ABL
|
||||
|
|
|
@ -5492,6 +5492,34 @@ V:
|
|||
codemirror_mode: go
|
||||
codemirror_mime_type: text/x-go
|
||||
language_id: 603371597
|
||||
VBA:
|
||||
type: programming
|
||||
color: "#867db1"
|
||||
extensions:
|
||||
- ".bas"
|
||||
- ".cls"
|
||||
- ".frm"
|
||||
- ".frx"
|
||||
- ".vba"
|
||||
tm_scope: source.vbnet
|
||||
aliases:
|
||||
- vb6
|
||||
- visual basic 6
|
||||
- visual basic for applications
|
||||
ace_mode: text
|
||||
codemirror_mode: vb
|
||||
codemirror_mime_type: text/x-vb
|
||||
language_id: 399230729
|
||||
VBScript:
|
||||
type: programming
|
||||
color: "#15dcdc"
|
||||
extensions:
|
||||
- ".vbs"
|
||||
tm_scope: source.vbnet
|
||||
ace_mode: text
|
||||
codemirror_mode: vbscript
|
||||
codemirror_mime_type: text/vbscript
|
||||
language_id: 408016005
|
||||
VCL:
|
||||
type: programming
|
||||
color: "#148AA8"
|
||||
|
@ -5573,22 +5601,18 @@ Vim script:
|
|||
- vimrc
|
||||
ace_mode: text
|
||||
language_id: 388
|
||||
Visual Basic:
|
||||
Visual Basic .NET:
|
||||
type: programming
|
||||
color: "#945db7"
|
||||
extensions:
|
||||
- ".vb"
|
||||
- ".bas"
|
||||
- ".cls"
|
||||
- ".frm"
|
||||
- ".frx"
|
||||
- ".vba"
|
||||
- ".vbhtml"
|
||||
- ".vbs"
|
||||
tm_scope: source.vbnet
|
||||
aliases:
|
||||
- vb.net
|
||||
- visual basic
|
||||
- vbnet
|
||||
- vb .net
|
||||
- vb.net
|
||||
tm_scope: source.vbnet
|
||||
ace_mode: text
|
||||
codemirror_mode: vb
|
||||
codemirror_mime_type: text/x-vb
|
||||
|
|
|
@ -0,0 +1,474 @@
|
|||
VERSION 1.0 CLASS
|
||||
BEGIN
|
||||
MultiUse = -1 'True
|
||||
END
|
||||
Attribute VB_Name = "Dictionary"
|
||||
Attribute VB_GlobalNameSpace = False
|
||||
Attribute VB_Creatable = False
|
||||
Attribute VB_PredeclaredId = False
|
||||
Attribute VB_Exposed = True
|
||||
Attribute VB_Description = "Drop-in replacement for Scripting.Dictionary on Mac\r\n\r\nDictionary v1.4.0\r\n(c) Tim Hall - https://github.com/timhall/VBA-Dictionary\r\nAuthor: tim.hall.engr@gmail.com\r\nLicense: MIT (http://www.opensource.org/licenses/mit-license.php)\r\n"
|
||||
''
|
||||
' Dictionary v1.4.1
|
||||
' (c) Tim Hall - https://github.com/timhall/VBA-Dictionary
|
||||
'
|
||||
' Drop-in replacement for Scripting.Dictionary on Mac
|
||||
'
|
||||
' @author: tim.hall.engr@gmail.com
|
||||
' @license: MIT (http://www.opensource.org/licenses/mit-license.php
|
||||
'
|
||||
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ '
|
||||
Option Explicit
|
||||
|
||||
' --------------------------------------------- '
|
||||
' Constants and Private Variables
|
||||
' --------------------------------------------- '
|
||||
|
||||
#Const UseScriptingDictionaryIfAvailable = True
|
||||
|
||||
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
|
||||
|
||||
' dict_KeyValue 0: FormattedKey, 1: OriginalKey, 2: Value
|
||||
Private dict_pKeyValues As Collection
|
||||
Private dict_pKeys() As Variant
|
||||
Private dict_pItems() As Variant
|
||||
Private dict_pObjectKeys As Collection
|
||||
Private dict_pCompareMode As CompareMethod
|
||||
|
||||
#Else
|
||||
|
||||
Private dict_pDictionary As Object
|
||||
|
||||
#End If
|
||||
|
||||
' --------------------------------------------- '
|
||||
' Types
|
||||
' --------------------------------------------- '
|
||||
|
||||
Public Enum CompareMethod
|
||||
BinaryCompare = VBA.vbBinaryCompare
|
||||
TextCompare = VBA.vbTextCompare
|
||||
DatabaseCompare = VBA.vbDatabaseCompare
|
||||
End Enum
|
||||
|
||||
' --------------------------------------------- '
|
||||
' Properties
|
||||
' --------------------------------------------- '
|
||||
|
||||
Public Property Get CompareMode() As CompareMethod
|
||||
Attribute CompareMode.VB_Description = "Set or get the string comparison method."
|
||||
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
|
||||
CompareMode = dict_pCompareMode
|
||||
#Else
|
||||
CompareMode = dict_pDictionary.CompareMode
|
||||
#End If
|
||||
End Property
|
||||
Public Property Let CompareMode(Value As CompareMethod)
|
||||
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
|
||||
If Me.Count > 0 Then
|
||||
' Can't change CompareMode for Dictionary that contains data
|
||||
' http://msdn.microsoft.com/en-us/library/office/gg278481(v=office.15).aspx
|
||||
Err.Raise 5 ' Invalid procedure call or argument
|
||||
End If
|
||||
|
||||
dict_pCompareMode = Value
|
||||
#Else
|
||||
dict_pDictionary.CompareMode = Value
|
||||
#End If
|
||||
End Property
|
||||
|
||||
Public Property Get Count() As Long
|
||||
Attribute Count.VB_Description = "Get the number of items in the dictionary.\n"
|
||||
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
|
||||
Count = dict_pKeyValues.Count
|
||||
#Else
|
||||
Count = dict_pDictionary.Count
|
||||
#End If
|
||||
End Property
|
||||
|
||||
Public Property Get Item(Key As Variant) As Variant
|
||||
Attribute Item.VB_Description = "Set or get the item for a given key."
|
||||
Attribute Item.VB_UserMemId = 0
|
||||
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
|
||||
Dim dict_KeyValue As Variant
|
||||
dict_KeyValue = dict_GetKeyValue(Key)
|
||||
|
||||
If Not IsEmpty(dict_KeyValue) Then
|
||||
If VBA.IsObject(dict_KeyValue(2)) Then
|
||||
Set Item = dict_KeyValue(2)
|
||||
Else
|
||||
Item = dict_KeyValue(2)
|
||||
End If
|
||||
Else
|
||||
' Not found -> Returns Empty
|
||||
End If
|
||||
#Else
|
||||
If VBA.IsObject(dict_pDictionary.Item(Key)) Then
|
||||
Set Item = dict_pDictionary.Item(Key)
|
||||
Else
|
||||
Item = dict_pDictionary.Item(Key)
|
||||
End If
|
||||
#End If
|
||||
End Property
|
||||
Public Property Let Item(Key As Variant, Value As Variant)
|
||||
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
|
||||
If Me.Exists(Key) Then
|
||||
dict_ReplaceKeyValue dict_GetKeyValue(Key), Key, Value
|
||||
Else
|
||||
dict_AddKeyValue Key, Value
|
||||
End If
|
||||
#Else
|
||||
dict_pDictionary.Item(Key) = Value
|
||||
#End If
|
||||
End Property
|
||||
Public Property Set Item(Key As Variant, Value As Variant)
|
||||
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
|
||||
If Me.Exists(Key) Then
|
||||
dict_ReplaceKeyValue dict_GetKeyValue(Key), Key, Value
|
||||
Else
|
||||
dict_AddKeyValue Key, Value
|
||||
End If
|
||||
#Else
|
||||
Set dict_pDictionary.Item(Key) = Value
|
||||
#End If
|
||||
End Property
|
||||
|
||||
Public Property Let Key(Previous As Variant, Updated As Variant)
|
||||
Attribute Key.VB_Description = "Change a key to a different key."
|
||||
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
|
||||
Dim dict_KeyValue As Variant
|
||||
dict_KeyValue = dict_GetKeyValue(Previous)
|
||||
|
||||
If Not VBA.IsEmpty(dict_KeyValue) Then
|
||||
dict_ReplaceKeyValue dict_KeyValue, Updated, dict_KeyValue(2)
|
||||
End If
|
||||
#Else
|
||||
dict_pDictionary.Key(Previous) = Updated
|
||||
#End If
|
||||
End Property
|
||||
|
||||
' ============================================= '
|
||||
' Public Methods
|
||||
' ============================================= '
|
||||
|
||||
''
|
||||
' Add an item with the given key
|
||||
'
|
||||
' @param {Variant} Key
|
||||
' @param {Variant} Item
|
||||
' --------------------------------------------- '
|
||||
Public Sub Add(Key As Variant, Item As Variant)
|
||||
Attribute Add.VB_Description = "Add a new key and item to the dictionary."
|
||||
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
|
||||
If Not Me.Exists(Key) Then
|
||||
dict_AddKeyValue Key, Item
|
||||
Else
|
||||
' This key is already associated with an element of this collection
|
||||
Err.Raise 457
|
||||
End If
|
||||
#Else
|
||||
dict_pDictionary.Add Key, Item
|
||||
#End If
|
||||
End Sub
|
||||
|
||||
''
|
||||
' Check if an item exists for the given key
|
||||
'
|
||||
' @param {Variant} Key
|
||||
' @return {Boolean}
|
||||
' --------------------------------------------- '
|
||||
Public Function Exists(Key As Variant) As Boolean
|
||||
Attribute Exists.VB_Description = "Determine if a given key is in the dictionary."
|
||||
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
|
||||
Exists = Not IsEmpty(dict_GetKeyValue(Key))
|
||||
#Else
|
||||
Exists = dict_pDictionary.Exists(Key)
|
||||
#End If
|
||||
End Function
|
||||
|
||||
''
|
||||
' Get an array of all items
|
||||
'
|
||||
' @return {Variant}
|
||||
' --------------------------------------------- '
|
||||
Public Function Items() As Variant
|
||||
Attribute Items.VB_Description = "Get an array containing all items in the dictionary."
|
||||
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
|
||||
If Me.Count > 0 Then
|
||||
Items = dict_pItems
|
||||
Else
|
||||
' Split("") creates initialized empty array that matches Dictionary Keys and Items
|
||||
Items = VBA.Split("")
|
||||
End If
|
||||
#Else
|
||||
Items = dict_pDictionary.Items
|
||||
#End If
|
||||
End Function
|
||||
|
||||
''
|
||||
' Get an array of all keys
|
||||
'
|
||||
' @return {Variant}
|
||||
' --------------------------------------------- '
|
||||
Public Function Keys() As Variant
|
||||
Attribute Keys.VB_Description = "Get an array containing all keys in the dictionary."
|
||||
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
|
||||
If Me.Count > 0 Then
|
||||
Keys = dict_pKeys
|
||||
Else
|
||||
' Split("") creates initialized empty array that matches Dictionary Keys and Items
|
||||
Keys = VBA.Split("")
|
||||
End If
|
||||
#Else
|
||||
Keys = dict_pDictionary.Keys
|
||||
#End If
|
||||
End Function
|
||||
|
||||
''
|
||||
' Remove an item for the given key
|
||||
'
|
||||
' @param {Variant} Key
|
||||
' --------------------------------------------- '
|
||||
Public Sub Remove(Key As Variant)
|
||||
Attribute Remove.VB_Description = "Remove a given key from the dictionary."
|
||||
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
|
||||
Dim dict_KeyValue As Variant
|
||||
dict_KeyValue = dict_GetKeyValue(Key)
|
||||
|
||||
If Not VBA.IsEmpty(dict_KeyValue) Then
|
||||
dict_RemoveKeyValue dict_KeyValue
|
||||
Else
|
||||
' Application-defined or object-defined error
|
||||
Err.Raise 32811
|
||||
End If
|
||||
#Else
|
||||
dict_pDictionary.Remove Key
|
||||
#End If
|
||||
End Sub
|
||||
|
||||
''
|
||||
' Remove all items
|
||||
' --------------------------------------------- '
|
||||
Public Sub RemoveAll()
|
||||
Attribute RemoveAll.VB_Description = "Remove all information from the dictionary."
|
||||
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
|
||||
Set dict_pKeyValues = New Collection
|
||||
|
||||
Erase dict_pKeys
|
||||
Erase dict_pItems
|
||||
#Else
|
||||
dict_pDictionary.RemoveAll
|
||||
#End If
|
||||
End Sub
|
||||
|
||||
' ============================================= '
|
||||
' Private Functions
|
||||
' ============================================= '
|
||||
|
||||
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
|
||||
|
||||
Private Function dict_GetKeyValue(dict_Key As Variant) As Variant
|
||||
On Error Resume Next
|
||||
dict_GetKeyValue = dict_pKeyValues(dict_GetFormattedKey(dict_Key))
|
||||
Err.Clear
|
||||
End Function
|
||||
|
||||
Private Sub dict_AddKeyValue(dict_Key As Variant, dict_Value As Variant, Optional dict_Index As Long = -1)
|
||||
If Me.Count = 0 Then
|
||||
ReDim dict_pKeys(0 To 0)
|
||||
ReDim dict_pItems(0 To 0)
|
||||
Else
|
||||
ReDim Preserve dict_pKeys(0 To UBound(dict_pKeys) + 1)
|
||||
ReDim Preserve dict_pItems(0 To UBound(dict_pItems) + 1)
|
||||
End If
|
||||
|
||||
Dim dict_FormattedKey As String
|
||||
dict_FormattedKey = dict_GetFormattedKey(dict_Key)
|
||||
|
||||
If dict_Index >= 0 And dict_Index < dict_pKeyValues.Count Then
|
||||
' Shift keys/items after + including index into empty last slot
|
||||
Dim dict_i As Long
|
||||
For dict_i = UBound(dict_pKeys) To dict_Index + 1 Step -1
|
||||
dict_pKeys(dict_i) = dict_pKeys(dict_i - 1)
|
||||
If VBA.IsObject(dict_pItems(dict_i - 1)) Then
|
||||
Set dict_pItems(dict_i) = dict_pItems(dict_i - 1)
|
||||
Else
|
||||
dict_pItems(dict_i) = dict_pItems(dict_i - 1)
|
||||
End If
|
||||
Next dict_i
|
||||
|
||||
' Add key/item at index
|
||||
dict_pKeys(dict_Index) = dict_Key
|
||||
If VBA.IsObject(dict_Value) Then
|
||||
Set dict_pItems(dict_Index) = dict_Value
|
||||
Else
|
||||
dict_pItems(dict_Index) = dict_Value
|
||||
End If
|
||||
|
||||
' Add key-value at proper index
|
||||
dict_pKeyValues.Add Array(dict_FormattedKey, dict_Key, dict_Value), dict_FormattedKey, Before:=dict_Index + 1
|
||||
Else
|
||||
' Add key-value as last item
|
||||
If VBA.IsObject(dict_Key) Then
|
||||
Set dict_pKeys(UBound(dict_pKeys)) = dict_Key
|
||||
Else
|
||||
dict_pKeys(UBound(dict_pKeys)) = dict_Key
|
||||
End If
|
||||
If VBA.IsObject(dict_Value) Then
|
||||
Set dict_pItems(UBound(dict_pItems)) = dict_Value
|
||||
Else
|
||||
dict_pItems(UBound(dict_pItems)) = dict_Value
|
||||
End If
|
||||
|
||||
dict_pKeyValues.Add Array(dict_FormattedKey, dict_Key, dict_Value), dict_FormattedKey
|
||||
End If
|
||||
End Sub
|
||||
|
||||
Private Sub dict_ReplaceKeyValue(dict_KeyValue As Variant, dict_Key As Variant, dict_Value As Variant)
|
||||
Dim dict_Index As Long
|
||||
Dim dict_i As Integer
|
||||
|
||||
dict_Index = dict_GetKeyIndex(dict_KeyValue(1))
|
||||
|
||||
' Remove existing dict_Value
|
||||
dict_RemoveKeyValue dict_KeyValue, dict_Index
|
||||
|
||||
' Add new dict_Key dict_Value back
|
||||
dict_AddKeyValue dict_Key, dict_Value, dict_Index
|
||||
End Sub
|
||||
|
||||
Private Sub dict_RemoveKeyValue(dict_KeyValue As Variant, Optional ByVal dict_Index As Long = -1)
|
||||
Dim dict_i As Long
|
||||
If dict_Index = -1 Then
|
||||
dict_Index = dict_GetKeyIndex(dict_KeyValue(1))
|
||||
End If
|
||||
|
||||
If dict_Index >= 0 And dict_Index <= UBound(dict_pKeys) Then
|
||||
' Shift keys/items after index down
|
||||
For dict_i = dict_Index To UBound(dict_pKeys) - 1
|
||||
dict_pKeys(dict_i) = dict_pKeys(dict_i + 1)
|
||||
|
||||
If VBA.IsObject(dict_pItems(dict_i + 1)) Then
|
||||
Set dict_pItems(dict_i) = dict_pItems(dict_i + 1)
|
||||
Else
|
||||
dict_pItems(dict_i) = dict_pItems(dict_i + 1)
|
||||
End If
|
||||
Next dict_i
|
||||
|
||||
' Resize keys/items to remove empty slot
|
||||
If UBound(dict_pKeys) = 0 Then
|
||||
Erase dict_pKeys
|
||||
Erase dict_pItems
|
||||
Else
|
||||
ReDim Preserve dict_pKeys(0 To UBound(dict_pKeys) - 1)
|
||||
ReDim Preserve dict_pItems(0 To UBound(dict_pItems) - 1)
|
||||
End If
|
||||
End If
|
||||
|
||||
dict_pKeyValues.Remove dict_KeyValue(0)
|
||||
dict_RemoveObjectKey dict_KeyValue(1)
|
||||
End Sub
|
||||
|
||||
Private Function dict_GetFormattedKey(dict_Key As Variant) As String
|
||||
If VBA.IsObject(dict_Key) Then
|
||||
dict_GetFormattedKey = dict_GetObjectKey(dict_Key)
|
||||
ElseIf VarType(dict_Key) = VBA.vbBoolean Then
|
||||
dict_GetFormattedKey = IIf(dict_Key, "-1__-1", "0__0")
|
||||
ElseIf VarType(dict_Key) = VBA.vbString Then
|
||||
dict_GetFormattedKey = dict_Key
|
||||
|
||||
If Me.CompareMode = CompareMethod.BinaryCompare Then
|
||||
' Collection does not have method of setting key comparison
|
||||
' So case-sensitive keys aren't supported by default
|
||||
' -> Approach: Append lowercase characters to original key
|
||||
' AbC -> AbC___b_, abc -> abc__abc, ABC -> ABC_____
|
||||
Dim dict_Lowercase As String
|
||||
dict_Lowercase = ""
|
||||
|
||||
Dim dict_i As Integer
|
||||
Dim dict_Char As String
|
||||
Dim dict_Ascii As Integer
|
||||
For dict_i = 1 To VBA.Len(dict_GetFormattedKey)
|
||||
dict_Char = VBA.Mid$(dict_GetFormattedKey, dict_i, 1)
|
||||
dict_Ascii = VBA.Asc(dict_Char)
|
||||
If dict_Ascii >= 97 And dict_Ascii <= 122 Then
|
||||
dict_Lowercase = dict_Lowercase & dict_Char
|
||||
Else
|
||||
dict_Lowercase = dict_Lowercase & "_"
|
||||
End If
|
||||
Next dict_i
|
||||
|
||||
If dict_Lowercase <> "" Then
|
||||
dict_GetFormattedKey = dict_GetFormattedKey & "__" & dict_Lowercase
|
||||
End If
|
||||
End If
|
||||
Else
|
||||
' For numbers, add duplicate to distinguish from strings
|
||||
' -> 123 -> "123__123"
|
||||
' "123" -> "123"
|
||||
dict_GetFormattedKey = VBA.CStr(dict_Key) & "__" & CStr(dict_Key)
|
||||
End If
|
||||
End Function
|
||||
|
||||
Private Function dict_GetObjectKey(dict_ObjKey As Variant) As String
|
||||
Dim dict_i As Integer
|
||||
For dict_i = 1 To dict_pObjectKeys.Count
|
||||
If dict_pObjectKeys.Item(dict_i) Is dict_ObjKey Then
|
||||
dict_GetObjectKey = "__object__" & dict_i
|
||||
Exit Function
|
||||
End If
|
||||
Next dict_i
|
||||
|
||||
dict_pObjectKeys.Add dict_ObjKey
|
||||
dict_GetObjectKey = "__object__" & dict_pObjectKeys.Count
|
||||
End Function
|
||||
|
||||
Private Sub dict_RemoveObjectKey(dict_ObjKey As Variant)
|
||||
Dim dict_i As Integer
|
||||
For dict_i = 1 To dict_pObjectKeys.Count
|
||||
If dict_pObjectKeys.Item(dict_i) Is dict_ObjKey Then
|
||||
dict_pObjectKeys.Remove dict_i
|
||||
Exit Sub
|
||||
End If
|
||||
Next dict_i
|
||||
End Sub
|
||||
|
||||
Private Function dict_GetKeyIndex(dict_Key As Variant) As Long
|
||||
Dim dict_i As Long
|
||||
For dict_i = 0 To UBound(dict_pKeys)
|
||||
If VBA.IsObject(dict_pKeys(dict_i)) And VBA.IsObject(dict_Key) Then
|
||||
If dict_pKeys(dict_i) Is dict_Key Then
|
||||
dict_GetKeyIndex = dict_i
|
||||
Exit For
|
||||
End If
|
||||
ElseIf VBA.IsObject(dict_pKeys(dict_i)) Or VBA.IsObject(dict_Key) Then
|
||||
' Both need to be objects to check equality, skip
|
||||
ElseIf dict_pKeys(dict_i) = dict_Key Then
|
||||
dict_GetKeyIndex = dict_i
|
||||
Exit For
|
||||
End If
|
||||
Next dict_i
|
||||
End Function
|
||||
|
||||
#End If
|
||||
|
||||
Private Sub Class_Initialize()
|
||||
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
|
||||
Set dict_pKeyValues = New Collection
|
||||
|
||||
Erase dict_pKeys
|
||||
Erase dict_pItems
|
||||
Set dict_pObjectKeys = New Collection
|
||||
#Else
|
||||
Set dict_pDictionary = CreateObject("Scripting.Dictionary")
|
||||
#End If
|
||||
End Sub
|
||||
|
||||
Private Sub Class_Terminate()
|
||||
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
|
||||
Set dict_pKeyValues = Nothing
|
||||
Set dict_pObjectKeys = Nothing
|
||||
#Else
|
||||
Set dict_pDictionary = Nothing
|
||||
#End If
|
||||
End Sub
|
|
@ -0,0 +1,648 @@
|
|||
Attribute VB_Name = "Specs"
|
||||
Private pForDisplay As Boolean
|
||||
Private pUseNative As Boolean
|
||||
|
||||
Public Sub SpeedTest()
|
||||
#If Mac Then
|
||||
' Mac
|
||||
ExecuteSpeedTest CompareToNative:=False
|
||||
#Else
|
||||
' Windows
|
||||
ExecuteSpeedTest CompareToNative:=True
|
||||
#End If
|
||||
End Sub
|
||||
|
||||
Sub ToggleNative(Optional Enabled As Boolean = True)
|
||||
Dim Code As CodeModule
|
||||
Dim Lines As Variant
|
||||
Dim i As Integer
|
||||
|
||||
Set Code = ThisWorkbook.VBProject.VBComponents("Dictionary").CodeModule
|
||||
Lines = Split(Code.Lines(1, 50), vbNewLine)
|
||||
|
||||
For i = 0 To UBound(Lines)
|
||||
If InStr(1, Lines(i), "#Const UseScriptingDictionaryIfAvailable") Then
|
||||
Code.ReplaceLine i + 1, "#Const UseScriptingDictionaryIfAvailable = " & Enabled
|
||||
Exit Sub
|
||||
End If
|
||||
Next i
|
||||
End Sub
|
||||
|
||||
Public Sub RunSpecs()
|
||||
DisplayRunner.IdCol = 1
|
||||
DisplayRunner.DescCol = 1
|
||||
DisplayRunner.ResultCol = 2
|
||||
DisplayRunner.OutputStartRow = 4
|
||||
|
||||
pForDisplay = True
|
||||
DisplayRunner.RunSuite Specs()
|
||||
pForDisplay = False
|
||||
End Sub
|
||||
|
||||
Public Function Specs() As SpecSuite
|
||||
Dim UseNative As Boolean
|
||||
|
||||
#If Mac Then
|
||||
UseNative = False
|
||||
#Else
|
||||
If pUseNative Then
|
||||
UseNative = True
|
||||
pUseNative = False
|
||||
Else
|
||||
If Not pForDisplay Then
|
||||
' Run native specs first
|
||||
pUseNative = True
|
||||
Specs
|
||||
End If
|
||||
|
||||
UseNative = False
|
||||
End If
|
||||
#End If
|
||||
|
||||
Set Specs = New SpecSuite
|
||||
If UseNative Then
|
||||
Specs.Description = "Scripting.Dictionary"
|
||||
Else
|
||||
Specs.Description = "VBA-Dictionary"
|
||||
End If
|
||||
|
||||
Dim Dict As Object
|
||||
Dim Items As Variant
|
||||
Dim Keys As Variant
|
||||
Dim Key As Variant
|
||||
Dim Item As Variant
|
||||
Dim A As New Collection
|
||||
Dim B As New Dictionary
|
||||
|
||||
' Properties
|
||||
' ------------------------- '
|
||||
With Specs.It("should get count of items")
|
||||
Set Dict = CreateDictionary(UseNative)
|
||||
|
||||
Dict.Add "A", 123
|
||||
Dict.Add "B", 3.14
|
||||
Dict.Add "C", "ABC"
|
||||
.Expect(Dict.Count).ToEqual 3
|
||||
|
||||
Dict.Remove "C"
|
||||
.Expect(Dict.Count).ToEqual 2
|
||||
End With
|
||||
|
||||
With Specs.It("should get item by key")
|
||||
Set Dict = CreateDictionary(UseNative)
|
||||
|
||||
Dict.Add "A", 123
|
||||
Dict.Add "B", 3.14
|
||||
Dict.Add "C", "ABC"
|
||||
|
||||
.Expect(Dict.Item("B")).ToEqual 3.14
|
||||
.Expect(Dict.Item("D")).ToBeEmpty
|
||||
.Expect(Dict("B")).ToEqual 3.14
|
||||
.Expect(Dict("D")).ToBeEmpty
|
||||
End With
|
||||
|
||||
With Specs.It("should let item by key")
|
||||
Set Dict = CreateDictionary(UseNative)
|
||||
|
||||
Dict.Add "A", 123
|
||||
Dict.Add "B", 3.14
|
||||
Dict.Add "C", "ABC"
|
||||
|
||||
' Let + New
|
||||
Dict("D") = True
|
||||
|
||||
' Let + Replace
|
||||
Dict("A") = 456
|
||||
Dict("B") = 3.14159
|
||||
|
||||
' Should have correct values
|
||||
.Expect(Dict("A")).ToEqual 456
|
||||
.Expect(Dict("B")).ToEqual 3.14159
|
||||
.Expect(Dict("C")).ToEqual "ABC"
|
||||
.Expect(Dict("D")).ToEqual True
|
||||
|
||||
' Should have correct order
|
||||
.Expect(Dict.Keys()(0)).ToEqual "A"
|
||||
.Expect(Dict.Keys()(1)).ToEqual "B"
|
||||
.Expect(Dict.Keys()(2)).ToEqual "C"
|
||||
.Expect(Dict.Keys()(3)).ToEqual "D"
|
||||
End With
|
||||
|
||||
With Specs.It("should set item by key")
|
||||
Set Dict = CreateDictionary(UseNative)
|
||||
|
||||
Dict.Add "A", 123
|
||||
Dict.Add "B", 3.14
|
||||
Dict.Add "C", "ABC"
|
||||
|
||||
' Set + New
|
||||
Set Dict("D") = CreateDictionary(UseNative)
|
||||
Dict("D").Add "key", "D"
|
||||
|
||||
' Set + Replace
|
||||
Set Dict("A") = CreateDictionary(UseNative)
|
||||
Dict("A").Add "key", "A"
|
||||
Set Dict("B") = CreateDictionary(UseNative)
|
||||
Dict("B").Add "key", "B"
|
||||
|
||||
' Should have correct values
|
||||
.Expect(Dict.Item("A")("key")).ToEqual "A"
|
||||
.Expect(Dict.Item("B")("key")).ToEqual "B"
|
||||
.Expect(Dict.Item("C")).ToEqual "ABC"
|
||||
.Expect(Dict.Item("D")("key")).ToEqual "D"
|
||||
|
||||
' Should have correct order
|
||||
.Expect(Dict.Keys()(0)).ToEqual "A"
|
||||
.Expect(Dict.Keys()(1)).ToEqual "B"
|
||||
.Expect(Dict.Keys()(2)).ToEqual "C"
|
||||
.Expect(Dict.Keys()(3)).ToEqual "D"
|
||||
End With
|
||||
|
||||
With Specs.It("should change key")
|
||||
Set Dict = CreateDictionary(UseNative)
|
||||
|
||||
Dict.Add "A", 123
|
||||
Dict.Add "B", 3.14
|
||||
Dict.Add "C", "ABC"
|
||||
|
||||
Dict.Key("B") = "PI"
|
||||
.Expect(Dict("PI")).ToEqual 3.14
|
||||
End With
|
||||
|
||||
With Specs.It("should use CompareMode")
|
||||
Set Dict = CreateDictionary(UseNative)
|
||||
Dict.CompareMode = 0
|
||||
|
||||
Dict.Add "A", 123
|
||||
Dict("a") = 456
|
||||
Dict.Add "B", 3.14
|
||||
Dict.Add "C", "ABC"
|
||||
|
||||
.Expect(Dict("A")).ToEqual 123
|
||||
.Expect(Dict("a")).ToEqual 456
|
||||
|
||||
Set Dict = CreateDictionary(UseNative)
|
||||
Dict.CompareMode = 1
|
||||
|
||||
Dict.Add "A", 123
|
||||
Dict("a") = 456
|
||||
Dict.Add "B", 3.14
|
||||
Dict.Add "C", "ABC"
|
||||
|
||||
.Expect(Dict("A")).ToEqual 456
|
||||
.Expect(Dict("a")).ToEqual 456
|
||||
End With
|
||||
|
||||
With Specs.It("should allow Variant for key")
|
||||
Set Dict = CreateDictionary(UseNative)
|
||||
|
||||
Key = "A"
|
||||
Dict(Key) = 123
|
||||
.Expect(Dict(Key)).ToEqual 123
|
||||
|
||||
Key = "B"
|
||||
Set Dict(Key) = CreateDictionary(UseNative)
|
||||
.Expect(Dict(Key).Count).ToEqual 0
|
||||
End With
|
||||
|
||||
With Specs.It("should handle numeric keys")
|
||||
Set Dict = CreateDictionary(UseNative)
|
||||
|
||||
Dict.Add 3, 1
|
||||
Dict.Add 2, 2
|
||||
Dict.Add 1, 3
|
||||
Dict.Add "3", 4
|
||||
Dict.Add "2", 5
|
||||
Dict.Add "1", 6
|
||||
|
||||
.Expect(Dict(3)).ToEqual 1
|
||||
.Expect(Dict(2)).ToEqual 2
|
||||
.Expect(Dict(1)).ToEqual 3
|
||||
.Expect(Dict("3")).ToEqual 4
|
||||
.Expect(Dict("2")).ToEqual 5
|
||||
.Expect(Dict("1")).ToEqual 6
|
||||
|
||||
.Expect(Dict.Keys()(0)).ToEqual 3
|
||||
.Expect(Dict.Keys()(1)).ToEqual 2
|
||||
.Expect(Dict.Keys()(2)).ToEqual 1
|
||||
.Expect(TypeName(Dict.Keys()(0))).ToEqual "Integer"
|
||||
.Expect(TypeName(Dict.Keys()(1))).ToEqual "Integer"
|
||||
.Expect(TypeName(Dict.Keys()(2))).ToEqual "Integer"
|
||||
End With
|
||||
|
||||
With Specs.It("should handle boolean keys")
|
||||
Set Dict = CreateDictionary(UseNative)
|
||||
|
||||
Dict.Add True, 1
|
||||
Dict.Add False, 2
|
||||
|
||||
.Expect(Dict(True)).ToEqual 1
|
||||
.Expect(Dict(False)).ToEqual 2
|
||||
|
||||
.Expect(Dict.Keys()(0)).ToEqual True
|
||||
.Expect(Dict.Keys()(1)).ToEqual False
|
||||
.Expect(TypeName(Dict.Keys()(0))).ToEqual "Boolean"
|
||||
.Expect(TypeName(Dict.Keys()(1))).ToEqual "Boolean"
|
||||
End With
|
||||
|
||||
With Specs.It("should handle object keys")
|
||||
Set Dict = CreateDictionary(UseNative)
|
||||
|
||||
Set A = New Collection
|
||||
Set B = New Dictionary
|
||||
|
||||
A.Add 123
|
||||
B.Add "a", 456
|
||||
|
||||
Dict.Add A, "123"
|
||||
Dict.Add B, "456"
|
||||
|
||||
.Expect(Dict(A)).ToEqual "123"
|
||||
.Expect(Dict(B)).ToEqual "456"
|
||||
|
||||
Dict.Remove B
|
||||
Dict.Key(A) = B
|
||||
|
||||
.Expect(Dict(B)).ToEqual "123"
|
||||
End With
|
||||
|
||||
' Methods
|
||||
' ------------------------- '
|
||||
With Specs.It("should add an item")
|
||||
Set Dict = CreateDictionary(UseNative)
|
||||
|
||||
Dict.Add "A", 123
|
||||
Dict.Add "B", 3.14
|
||||
Dict.Add "C", "ABC"
|
||||
Dict.Add "D", True
|
||||
Dict.Add "E", Array(1, 2, 3)
|
||||
Dict.Add "F", Dict
|
||||
|
||||
.Expect(Dict("A")).ToEqual 123
|
||||
.Expect(Dict("B")).ToEqual 3.14
|
||||
.Expect(Dict("C")).ToEqual "ABC"
|
||||
.Expect(Dict("D")).ToEqual True
|
||||
.Expect(Dict("E")(1)).ToEqual 2
|
||||
.Expect(Dict("F")("C")).ToEqual "ABC"
|
||||
End With
|
||||
|
||||
With Specs.It("should check if an item exists")
|
||||
Set Dict = CreateDictionary(UseNative)
|
||||
|
||||
Dict.Add "Exists", 123
|
||||
.Expect(Dict.Exists("Exists")).ToEqual True
|
||||
.Expect(Dict.Exists("Doesn't Exist")).ToEqual False
|
||||
End With
|
||||
|
||||
With Specs.It("should get an array of all items")
|
||||
Set Dict = CreateDictionary(UseNative)
|
||||
|
||||
.Expect(Dict.Items).RunMatcher "Specs.ToBeAnEmptyArray", "to be an empty array"
|
||||
|
||||
Dict.Add "A", 123
|
||||
Dict.Add "B", 3.14
|
||||
Dict.Add "C", "ABC"
|
||||
Dict.Add "D", True
|
||||
|
||||
Items = Dict.Items
|
||||
.Expect(UBound(Items)).ToEqual 3
|
||||
.Expect(Items(0)).ToEqual 123
|
||||
.Expect(Items(3)).ToEqual True
|
||||
|
||||
Dict.Remove "A"
|
||||
Dict.Remove "B"
|
||||
Dict.Remove "C"
|
||||
Dict.Remove "D"
|
||||
.Expect(Dict.Items).RunMatcher "Specs.ToBeAnEmptyArray", "to be an empty array"
|
||||
End With
|
||||
|
||||
With Specs.It("should get an array of all keys")
|
||||
Set Dict = CreateDictionary(UseNative)
|
||||
|
||||
.Expect(Dict.Keys).RunMatcher "Specs.ToBeAnEmptyArray", "to be an empty array"
|
||||
|
||||
Dict.Add "A", 123
|
||||
Dict.Add "B", 3.14
|
||||
Dict.Add "C", "ABC"
|
||||
Dict.Add "D", True
|
||||
|
||||
Keys = Dict.Keys
|
||||
.Expect(UBound(Keys)).ToEqual 3
|
||||
.Expect(Keys(0)).ToEqual "A"
|
||||
.Expect(Keys(3)).ToEqual "D"
|
||||
|
||||
Dict.RemoveAll
|
||||
.Expect(Dict.Keys).RunMatcher "Specs.ToBeAnEmptyArray", "to be an empty array"
|
||||
End With
|
||||
|
||||
With Specs.It("should remove item")
|
||||
Set Dict = CreateDictionary(UseNative)
|
||||
|
||||
Dict.Add "A", 123
|
||||
Dict.Add "B", 3.14
|
||||
Dict.Add "C", "ABC"
|
||||
Dict.Add "D", True
|
||||
|
||||
.Expect(Dict.Count).ToEqual 4
|
||||
|
||||
Dict.Remove "C"
|
||||
|
||||
.Expect(Dict.Count).ToEqual 3
|
||||
End With
|
||||
|
||||
With Specs.It("should remove all items")
|
||||
Set Dict = CreateDictionary(UseNative)
|
||||
|
||||
Dict.Add "A", 123
|
||||
Dict.Add "B", 3.14
|
||||
Dict.Add "C", "ABC"
|
||||
Dict.Add "D", True
|
||||
|
||||
.Expect(Dict.Count).ToEqual 4
|
||||
|
||||
Dict.RemoveAll
|
||||
|
||||
.Expect(Dict.Count).ToEqual 0
|
||||
End With
|
||||
|
||||
' Other
|
||||
' ------------------------- '
|
||||
With Specs.It("should For Each over keys")
|
||||
Set Dict = CreateDictionary(UseNative)
|
||||
|
||||
Set Keys = New Collection
|
||||
For Each Key In Dict.Keys
|
||||
Keys.Add Key
|
||||
Next Key
|
||||
|
||||
.Expect(Keys.Count).ToEqual 0
|
||||
|
||||
Dict.Add "A", 123
|
||||
Dict.Add "B", 3.14
|
||||
Dict.Add "C", "ABC"
|
||||
Dict.Add "D", True
|
||||
|
||||
Set Keys = New Collection
|
||||
For Each Key In Dict.Keys
|
||||
Keys.Add Key
|
||||
Next Key
|
||||
|
||||
.Expect(Keys.Count).ToEqual 4
|
||||
.Expect(Keys(1)).ToEqual "A"
|
||||
.Expect(Keys(4)).ToEqual "D"
|
||||
End With
|
||||
|
||||
With Specs.It("should For Each over items")
|
||||
Set Dict = CreateDictionary(UseNative)
|
||||
|
||||
Set Items = New Collection
|
||||
For Each Item In Dict.Items
|
||||
Items.Add Item
|
||||
Next Item
|
||||
|
||||
.Expect(Items.Count).ToEqual 0
|
||||
|
||||
Dict.Add "A", 123
|
||||
Dict.Add "B", 3.14
|
||||
Dict.Add "C", "ABC"
|
||||
Dict.Add "D", True
|
||||
|
||||
Set Items = New Collection
|
||||
For Each Item In Dict.Items
|
||||
Items.Add Item
|
||||
Next Item
|
||||
|
||||
.Expect(Items.Count).ToEqual 4
|
||||
.Expect(Items(1)).ToEqual 123
|
||||
.Expect(Items(4)).ToEqual True
|
||||
End With
|
||||
|
||||
With Specs.It("should have UBound of -1 for empty Keys and Items")
|
||||
Set Dict = CreateDictionary(UseNative)
|
||||
|
||||
.Expect(UBound(Dict.Keys)).ToEqual -1
|
||||
.Expect(UBound(Dict.Items)).ToEqual -1
|
||||
.Expect(Err.Number).ToEqual 0
|
||||
End With
|
||||
|
||||
' Errors
|
||||
' ------------------------- '
|
||||
Err.Clear
|
||||
On Error Resume Next
|
||||
|
||||
With Specs.It("should throw 5 when changing CompareMode with items in Dictionary")
|
||||
Set Dict = CreateDictionary(UseNative)
|
||||
Dict.Add "A", 123
|
||||
|
||||
Dict.CompareMode = vbTextCompare
|
||||
|
||||
.Expect(Err.Number).ToEqual 5
|
||||
Err.Clear
|
||||
End With
|
||||
|
||||
With Specs.It("should throw 457 on Add if key exists")
|
||||
Set Dict = CreateDictionary(UseNative)
|
||||
|
||||
Dict.Add "A", 123
|
||||
Dict.Add "A", 456
|
||||
|
||||
.Expect(Err.Number).ToEqual 457
|
||||
Err.Clear
|
||||
|
||||
Dict.RemoveAll
|
||||
Dict.Add "A", 123
|
||||
Dict.Add "a", 456
|
||||
|
||||
.Expect(Err.Number).ToEqual 0
|
||||
Err.Clear
|
||||
|
||||
Dict.RemoveAll
|
||||
Dict.CompareMode = vbTextCompare
|
||||
Dict.Add "A", 123
|
||||
Dict.Add "a", 456
|
||||
|
||||
.Expect(Err.Number).ToEqual 457
|
||||
Err.Clear
|
||||
End With
|
||||
|
||||
With Specs.It("should throw 32811 on Remove if key doesn't exist")
|
||||
Set Dict = CreateDictionary(UseNative)
|
||||
|
||||
Dict.Remove "A"
|
||||
|
||||
.Expect(Err.Number).ToEqual 32811
|
||||
Err.Clear
|
||||
End With
|
||||
|
||||
With Specs.It("should throw 457 for Boolean key quirks")
|
||||
Set Dict = CreateDictionary(UseNative)
|
||||
|
||||
Dict.Add True, "abc"
|
||||
Dict.Add -1, "def"
|
||||
|
||||
.Expect(Err.Number).ToEqual 457
|
||||
Err.Clear
|
||||
|
||||
Dict.Add False, "abc"
|
||||
Dict.Add 0, "def"
|
||||
|
||||
.Expect(Err.Number).ToEqual 457
|
||||
Err.Clear
|
||||
End With
|
||||
|
||||
On Error GoTo 0
|
||||
InlineRunner.RunSuite Specs
|
||||
End Function
|
||||
|
||||
Public Sub ExecuteSpeedTest(Optional CompareToNative As Boolean = False)
|
||||
Dim Counts As Variant
|
||||
Counts = Array(5000, 5000, 5000, 5000, 7500, 7500, 7500, 7500)
|
||||
|
||||
Dim Baseline As Collection
|
||||
If CompareToNative Then
|
||||
Set Baseline = RunSpeedTest(Counts, True)
|
||||
End If
|
||||
|
||||
Dim Results As Collection
|
||||
Set Results = RunSpeedTest(Counts, False)
|
||||
|
||||
Debug.Print vbNewLine & "SpeedTest Results:" & vbNewLine
|
||||
PrintResults "Add", Baseline, Results, 0
|
||||
PrintResults "Iterate", Baseline, Results, 1
|
||||
End Sub
|
||||
|
||||
Public Sub PrintResults(Test As String, Baseline As Collection, Results As Collection, Index As Integer)
|
||||
Dim BaselineAvg As Single
|
||||
Dim ResultsAvg As Single
|
||||
Dim i As Integer
|
||||
|
||||
If Not Baseline Is Nothing Then
|
||||
For i = 1 To Baseline.Count
|
||||
BaselineAvg = BaselineAvg + Baseline(i)(Index)
|
||||
Next i
|
||||
BaselineAvg = BaselineAvg / Baseline.Count
|
||||
End If
|
||||
|
||||
For i = 1 To Results.Count
|
||||
ResultsAvg = ResultsAvg + Results(i)(Index)
|
||||
Next i
|
||||
ResultsAvg = ResultsAvg / Results.Count
|
||||
|
||||
Dim Result As String
|
||||
Result = Test & ": " & Format(Round(ResultsAvg, 0), "#,##0") & " ops./s"
|
||||
|
||||
If Not Baseline Is Nothing Then
|
||||
Result = Result & " vs. " & Format(Round(BaselineAvg, 0), "#,##0") & " ops./s "
|
||||
|
||||
If ResultsAvg < BaselineAvg Then
|
||||
Result = Result & Format(Round(BaselineAvg / ResultsAvg, 0), "#,##0") & "x slower"
|
||||
ElseIf BaselineAvg > ResultsAvg Then
|
||||
Result = Result & Format(Round(ResultsAvg / BaselineAvg, 0), "#,##0") & "x faster"
|
||||
End If
|
||||
End If
|
||||
Result = Result
|
||||
|
||||
If Results.Count > 1 Then
|
||||
Result = Result & vbNewLine
|
||||
For i = 1 To Results.Count
|
||||
Result = Result & " " & Format(Round(Results(i)(Index), 0), "#,##0")
|
||||
|
||||
If Not Baseline Is Nothing Then
|
||||
Result = Result & " vs. " & Format(Round(Baseline(i)(Index), 0), "#,##0")
|
||||
End If
|
||||
|
||||
Result = Result & vbNewLine
|
||||
Next i
|
||||
End If
|
||||
|
||||
Debug.Print Result
|
||||
End Sub
|
||||
|
||||
Public Function RunSpeedTest(Counts As Variant, Optional UseNative As Boolean = False) As Collection
|
||||
Dim Results As New Collection
|
||||
Dim CountIndex As Integer
|
||||
Dim Dict As Object
|
||||
Dim i As Long
|
||||
Dim AddResult As Double
|
||||
Dim Key As Variant
|
||||
Dim Value As Variant
|
||||
Dim IterateResult As Double
|
||||
Dim Timer As New PreciseTimer
|
||||
|
||||
For CountIndex = LBound(Counts) To UBound(Counts)
|
||||
Timer.StartTimer
|
||||
|
||||
Set Dict = CreateDictionary(UseNative)
|
||||
For i = 1 To Counts(CountIndex)
|
||||
Dict.Add CStr(i), i
|
||||
Next i
|
||||
|
||||
' Convert to seconds
|
||||
AddResult = Timer.TimeElapsed / 1000#
|
||||
|
||||
' Convert to ops./s
|
||||
If AddResult > 0 Then
|
||||
AddResult = Counts(CountIndex) / AddResult
|
||||
Else
|
||||
' Due to single precision, timer resolution is 0.01 ms, set to 0.005 ms
|
||||
AddResult = Counts(CountIndex) / 0.005
|
||||
End If
|
||||
|
||||
Timer.StartTimer
|
||||
|
||||
For Each Key In Dict.Keys
|
||||
Value = Dict.Item(Key)
|
||||
Next Key
|
||||
|
||||
' Convert to seconds
|
||||
IterateResult = Timer.TimeElapsed / 1000#
|
||||
|
||||
' Convert to ops./s
|
||||
If IterateResult > 0 Then
|
||||
IterateResult = Counts(CountIndex) / IterateResult
|
||||
Else
|
||||
' Due to single precision, timer resolution is 0.01 ms, set to 0.005 ms
|
||||
IterateResult = Counts(CountIndex) / 0.005
|
||||
End If
|
||||
|
||||
Results.Add Array(AddResult, IterateResult)
|
||||
Next CountIndex
|
||||
|
||||
Set RunSpeedTest = Results
|
||||
End Function
|
||||
|
||||
Public Function CreateDictionary(Optional UseNative As Boolean = False) As Object
|
||||
If UseNative Then
|
||||
Set CreateDictionary = CreateObject("Scripting.Dictionary")
|
||||
Else
|
||||
Set CreateDictionary = New Dictionary
|
||||
End If
|
||||
End Function
|
||||
|
||||
Public Function ToBeAnEmptyArray(Actual As Variant) As Variant
|
||||
Dim UpperBound As Long
|
||||
|
||||
Err.Clear
|
||||
On Error Resume Next
|
||||
|
||||
' First, make sure it's an array
|
||||
If IsArray(Actual) = False Then
|
||||
' we weren't passed an array, return True
|
||||
ToBeAnEmptyArray = True
|
||||
Else
|
||||
' Attempt to get the UBound of the array. If the array is
|
||||
' unallocated, an error will occur.
|
||||
UpperBound = UBound(Actual, 1)
|
||||
If (Err.Number <> 0) Then
|
||||
ToBeAnEmptyArray = True
|
||||
Else
|
||||
' Check for case of -1 UpperBound (Scripting.Dictionary.Keys/Items)
|
||||
Err.Clear
|
||||
If LBound(Actual) > UpperBound Then
|
||||
ToBeAnEmptyArray = True
|
||||
Else
|
||||
ToBeAnEmptyArray = False
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
End Function
|
|
@ -0,0 +1,140 @@
|
|||
Class v_Data_ArrayList
|
||||
Private pArrayList
|
||||
|
||||
Private Sub Class_Initialize()
|
||||
Set pArrayList = CreateObject("System.Collections.ArrayList")
|
||||
End Sub
|
||||
|
||||
|
||||
' Properties
|
||||
|
||||
|
||||
Public Property Get Capacity()
|
||||
Capacity = pArrayList.Capacity
|
||||
End Property
|
||||
|
||||
Public Property Let Capacity(intSize)
|
||||
pArrayList.Capacity = intSize
|
||||
End Property
|
||||
|
||||
Public Property Get Count()
|
||||
Count = pArrayList.Count
|
||||
End Property
|
||||
|
||||
Public Property Get IsFixedSize()
|
||||
IsFixedSize = pArrayList.IsFixedSize
|
||||
End Property
|
||||
|
||||
Public Property Get IsReadOnly()
|
||||
IsReadOnly = pArrayList.IsReadOnly
|
||||
End Property
|
||||
|
||||
Public Property Get IsSynchronized()
|
||||
IsSynchronized = pArrayList.IsSynchronized
|
||||
End Property
|
||||
|
||||
Public Default Property Get Item(intIndex)
|
||||
If IsObject(pArrayList(intIndex)) Then
|
||||
Set Item = pArrayList(intIndex)
|
||||
Else
|
||||
Item = pArrayList(intIndex)
|
||||
End If
|
||||
End Property
|
||||
|
||||
Public Property Let Item(intIndex, varInput)
|
||||
pArrayList(intIndex) = varInput
|
||||
End Property
|
||||
|
||||
Public Property Set Item(intIndex, varInput)
|
||||
Set pArrayList(intIndex) = varInput
|
||||
End Property
|
||||
|
||||
Public Property Get SyncRoot()
|
||||
SyncRoot = pArrayList.SyncRoot
|
||||
End Property
|
||||
|
||||
|
||||
' Methods
|
||||
|
||||
|
||||
Public Sub Add(varItem)
|
||||
pArrayList.Add varItem
|
||||
End Sub
|
||||
|
||||
Public Sub Clear()
|
||||
pArrayList.Clear()
|
||||
End Sub
|
||||
|
||||
Public Function Clone()
|
||||
Set Clone = pArrayList.Clone()
|
||||
End Function
|
||||
|
||||
Public Function Contains(varItem)
|
||||
Contains = pArrayList.Contains(varItem)
|
||||
End Function
|
||||
|
||||
Public Function Equals(objItem)
|
||||
Equals = pArrayList.Equals(objItem)
|
||||
End Function
|
||||
|
||||
Public Function GetEnumerator(intStart, intEnd)
|
||||
Set GetEnumerator = pArrayList.GetEnumerator(intStart, intEnd)
|
||||
End Function
|
||||
|
||||
Public Function GetHashCode()
|
||||
GetHashCode = pArrayList.GetHashCode()
|
||||
End Function
|
||||
|
||||
Public Function GetType()
|
||||
GetType = pArrayList.GetType()
|
||||
End Function
|
||||
|
||||
Public Sub Insert(intIndex, varItem)
|
||||
pArrayList.Insert intIndex, varItem
|
||||
End Sub
|
||||
|
||||
Public Sub Remove(varItem)
|
||||
pArrayList.Remove varItem
|
||||
End Sub
|
||||
|
||||
Public Sub RemoveAt(intIndex)
|
||||
pArrayList.RemoveAt intIndex
|
||||
End Sub
|
||||
|
||||
Public Sub Reverse()
|
||||
pArrayList.Reverse()
|
||||
End Sub
|
||||
|
||||
Public Sub Sort()
|
||||
pArrayList.Sort()
|
||||
End Sub
|
||||
|
||||
Public Function ToArray()
|
||||
ToArray = pArrayList.ToArray()
|
||||
End Function
|
||||
|
||||
Public Function ToString()
|
||||
ToString = pArrayList.ToString()
|
||||
End Function
|
||||
|
||||
Public Function TrimToSize()
|
||||
TrimToSize = pArrayList.TrimToSize()
|
||||
End Function
|
||||
|
||||
Private Sub Class_Terminate()
|
||||
Set pArrayList = Nothing
|
||||
End Sub
|
||||
End Class
|
||||
|
||||
If WScript.ScriptName = "v_Data_ArrayList.vbs" Then
|
||||
Dim arraylist
|
||||
Set arraylist = New v_Data_ArrayList
|
||||
|
||||
arraylist.Add "Train"
|
||||
arraylist.Add "Bus"
|
||||
arraylist.Add "Car"
|
||||
arraylist.Add "Bicycle"
|
||||
arraylist.Add "Boat"
|
||||
|
||||
WScript.Echo arraylist(2)
|
||||
End If
|
|
@ -117,7 +117,7 @@ class TestHeuristics < Minitest::Test
|
|||
"TeX" => all_fixtures("TeX", "*.cls"),
|
||||
"ObjectScript" => all_fixtures("ObjectScript", "*.cls"),
|
||||
# Missing heuristics
|
||||
nil => all_fixtures("Apex", "*.cls") + all_fixtures("OpenEdge ABL", "*.cls") + all_fixtures("Visual Basic", "*.cls"),
|
||||
nil => all_fixtures("Apex", "*.cls") + all_fixtures("OpenEdge ABL", "*.cls") + all_fixtures("VBA", "*.cls"),
|
||||
})
|
||||
end
|
||||
|
||||
|
@ -510,7 +510,7 @@ class TestHeuristics < Minitest::Test
|
|||
|
||||
def test_vba_by_heuristics
|
||||
assert_heuristics({
|
||||
"Visual Basic" => all_fixtures("Visual Basic", "*.vba"),
|
||||
"VBA" => all_fixtures("VBA", "*.vba"),
|
||||
"Vim script" => all_fixtures("Vim script", "*.vba")
|
||||
})
|
||||
end
|
||||
|
|
|
@ -420,13 +420,15 @@ This is a list of grammars that Linguist selects to provide syntax highlighting
|
|||
- **UnrealScript:** [textmate/java.tmbundle](https://github.com/textmate/java.tmbundle)
|
||||
- **UrWeb:** [gwalborn/UrWeb-Language-Definition](https://github.com/gwalborn/UrWeb-Language-Definition)
|
||||
- **V:** [0x9ef/vscode-vlang](https://github.com/0x9ef/vscode-vlang)
|
||||
- **VBA:** [angryant0007/VBDotNetSyntax](https://github.com/angryant0007/VBDotNetSyntax)
|
||||
- **VBScript:** [angryant0007/VBDotNetSyntax](https://github.com/angryant0007/VBDotNetSyntax)
|
||||
- **VCL:** [brandonwamboldt/sublime-varnish](https://github.com/brandonwamboldt/sublime-varnish)
|
||||
- **VHDL:** [textmate/vhdl.tmbundle](https://github.com/textmate/vhdl.tmbundle)
|
||||
- **Vala:** [technosophos/Vala-TMBundle](https://github.com/technosophos/Vala-TMBundle)
|
||||
- **Verilog:** [textmate/verilog.tmbundle](https://github.com/textmate/verilog.tmbundle)
|
||||
- **Vim Snippet:** [Alhadis/language-viml](https://github.com/Alhadis/language-viml)
|
||||
- **Vim script:** [Alhadis/language-viml](https://github.com/Alhadis/language-viml)
|
||||
- **Visual Basic:** [angryant0007/VBDotNetSyntax](https://github.com/angryant0007/VBDotNetSyntax)
|
||||
- **Visual Basic .NET:** [angryant0007/VBDotNetSyntax](https://github.com/angryant0007/VBDotNetSyntax)
|
||||
- **Volt:** [textmate/d.tmbundle](https://github.com/textmate/d.tmbundle)
|
||||
- **Vue:** [vuejs/vue-syntax-highlight](https://github.com/vuejs/vue-syntax-highlight)
|
||||
- **Wavefront Material:** [Alhadis/language-wavefront](https://github.com/Alhadis/language-wavefront)
|
||||
|
|
Загрузка…
Ссылка в новой задаче