Ariser
Ariser

Reputation: 107

Can I use System.Collections.Generic.SortedList in VBscript?

I'm trying to generate a sorted list in VBscript doing this:

Set GNDcons = CreateObject( "System.Collections.Generic.SortedList<string, integer>" )

however it doesn't work, I get Scode:800a01ad Is it even possible to use this type in VBscript? I saw there's another SortedList in System.Collections without the possibility of setting the data types but the use was deprecated.

enter image description here

Upvotes: 0

Views: 617

Answers (1)

leeharvey1
leeharvey1

Reputation: 1446

You can use the System.Collections.SortedList type in VBScript; just avoid the System.Collections.Generic types, and constructors requiring parameters.

Here's a simple example:

Dim sl : Set sl = CreateObject("System.Collections.SortedList")
sl.Capacity = 5
sl.Add "Just", 0
sl.Add "One", 1
sl.Add "Of", 2
sl.Add "Many", 3
sl.Add "Examples", 4

Dim i, k, v
For i = 0 To sl.Count-1
    k = sl.GetKey(i)
    v = sl.Item(k)
    WScript.Echo "Item at index " & i & " contains key " & k & " and value " & v
Next

If you want to simulate type constraints for keys and values, then you can create a VBScript wrapper class. For example:

Option Explicit

Class CSortedList
    Private sl
    Private TKeyVarType
    Private TValueVarType

    Private Sub Class_Initialize()
        TKeyVarType = vbEmpty
        TValueVarType = vbEmpty
        Set sl = CreateObject("System.Collections.SortedList")
    End Sub

    Private Sub Class_Terminate()
        Set sl = Nothing
    End Sub

    Public Property Let TKey(ByVal VarType_)
        TKeyVarType = VarType_
    End Property

    Public Property Get TKey()
        TKey = TKeyVarType
    End Property

    Public Property Let TValue(ByVal VarType_)
        TValueVarType = VarType_
    End Property

    Public Property Get TValue()
        TValue = TValueVarType
    End Property

    Public Property Let Capacity(ByVal v_)
        sl.Capacity = v_
    End Property

    Public Property Get Capacity()
        Capacity = sl.Capacity
    End Property

    Public Property Get Count()
        Count = sl.Count
    End Property

    Public Property Get IsFixedSize()
        IsFixedSize = sl.IsFixedSize
    End Property

    Public Property Get IsReadOnly()
        IsReadOnly = sl.IsReadOnly
    End Property

    Public Property Get IsSynchronized()
        IsSynchronized = sl.IsSynchronized
    End Property

    Public Property Let Item(ByVal key, ByVal value)
        If VarType(key) <> TKeyVarType Then
            WScript.StdErr.WriteLine "Error: Wrong type for key"
        ElseIf VarType(value) <> TValueVarType Then
            WScript.StdErr.WriteLine "Error: Wrong type for value"
        Else
            sl.Item(key) = value
        End If
    End Property

    Public Property Get Item(ByVal key)
        If VarType(key) <> TKeyVarType Then
            WScript.StdErr.WriteLine "Error: Wrong type for key"
        ElseIf vbObject = VarType(sl.Item(key)) Then
            Set Item = sl.Item(key)
        Else
            Item = sl.Item(key)
        End If
    End Property

    Public Property Get Keys()
        Set Keys = sl.Keys
    End Property

    Public Property Get SyncRoot()
        Set SyncRoot = sl.SyncRoot
    End Property

    Public Property Get Values()
        Set Values = sl.Values
    End Property

    Public Sub Add(ByVal key, ByVal value)
        If VarType(key) <> TKeyVarType Then
            WScript.StdErr.WriteLine "Error: Wrong type for key"
        ElseIf VarType(value) <> TValueVarType Then
            WScript.StdErr.WriteLine "Error: Wrong type for value"
        Else
            sl.Add key, value
        End If
    End Sub

    Public Sub Clear()
        sl.Clear
    End Sub

    Public Function Clone()
        Set Clone = sl.Clone()
    End Function

    Public Function Contains(ByVal key)
        If VarType(key) <> TKeyVarType Then
            WScript.StdErr.WriteLine "Error: Wrong type for key"
        Else
            Contains = sl.Contains(key)
        End If
    End Function

    Public Function ContainsKey(ByVal key)
        ContainsKey = Contains(key)
    End Function

    Public Function ContainsValue(ByVal value)
        If VarType(value) <> TValueVarType Then
            WScript.StdErr.WriteLine "Error: Wrong type for value"
        Else
            ContainsValue = sl.ContainsValue(value)
        End If
    End Function

    Public Function GetByIndex(ByVal index)
        If vbObject = VarType(sl.GetByIndex(index)) Then
            Set GetByIndex = sl.GetByIndex(index)
        Else
            GetByIndex = sl.GetByIndex(index)
        End If
    End Function

    Public Function GetEnumerator()
        Set GetEnumerator = sl.GetEnumerator()
    End Function

    Public Function GetKey(ByVal index)
        If vbObject = sl.GetKey(index) Then
            Set GetKey = sl.GetKey(index)
        Else
            GetKey = sl.GetKey(index)
        End If
    End Function

    Public Function GetKeyList()
        Set GetKeyList = sl.GetKeyList()
    End Function

    Public Function GetValueList()
        Set GetValueList = sl.GetValueList()
    End Function

    Public Function IndexOfKey(ByVal key)
        If VarType(key) <> TKeyVarType Then
            WScript.StdErr.WriteLine "Error: Wrong type for key"
        Else
            IndexOfKey = sl.IndexOfKey(key)
        End If
    End Function

    Public Function IndexOfValue(ByVal value)
        If VarType(value) <> TValueVarType Then
            WScript.StdErr.WriteLine "Error: Wrong type for value"
        Else
            IndexOfValue = sl.IndexOfValue(value)
        End If
    End Function

    Public Sub Remove(ByVal key)
        If VarType(key) <> TKeyVarType Then
            WScript.StdErr.WriteLine "Error: Wrong type for key"
        Else
            sl.Remove key
        End If
    End Sub

    Public Sub RemoveAt(ByVal index)
        sl.RemoveAt index
    End Sub

    Public Sub SetByIndex(ByVal index, ByVal value)
        If VarType(value) <> TValueVarType Then
            WScript.StdErr.WriteLine "Error: Wrong type for value"
        Else
            sl.SetByIndex index, value
        End If
    End Sub

    Public Sub TrimToSize()
        sl.TrimToSize
    End Sub
End Class

With New CSortedList
    .TKey = vbString
    .TValue = vbInteger
    .Capacity = 5
    .Add "Just", 0
    .Add "One", 1
    .Add "Of", 2
    .Add "Many", 3
    .Add "Examples", 4

    Dim i, k, v
    For i = 0 To .Count-1
        k = .GetKey(i)
        v = .Item(k)
        WScript.Echo "Item at index " & i & " contains key " & k & " and value " & v
    Next
End With

Note: The above wrapper class has not been 100% tested, but does restrict keys to Variant string subtypes, and values to Variant integer subtypes. The resulting list is automatically sorted by keys.

Output:

Item at index 0 contains key Examples and value 4
Item at index 1 contains key Just and value 0
Item at index 2 contains key Many and value 3
Item at index 3 contains key Of and value 2
Item at index 4 contains key One and value 1

Upvotes: 2

Related Questions