patternMinor
VBA Python-like List Class
Viewed 0 times
likepythonvbalistclass
Problem
VBA's
The biggest features are better setting and accessing of values. But one neat-o feature is Python-style indexing.
Note: I kept VBA's 1 offset for collections. This means that there is a hole at index 0 and will always return subscript out of range. I don't like it but this way List's will play nice with VBA's collection objects.
Private members
Replace is
Some boring stuff
Public Methods
The general pattern for these is and implementation of one action for a single element and another for a sequence of elements. e.g.
Accessers and Replacement
```
Public Property Let Item(ByVal index As Long, ByVal element As Variant)
Attribute Item.VB_UserMemId
Collection class is lacking so I created a basic List class using Python's as a template. This could make future derived classes easier to implement.The biggest features are better setting and accessing of values. But one neat-o feature is Python-style indexing.
Dim myList As List
myList.Extend(Array(1,2,3,4,5,6))
Debug.Print myList(-2) ' 5
Debug.print myList.Slice(-1, 1).ToString '"[6,5,4,3,2,1]"Note: I kept VBA's 1 offset for collections. This means that there is a hole at index 0 and will always return subscript out of range. I don't like it but this way List's will play nice with VBA's collection objects.
Private members
Option Explicit
Private collec As Collection ' Sole datamemberTransformIndex: Enforces Zero Offset and Cylcing.Private Sub TransformIndex(ByRef x As Variant)
If x < 0 Then x = x + collec.Count + 1
End SubReplace is
private; use Item and Slice to actually replace elementsPrivate Sub Replace(ByVal index As Long, ByVal element As Variant)
collec.Remove index
If index = collec.Count + 1 Then
collec.Add element
Else
collec.Add element, before:=index
End If
End SubSome boring stuff
Private Sub Class_Initialize()
Set collec = New Collection
End Sub
Private Sub Class_Terminate()
Set collec = Nothing
End Sub
Public Property Get NewEnum() As IUnknown
Attribute NewEnum.VB_UserMemId = -4
Set NewEnum = collec.[_NewEnum]
End PropertyPublic Methods
The general pattern for these is and implementation of one action for a single element and another for a sequence of elements. e.g.
Item and then Slice or Append and Extend. The only exception is removal that only implements single elements.Accessers and Replacement
Item and Slice provide general access to members and allows replacement as they are not read only.```
Public Property Let Item(ByVal index As Long, ByVal element As Variant)
Attribute Item.VB_UserMemId
Solution
I'm no VBA coder so just a few minor things:
-
Is there a particular reason to use
-
-
You should take a bit more care naming method parameters. Parameter names form an important part of the method documentation and should convey their intent clearly. For example here it is not exactly clear what
-
For
-
I don't think dumping the entire list content in
-
Is there a particular reason to use
ByRef for the parameter to TransformIndex? It doesn't seem exactly necessary and I usually prefer methods without side effects.-
collec reads clumsy. I would rename it to something like underlying or underlyingCollection.-
You should take a bit more care naming method parameters. Parameter names form an important part of the method documentation and should convey their intent clearly. For example here it is not exactly clear what
a and b mean:Public Sub Clear(ByVal a As Long, ByVal b As Long)-
For
Clear it is not entirely clear if for example the end index is included or not for the removal. C# usually follows the convention of specify the start index and the count of how many elements should be removed (i.e. Clear(start, count)). I found that approach more robust in the long run.-
I don't think dumping the entire list content in
ToString() is all that useful, especially if the list can grow larger it could be problematic.Code Snippets
Public Sub Clear(ByVal a As Long, ByVal b As Long)Context
StackExchange Code Review Q#62963, answer score: 5
Revisions (0)
No revisions yet.