A fun project for using a custom collection to create a class object that lets you do what you wish you could with regular strings, iterate through the characters or pull out a single character at specific spot. Can also append, prepend, and replace characters. Some testing, some more probably needed to be done.
Maybe more of a fun example of creating a custom collection. Although I suppose it could be useful, it's not super efficient for intensive uses I guess.
NOTE: This custom collection uses hidden attributes. You CANNOT simply copy and paste this into a class module and expect it to work. You have to copy and paste it into a text file (preferably saved with the .cls extension, I suppose), and then import it into the project using File --> Import File. This allows you to use the short cut to refer to the "Char" attribute (using, for instance, Debug.Print sc(11) instead of Debug.Print sc.Char(11)).
The class will work, but editing and compiling the attributes (like VB_UserMemID = 0) will not work with VBE because it does not directly support it. They will have to be added, removed, and edited outside the VBE.
Here is the code:
Code:
VERSION 1.0 CLASSBEGIN
MultiUse = -1 'True
END
Attribute VB_Name = "StringContainer"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Compare Database
Option Explicit
Dim myCol As Collection, myStr As String
Public Sub Load(setStr As String)
myStr = setStr
If setStr <> vbNullString Then
LoadCollection setStr
End If
End Sub
Public Property Get GetCollection() As Collection
Set GetCollection = myCol
End Property
Public Property Get Length() As Long
If Not myCol Is Nothing Then
Length = myCol.Count
End If
End Property
Public Property Get Value() As String
Value = myStr
End Property
Public Sub Append(addStr As String)
If Me.Length = 0 Then
Me.Load addStr
Else
If addStr <> vbNullString Then
myStr = myStr & addStr
LoadCollection myStr
End If
End If
End Sub
Public Function NewEnum() As IUnknown
Attribute NewEnum.VB_UserMemId = -4
Set NewEnum = myCol.[_NewEnum]
End Function
Public Sub Prepend(preStr As String)
Set myCol = New Collection
myStr = preStr & myStr
LoadCollection myStr
End Sub
Public Sub Insert(insStr As String, insAt As Long)
Dim craftStr As String, sLen As Long
craftStr = Left(myStr, insAt - 1) & insStr & _
Right(myStr, Len(myStr) - (insAt - 1))
myStr = craftStr
LoadCollection myStr
End Sub
Public Sub ReplaceStr(repStr As String, repWith As String, Optional compare As VbCompareMethod)
Dim sLen As Long, rLen As Long
myStr = Replace(myStr, repStr, repWith, compare:=compare)
LoadCollection myStr
End Sub
Public Property Get Char(charNum As Long) As String
Attribute Char.VB_UserMemID = 0
Char = myCol(charNum)
End Property
Public Property Let Char(charNum As Long, setTo As String)
If Me.Length = 1 Then
myCol.Remove charNum
myCol.Add Left(setTo, 1)
myStr = setTo
Else
myCol.Remove charNum
If charNum > 1 Then
myCol.Add Left(setTo, 1), After:=charNum - 1
Else
myCol.Add Left(setTo, 1), Before:=charNum + 1
End If
myStr = Left(myStr, charNum - 1) & setTo & Right(myStr, Len(myStr) - charNum)
End If
End Property
Private Sub LoadCollection(toLoad As String)
Set myCol = New Collection
Dim sLen As Long, i As Long
sLen = Len(toLoad)
For i = 1 To sLen
myCol.Add Mid$(toLoad, i, 1)
Next
End Sub
Private Sub Class_Terminate()
Set myCol = Nothing
End Sub
Here is some Sample Code. Note that I iterate through the collection using a for loop directly against the object, and use the default property "Char" without referring to it directly.
Code:
Public Sub Test() Dim sc As New StringContainer
sc.Load "This is a string"
Debug.Print "Init. Load: " & sc.Value
Debug.Print sc(3)
Debug.Print sc(4)
sc(11) = "S"
Debug.Print "(After char change) Per val: " & sc.Value
Debug.Print "Per col: " & IterateTest(sc)
sc.Append " and more!"
Debug.Print "(After Append) Per val: " & sc.Value
Debug.Print "Per col: " & IterateTest(sc)
sc.Prepend "1) "
Debug.Print "(After Prepend) Per val: " & sc.Value
Debug.Print "Per col: " & IterateTest(sc)
sc.Insert " damn fine", 13
Debug.Print "(Insert str) Per val: " & sc.Value
Debug.Print "Per col: " & IterateTest(sc)
sc.ReplaceStr "Damn", "bleep", vbTextCompare
Debug.Print "(Replace Str) Per val: " & sc.Value
Debug.Print "Per col: " & IterateTest(sc)
End Sub
Public Function IterateTest(inSc As StringContainer) As String
Dim var As Variant, bld As String
For Each var In inSc
bld = bld & var
Next
IterateTest = bld
End Function
Here is the output:
Code:
Init. Load: This is a string
i
s
(After char change) Per val: This is a String
Per col: This is a String
(After Append) Per val: This is a String and more!
Per col: This is a String and more!
(After Prepend) Per val: 1) This is a String and more!
Per col: 1) This is a String and more!
(Insert str) Per val: 1) This is a damn fine String and more!
Per col: 1) This is a damn fine String and more!
(Replace Str) Per val: 1) This is a bleep fine String and more!
Per col: 1) This is a bleep fine String and more!