0

Could anybody please tell me what is the best way to sort a dynamic (key, string) set by the key using VB6. I have tried to use VBA.collections and 2D arrays. But they seems to have a big workaround to do the sort. I also tried with the MSComctlLib.ListView as mentioned in this stackoverflow question.

Dim lvSelectedStyles As MSComctlLib.ListView
Dim listItem As MSComctlLib.listItem
'Some code here
lvSelectedStyles.ListItems.Add Key:=CStr(lngCount) Text:=objParagraph.Key

But this item adding gives an error saying "Object or with block variable not set". If I can go through this I can sort the list view by column and move forward.

Could anybody please let me know a way to overcome this, or if you have any other way to do this, please let me know.

Thank you.

ApsSanj
  • 549
  • 7
  • 23
  • Did you use `Set` to New up `lvSelectedStyles`? – Brian M Stafford Sep 20 '18 at 11:15
  • I tried,But set lvSelectedStyles = New ... vb doesn't give the suggestion MSComctlLib.ListView in here. I am stuck. – ApsSanj Sep 20 '18 at 11:24
  • 1
    It appears a ListView cannot be created using New, so I see a couple of options: first, you could drop a ListView onto a hidden form. Second, you could use a Dictionary and write some custom code to sort it. There are examples on this site and others. – Brian M Stafford Sep 20 '18 at 11:57
  • @BrianMStafford I created a listview (invisible) within my form and using listview.sort , I am now able to do the sort as I wanted. Thank you. – ApsSanj Sep 21 '18 at 09:12
  • It would be possible to create a VB (.NET) or C# class which could do this using .NET framework collections, and access the class from VB6. But this may not be the most expedient / direct approach. – StayOnTarget Sep 21 '18 at 11:28

1 Answers1

3

Try using a Recordset object to do the sorting like this

Option Explicit

Private Function pvSortImpl(vData As Variant, _
            ByVal lKeyType As Long, _
            ByVal lKeySize As Long, _
            ByVal lValueType As Long, _
            ByVal lValueSize As Long) As Variant
    Const adFldIsNullable As Long = 32
    Dim rs              As Object
    Dim vElem           As Variant
    Dim vFields         As Variant
    Dim vRetVal         As Variant
    Dim lIdx            As Long
    Dim oFldKey         As Object
    Dim oFldValue       As Object

    Set rs = CreateObject("ADODB.Recordset")
    rs.Fields.Append "Key", lKeyType, lKeySize, adFldIsNullable
    rs.Fields.Append "Value", lValueType, lValueSize, adFldIsNullable
    rs.Open
    vFields = Array(0, 1)
    For Each vElem In vData
        rs.AddNew vFields, vElem
    Next
    If rs.RecordCount = 0 Then
        vRetVal = Array()
    Else
        rs.Sort = "Key"
        ReDim vRetVal(0 To rs.RecordCount - 1) As Variant
        Set oFldKey = rs.Fields("Key")
        Set oFldValue = rs.Fields("Value")
        rs.MoveFirst
        Do While Not rs.EOF
            vRetVal(lIdx) = Array(oFldKey.Value, oFldValue.Value)
            lIdx = lIdx + 1
            rs.MoveNext
        Loop
    End If
    pvSortImpl = vRetVal
End Function

Public Function SortNumeric(vData As Variant) As Variant
    Const adDouble      As Long = 5
    Const adVarWChar    As Long = 202

    SortNumeric = pvSortImpl(vData, adDouble, 0, adVarWChar, 1000)
End Function

Public Function SortStrings(vData As Variant) As Variant
    Const adVarWChar    As Long = 202

    SortStrings = pvSortImpl(vData, adVarWChar, 202, adVarWChar, 1000)
End Function

Private Sub Form_Load()
    Dim vResult         As Variant

    vResult = SortStrings(Array(Array("bbb", "test"), Array("aaa", Now)))
    Debug.Print Join(vResult(0), "=>")
    Debug.Print Join(vResult(1), "=>")
    vResult = SortNumeric(Array(Array("33", "test"), Array("2.2", Now), Array("22", "Proba")))
    Debug.Print Join(vResult(0), "=>")
    Debug.Print Join(vResult(1), "=>")
    Debug.Print Join(vResult(2), "=>")
End Sub

This prints in Immediate window

aaa=>9/21/2018 11:50:19 AM
bbb=>test
2.2=>9/21/2018 11:50:19 AM
22=>Proba
33=>test
wqw
  • 11,771
  • 1
  • 33
  • 41