Swap Index of Items in a Collection

  • Thread starter Thread starter Chris Picklesimer
  • Start date Start date
C

Chris Picklesimer

I have created a collection class with the code below and fill it with
objects from another class. I have populated a listbox with the
MyObject.Name property of these objects. What I would like to do now is
swap the positions of the items in the collection and then repopulate the
listbox. Is it possible to change the index of items in a collection?

Thanks for any help.

Chris


Option Explicit

Private m_colColumns As Collection
Private m_lngKeyNum As Long

Public Property Get Count() As Long
Count = m_colColumns.Count
End Property

Public Sub AddColumn(ByRef objColumn As clsColumn)
On Error GoTo AddColumnError
m_colColumns.Add objColumn, CStr(m_lngKeyNum) 'objColumn.Name
m_lngKeyNum = m_lngKeyNum + 1
Exit Sub

AddColumnError:
If Err.Number = 457 Then
MsgBox objColumn.Name & " already exists and was not added. Enter
another name."
Else
MsgBox objColumn.Name & " already exists and was not added."
End If

End Sub

Public Function Item(ByVal v_vntIndex As Variant) As clsColumn

On Error Resume Next
Set Item = m_colColumns.Item(v_vntIndex)
If Err.Number <> 0 Then
Set Item = Nothing
End If

End Function
Public Sub Remove(Index As Variant)
m_colColumns.Remove (Index)
End Sub
Private Sub Class_Initialize()
Set m_colColumns = New Collection
m_lngKeyNum = 1
End Sub

Private Sub Class_Terminate()
Set m_colColumns = Nothing
End Sub

Public Property Get NewEnum() As IUnknown

Set NewEnum = m_colColumns.[_NewEnum]

End Property
 
Define SWAP. Are you looking to sort the collection? If so, I can post that
for you. Otherwise, it is possible, but you'll need to write a function to
accommodate. It would be easier to do it with Dictionaries instead of
collections

-- Mike
___________________________
Mike Tuersley
CADalyst's CAD Clinic
Rand IMAGINiT Technologies
___________________________
the trick is to realize that there is no spoon...
 
By SWAP I mean that I would like to be able to change/reorder the index
values of certain items in the collection. For instance, I am currently
adding items to my collection. I then populate a listbox with info from
items of that collection. Later, I may either add or delete items from that
collection. I then clear and then refill the listbox to show the current
items of the collection. The order in which they are displayed in dependent
upon the order in which they were added to the collection. I want to adjust
that order.

In the past I have had listboxes based on array info. I would use a spin
button to reposition the selected item either up or down. Below is an
example using arrays (paste into form with Listbox1 and SpinButton1
controls). I now want to do the same thing with a collection. I hope this
makes it a little more clear.

btw, I read your article in Cadalyst Aug 04 where you mentioned dictionaries
and should give them a serious look.

Thanks.

Chris


Option Explicit
Private m_MyArray(4) As String

Private Sub UserForm_Initialize()

m_MyArray(0) = "A"
m_MyArray(1) = "B"
m_MyArray(2) = "C"
m_MyArray(3) = "D"
m_MyArray(4) = "E"

FillList

End Sub

Private Sub FillList()
Dim i As Integer

ListBox1.Clear
For i = LBound(m_MyArray) To UBound(m_MyArray)
ListBox1.AddItem m_MyArray(i)
Next i

End Sub
Private Sub SpinButton1_SpinDown()
Dim iPos As Integer
Select Case True

Case ListBox1.ListIndex = -1
MsgBox "You must select one!"
Case ListBox1.ListIndex = ListBox1.ListCount - 1
MsgBox "You are at the Bottom!"
Case Else
Swap m_MyArray(ListBox1.ListIndex), m_MyArray(ListBox1.ListIndex +
1)


If ListBox1.ListIndex < ListBox1.ListCount - 1 Then
iPos = ListBox1.ListIndex + 1
End If

FillList
ListBox1.ListIndex = iPos

End Select

End Sub

Private Sub SpinButton1_SpinUp()
Dim iPos As Integer

Select Case True

Case ListBox1.ListIndex = -1
MsgBox "You must select one!"
Case ListBox1.ListIndex = 0
MsgBox "You are at the Top!"
Case Else
Swap m_MyArray(ListBox1.ListIndex), m_MyArray(ListBox1.ListIndex -
1)


If ListBox1.ListIndex > 0 Then
iPos = ListBox1.ListIndex - 1
End If

FillList
ListBox1.ListIndex = iPos

End Select

End Sub


Public Sub Swap(A As String, B As String)
Dim C As String

C = A
A = B
B = C

End Sub
 
Here is what I use for what its worth. It is much the same
as yours. I think the listbox and collection are separate
items. Therefore you'll have to remake the collection with the
listbox if you expect the collection to be ordered the same.

Private Sub spinList_Spindown()
BumpItemDn
End Sub
Private Sub spinList_SpinUp()
BumpItemUp
End Sub

Private Sub BumpItemUp()
Dim t As String
With ufQP.lboxFiles2Plot
For x = 0 To .ListCount - 1
If .Selected(x) = True And x > 0 Then
t = .List(x - 1)
.List(x - 1) = .List(x)
.List(x) = t
.Selected(x - 1) = True
.Selected(x) = False
Exit For
End If
Next
End With
End Sub

Private Sub BumpItemDn()
Dim t As String
With ufQP.lboxFiles2Plot
For x = 0 To .ListCount - 1
If .Selected(x) = True And x < .ListCount - 1 Then
t = .List(x + 1)
.List(x + 1) = .List(x)
.List(x) = t
.Selected(x + 1) = True
.Selected(x) = False
Exit For
End If
Next
End With
End Sub
 
Well when you add an item to a collection, you can specify the Before or
After item. What you could do is capture the place where the 'move' item
should be, remove it, adjust your stored 'insertion point' because all
items below the remove will shift up one, then re-insert the 'move' item.

So in pseudo code:

col.item1 = "Item1"
col.item2 = "Item2"
col.item3 = 'Item3"

-- move 2 to top
iNewPlace = 1
col.remove 2
col.add "Item2", Before:=1

Again, not real code but the idea =)

-- Mike
___________________________
Mike Tuersley
CADalyst's CAD Clinic
Rand IMAGINiT Technologies
___________________________
the trick is to realize that there is no spoon...
 
Back
Top