Speed up selecting all items in list box

  • Thread starter Thread starter Nelson
  • Start date Start date
N

Nelson

Is there a faster way to select all items in an extended multiselect listbox
with a high ListCount than?

Me.Painting = False
For i = 0 To ProcedureList.ListCount - 1
ProcedureList.Selected(i) = True
Next i
Me.Painting = True

When ProcedureList.ListCount is higher than ~2000, the above procedure takes
10+ seconds.

Clicking on the first item, scrolling to the bottom and shift clicking on
the last item selects all items almost instantly so I tried to simulate that
in code. These attempts did not work but maybe they will give someone an
idea:

ProcedureList.SetFocus
hWndSB = GetFocus
ProcedureList.ListIndex = 0
SendKeys " "
ProcedureList.ListIndex = ProcedureList.ListCount - 1
SendKeys "+ "

ProcedureList.SetFocus
hWndSB = GetFocus
ProcedureList.ListIndex = 0
LngThumb = MakeDWord(SB_THUMBPOSITION, CInt(ProcedureList.ListCount - 1))
lngRet = SendMessage(hWndSB, WM_VSCROLL, LngThumb, 0&)
SendKeys "+ "
 
Just guessing, but Send Keys may do it. If you select the first item then
send Ctrl+Shift+End, it should select everything in the listbox.

I just tried the following and it worked. However, the test list didn't have
enough entries to verify the speed.

Me.List0.Selected(0) = True
Me.List0.SetFocus
SendKeys "^+{END}"
 
Wayne,

I tried:

Me.List0.Selected(0) = True
Me.List0.SetFocus
SendKeys "^+{END}"

but it only highlighted the items displayed not all of them, however;

Me.List0.SetFocus
SendKeys "^{END}"
SendKeys "^+{HOME}"

highlighted all the items, however neither actually selects the items, just
highlights them. I think we are one a track that might work.

Nelson
 
I use a generic sub in my applications:

Sub LBOSelectAll(lboCtl As ListBox)
Dim itm
Dim intI
For intI = 0 To lboCtl.ListCount
lboCtl.Selected(intI) = True
Next
End Sub

You call it with code in a form like
LBOSelectAll Me.lboEmployees
 
Duane,

I'm using that routine now but it is too slow when ListCount > ~2000 items.

Nelson
 
Actually, my code for using multi-select list box results will ignore a list
box if none of the values are selected. This would be virtually the same as
selecting all values.
 
Duane,

Perhaps I am missing something. You define Itm with Dim itm but then I
don't see that you are using itm. Other than that, what I see is you are
iterating through each item in lboCtl and making it true. Am I right?

Nelson
 
Since you had to go to the end first, it appears that Access may not have
grabbed all of the items in the list to start with, but only when you forced
it to. If that is the case, then going through on item at a time to select
it may be so slow because Access keeps going back to get the next item in
the list. What happens if you move to the end of the list first, as you did,
then loop through to select the items. That's the only other thing I can
think of since, as you said, the other way highlights them but doesn't
select them.

On the other hand, there may be one more possibility. The highlighted items
may become selected after the list box updates. It may not update until you
move the focus from it. What happens if you highlight all of them then move
the focus to another control? Do the highlighted items then become selected
items?
 
ps.

If moving the focus doesn't "force the update", what happens if you send an
Enter key after highlighting all of them?
 
Wayne,

This is what I ended up with. This simulates setting every item true and
does it very quickly:

Dim ListBoxIsSelected As Boolean

Private Sub Form_Open(Cancel As Integer)
ListBoxIsSelected = False
.....
End Sub

Private Sub ListBoxRequeryButton_Click()
ListBoxIsSelected = False
.....
End Sub

' The SendKeys routine activates the ListBox click and update events,
' but does not change the ListBox.ItemsSelected collection.
' The MouseDown event signals the user has clicked in the ListBox

Private Sub ListBox_MouseDown(Button As Integer, Shift As Integer, X As
Single, Y As Single)
ListBoxIsSelected = True
End Sub

' Then at the point in code where I create the filter:

Private Function CreateReportFilter() As String
Dim strIn As String, varItm As Variant

strIn = ""

For Each varItm In ListBox.ItemsSelected
strIn = strIn & ListBox.Column(8, varItm) & ","
Next varItm

If strIn <> "" Then
CreateReportFilter = "ctlFilter In(" & Left(strIn, Len(strIn) - 1) & ")"
Else
If SelectedProcedure Then
CreateReportFilter = "ctlFilter = 0" 'no records
Else
CreateReportFilter = "ctlFilter > 0" 'all records
ListBox.SetFocus
SendKeys "^{END}"
SendKeys "^+{HOME}"
End If
End If
End Function

Thanks for your help!
Nelson
 
I tried moving the focus to another control, sending enter, ^enter, up, down
and bunches of other key combinations but the highlighted items did not show
up in the ItemsSelected collection unless I clicked in the ListBox. So, I
ended up faking out selecting all with the code I sent you.
 
Back
Top