|
-
Oct 30th, 2006, 06:40 PM
#1
Thread Starter
Hyperactive Member
Way around DoEvents taking forever
Everyone knows DoEvents takes forever if you're doing anything lengthly with it(adding a large amount of items to a listbox, for example). But it lets you do other tasks, so it's great in that respect.
But let's say you want a label to be a real-time display of items being added to the listbox(like a counter), but you're adding a large number of items to the listbox and you don't want it to take FOREVER. There's a way around it, and it's very simple. I'm sure a lot of people already know about this, but for the folks who don't(possibly new to VB), this will let you have the best of both worlds with DoEvents:
VB Code:
Public Function sysDoEventsIf(doIf As Integer, isDivisibleBy As Integer) As Boolean
On Error GoTo endWithoutEvents
If doIf = 0 Then GoTo endWithoutEvents
If doIf < isDivisibleBy Then GoTo endWithoutEvents
Dim divisResult As Integer
divisResult = (doIf / isDivisibleBy)
If divisResult < 1 Then GoTo endWithoutEvents
If InStrB((doIf / isDivisibleBy), ".") > 0 Then GoTo endWithoutEvents
sysDoEventsIf = True
DoEvents
endWithoutEvents:
End Function
What does that do? It checks if the variable you specify is equally divisible by anothe specified number, and then ONLY does "DoEvents" if it is. How is that useful? Here's an example:
VB Code:
Private Sub Command1_Click()
Dim d As Boolean
Dim i As Integer
For i = 0 To 24999
d = sysDoEventsIf(i, 100)
List1.AddItem "Item " & i, i
If d = True Then Label1.Caption = "Items: " & List1.ListCount
Next i
Label1.Caption = "Items: " & List1.ListCount
End Sub
This button(Command1) adds 25,000 items to a listbox. The kicker is it will only call DoEvents to free up the process if the current step(defined as "i") is divisible by 100. So rather than calling DoEvents on EVERY step(making the process take a lot longer), it will only call it every 10 steps!
You can make it call DoEvents as often as you want. Change the function call to "d = sysDoEventsIf(i, 1000)" and it will only call DoEvents if the current step integer is divisible by 1000 evenly.
NOTE: The larger the number you're trying to divide it by, the quicker it goes. The smaller the number you're trying to divide it by, the slower it will go.
Hope this helps some folks with... whatever.
-Brendan
-
Oct 30th, 2006, 07:26 PM
#2
Re: Way around DoEvents taking forever
this is typically done with Mod:
VB Code:
Private Sub Command1_Click()
Dim I As Integer
For I = 0 To 24999
List1.AddItem "Item " & I
If I Mod 1000 = 0 Then DoEvents
Next I
End Sub
-
Oct 31st, 2006, 09:24 AM
#3
Thread Starter
Hyperactive Member
Re: Way around DoEvents taking forever
 Originally Posted by bushmobile
this is typically done with Mod:
VB Code:
Private Sub Command1_Click()
Dim I As Integer
For I = 0 To 24999
List1.AddItem "Item " & I
If I Mod 1000 = 0 Then DoEvents
Next I
End Sub
Hmm, I'm not familiar with Mod. See, learn something new every day. Does it check if it's equally divisible each time or does it just check if it is equal to 1000(or whatever integer you specify)?
-
Oct 31st, 2006, 09:27 AM
#4
Re: Way around DoEvents taking forever
it returns the remainder: Mod
-
Oct 31st, 2006, 09:32 AM
#5
Re: Way around DoEvents taking forever
First of all, you posted in the wrong forum, this is the CodeBank, where you post working code pro programs that you think other people might need (and is not already in the CodeBank).
This thread should be moved.
About your question:
Mod means Modulus, and it calculates the reminder from a division.
For example:
you divide 9 by 5, you get the result 1 (5 does not go into 9 two times), and the reminder is 4.
So, as I was saing Mod returns the reminder of a division: 9 Mod 5 = 4
So this line:
VB Code:
If I Mod 1000 = 0 Then DoEvents
Executes DoEvents every 1000'th time, because only then the reminder is equal to 0...
-
Oct 31st, 2006, 02:17 PM
#6
Thread Starter
Hyperactive Member
Re: Way around DoEvents taking forever
CVM, my codes DOES work. Just because it's a longer way around, doesn't mean it doesn't work.
...and my apologies, I was just trying to help. I could have benefit from examples like this, however unprofessional they may be, when I was just starting out.
-
Oct 31st, 2006, 02:50 PM
#7
Re: Way around DoEvents taking forever
Sorry, when I first read you post, it looked more like a question to me rather than a CodeBank entry.
-
Oct 31st, 2006, 03:25 PM
#8
Re: Way around DoEvents taking forever
whilst your code does work and does reduce the speed of the loop in comparison to calling DoEvents everytime, it still causes the loop to suffer a significant drop in performance. Consider this:
VB Code:
Private Sub Command1_Click()
Dim N As Long, lTimer As Long, lRet As Long
lTimer = GetTickCount
For N = 0 To 20000000
lRet = N
Next N
Print GetTickCount - lTimer
End Sub
that takes 16~31 milliseconds on my comp to execute.
With If N Mod 1000 = 0 Then DoEvents in the loop it takes ~500 milliseconds
and with bln = sysDoEventsIf(N, 1000) in the loop it takes ~13750 milliseconds.
-
Nov 11th, 2006, 02:56 AM
#9
Re: Way around DoEvents taking forever
Or use the GetInputState API function.
VB Code:
If GetInputState Then DoEvents
There's an even better API function to use, but I forget what it is.
-
Nov 15th, 2006, 05:12 PM
#10
Re: Way around DoEvents taking forever
 Originally Posted by DigiRev
There's an even better API function to use, but I forget what it is.
This should jog your memory.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|