fastest way to load comboboxes
I need to load 32 comboboxes each with 256 values.
So I though:
Code:
For intN = 0 To 31
For intM = 1 To 256
cboParameter(intN).AddItem (intM)
Next
Next
Problem is that it takes about 4 seconds.
So I added 1 to 256 in each list of the combobox proberties, but somehow 1 to 9 are not displayed.
Who can help me?
Kiter
Re: fastest way to load comboboxes
It should be a bit faster to use a With block, and remove the data type conversion (due to the brackets around intM):
Code:
For intN = 0 To 31
With cboParameter(intN)
For intM = 1 To 256
.AddItem intM
Next
End With
Next
Re: fastest way to load comboboxes
Kiter,
On my machine it takes about a second-and-a-half, however yeah that's just how long it takes. There are ways to keep the user busy while you set that up.
As for the missing 1-9, though ... I can't reproduce that.
I've got 36 combo boxes set up and initializing them the same way you are:
Code:
Private Sub Form_Load()
Dim intN As Integer
Dim intM As Integer
For intN = 0 To 35
Combo1(intN).Clear
For intM = 1 To 256
Combo1(intN).AddItem (intM)
Next
Combo1(intN).ListIndex = 0
Next
End Sub
Originally I was thinking you were trying to put the string representation of intM into the boxes in which case you'd get unprintable characters. Have you declared intM and intN differently than with type Integer? If not, this should work.
If you'd like to ZIP up your project and sent it to me I'd be glad to troubleshoot it with you.
-Max
Re: fastest way to load comboboxes
Quote:
Originally Posted by
si_the_geek
It should be a bit faster to use a With block, and remove the data type conversion (due to the brackets around intM):
Code:
For intN = 0 To 31
With cboParameter(intN)
For intM = 1 To 256
.AddItem intM
Next
End With
Next
That won't speed it up enough to notice. The compiler will still emit the same code when you use the With block - that's just a syntactical convenience for the developer.
-Max
Re: fastest way to load comboboxes
Hi Max Peck,
Thanks for the fast reply.
I did the same as u and the delay was about 5 seconds.
I also recorded it with snagit, but probably because of the recording the delay increased to 10 seconds (see link: http://dl.dropbox.com/u/16885504/combo.avi)
I'm using VB6 on a Windows 7 machine (2,80Ghz / RAM: 8GB)
Re: fastest way to load comboboxes
Try changing the data type of the variables from Integer to Long
It generally provides a minor speed improvement, albeit at the expense of extra memory (2 bytes per variable, which is easily ignored for two non-array variables).
Quote:
Originally Posted by Max Peck
That won't speed it up enough to notice. The compiler will still emit the same code when you use the With block - that's just a syntactical convenience for the developer.
I'm afraid that based on my experience, I will have to disagree with you.
While the behaviour of a With block will be identical to the same code without it, there are many cases where a With block is noticeably faster (presumably due to caching of the object). I don't ever remember a case where the speed was worse using a With block.
I'm not saying that by using With in this case the speed will improve dramatically (or even that it will definitely improve), just that you cannot reliably assume the results.
Re: fastest way to load comboboxes
I just tried it on a XP machine an it took about a second.
So it looks like a Windows 7 issue??
Re: fastest way to load comboboxes
Quote:
Originally Posted by
Kiter
I just tried it on a XP machine an it took about a second.
So it looks like a Windows 7 issue??
check other configs also of each machine? if both same then may be windows 7 issue.
Re: fastest way to load comboboxes
Are you running it inside VB (rather than compiled)?
If so that will make it slower anyway, and on Windows 7 the issue is likely made worse if you haven't ticked the "Disable desktop composition" box in the shortcut to VB.
Re: fastest way to load comboboxes
Curious as to what this achieves. The 1st combo has 256 0's and the last
has 256 31's. What is the user going to select? I mean, wouldn't a two
dimension array achieve the same and load up almost instantaneously?
Re: fastest way to load comboboxes
Quote:
Originally Posted by
VBClassicRocks
The 1st combo has 256 0's and the last
has 256 31's.
Nope, look closer. intM is added to the combos. intM (inner loop) goes from 1 to 256. intN (outer loop) goes from 0 to 31 which are the combobox indexes
Re: fastest way to load comboboxes
This should help a bit
Code:
Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As Any) As Long
Private Const WM_SETREDRAW As Long = &HB
Private Sub Form_Load()
Dim intN As Integer
Dim intM As Integer
For intN = 0 To 31
Combo1(intN).Clear
'// added following line
SendMessage Combo1(intN).hWnd, WM_SETREDRAW, 0&, ByVal 0&
For intM = 1 To 256
Combo1(intN).AddItem intM
Next
Combo1(intN).ListIndex = 0
'// added following line
SendMessage Combo1(intN).hWnd, WM_SETREDRAW, 1&, ByVal 0&
Next
End Sub
Note that there is a promising message that can be sent: CB_INITSTORAGE. However, I cannot find any significant speed increase by using it
Re: fastest way to load comboboxes
Quote:
Originally Posted by
si_the_geek
I'm afraid that based on my experience, I will have to disagree with you.
While the behaviour of a With block will be identical to the same code without it, there are many cases where a With block is noticeably faster (presumably due to caching of the object). I don't ever remember a case where the speed was worse using a With block.
I'm not saying that by using With in this case the speed will improve dramatically (or even that it will definitely improve), just that you cannot reliably assume the results.
I certainly like to use the With block myself - wish there was an analog to it in C#! OK ... we can agree to disagree. I've never benchmarked it but in my commercial applications I've never been able to see a difference, not a significant one anyway. Perhaps it's because I prefer to use the With when it's available. Not worth arguing about. :-)
-Max :D
Re: fastest way to load comboboxes
Quote:
Originally Posted by
Kiter
I just tried it on a XP machine an it took about a second.
So it looks like a Windows 7 issue??
That's about right. I ran it in a VM running XP Professional and it took maybe a second-and-a-half to populate the combos and present the form.
-Max
Re: fastest way to load comboboxes
OK Guys ... here's how to solve the speed problem.
Create a form with, say, 36 combo boxes in a control array. Then, write your form code as follows. (I'll explain it in a sec...)
Code:
Option Explicit
Private Sub cmdOK_Click()
Unload Me
End Sub
Private Sub Combo1_GotFocus(Index As Integer)
Dim i As Integer
If Combo1(Index).ListCount < 256 Then
For i = 2 To 256
Combo1(Index).AddItem (i)
Next
End If
End Sub
Private Sub Form_Load()
Dim i As Integer
For i = 0 To 35
Combo1(i).Clear
Combo1(i).AddItem 1
Combo1(i).ListIndex = 0
Next
End Sub
OK. You will notice that on the Form Load I'm only loading "1" into the combo boxes and setting the ListIndex to 0 to show the first selection. All 36 combos presently have just one item in them.
Next, place code in the GotFocus event that checks to see if the combo receiving focus has yet been populated with all 256 entries. If not, populate them at that time.
This will have 2 effects:
1) The form will present instantaneously with all 36 combos available.
2) All combos will have 256 options to select from but will only be populated when needed.
Let me know if there are any further questions.
-Max :D
Re: fastest way to load comboboxes
Max, nice idea.
However, since I already had the following implementation ready to post, I'll do that too. Thought of this more as a fun challenge
Here we are going to do most stuff by API. We will avoid the Unicode to ANSI conversion for each string added to the combobox and by also including the WM_SETREDRAW message, this screams
Code:
Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As Any) As Long
Private Const WM_SETREDRAW As Long = &HB
Private Const CB_ADDSTRING As Long = &H143
Private Sub Form_Load()
Dim intN As Integer
Dim intM As Integer
Dim arrItems(0 To 4) As Byte
Dim intO As Integer
Dim sPtr As Long
sPtr = VarPtr(arrItems(0))
For intN = 0 To 31
Combo1(intN).Clear
Erase arrItems()
SendMessage Combo1(intN).hWnd, WM_SETREDRAW, 0&, ByVal 0&
' do 1-9
For intM = 49 To 57 ' 1-9
arrItems(0) = intM
SendMessage Combo1(intN).hWnd, CB_ADDSTRING, 0&, ByVal sPtr
Next
' do 10-99
For intO = 49 To 57
arrItems(0) = intO ' tens
For intM = 48 To 57 ' 0-9
arrItems(1) = intM
SendMessage Combo1(intN).hWnd, CB_ADDSTRING, 0&, ByVal sPtr
Next
Next
' do 100-199
arrItems(0) = 49 ' 100 place
For intO = 48 To 57 ' 0-9 tens
arrItems(1) = intO
For intM = 48 To 57 ' 0-9
arrItems(2) = intM
SendMessage Combo1(intN).hWnd, CB_ADDSTRING, 0&, ByVal sPtr
Next
Next
' do 200-249
arrItems(0) = 50 ' 200 place
For intO = 48 To 52 ' 0-4 tens
arrItems(1) = intO
For intM = 48 To 57 ' 0-9
arrItems(2) = intM
SendMessage Combo1(intN).hWnd, CB_ADDSTRING, 0&, ByVal sPtr
Next
Next
' do 250-256
arrItems(1) = 53 ' 50 place
For intM = 48 To 54 ' 0-6
arrItems(2) = intM
SendMessage Combo1(intN).hWnd, CB_ADDSTRING, 0&, ByVal sPtr
Next
Combo1(intN).ListIndex = 0
SendMessage Combo1(intN).hWnd, WM_SETREDRAW, 1&, ByVal 0&
Next
End Sub
The loops are using ASCII values of 0 thru 9, vs decimal values of 0 thru 9
Re: fastest way to load comboboxes
Hi Max Peck,
Had the getfocus also in mind, but could not find out how to program it.
And sorry LaVolpe,
Your lines are a bit to complex for me :-(
Re: fastest way to load comboboxes
Quote:
Originally Posted by
Kiter
And sorry LaVolpe,
Your lines are a bit to complex for me :-(
Umm, copy, paste & try
Re: fastest way to load comboboxes
-- I'm confused, right now: Are you wanting a faster way to source code your ComboBoxes or a way to .AddItem your ComboBoxes???
Re: fastest way to load comboboxes
Quote:
Originally Posted by
Kiter
Hi Max Peck,
Had the getfocus also in mind, but could not find out how to program it.
And sorry LaVolpe,
Your lines are a bit to complex for me :-(
Kiter,
Just code the GetFocus() the way I described. I included the entire form code as an example and described how to set it up. Is there something more you need?
-Max