Results 1 to 10 of 10

Thread: Way around DoEvents taking forever

  1. #1

    Thread Starter
    Hyperactive Member BrendanDavis's Avatar
    Join Date
    Oct 2006
    Location
    Florida
    Posts
    492

    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:
    1. Public Function sysDoEventsIf(doIf As Integer, isDivisibleBy As Integer) As Boolean
    2.  
    3.     On Error GoTo endWithoutEvents
    4.    
    5.     If doIf = 0 Then GoTo endWithoutEvents
    6.     If doIf < isDivisibleBy Then GoTo endWithoutEvents
    7.        
    8.         Dim divisResult As Integer
    9.         divisResult = (doIf / isDivisibleBy)
    10.            
    11.             If divisResult < 1 Then GoTo endWithoutEvents
    12.                 If InStrB((doIf / isDivisibleBy), ".") > 0 Then GoTo endWithoutEvents
    13.                    
    14.                     sysDoEventsIf = True
    15.                     DoEvents
    16.                
    17. endWithoutEvents:
    18.  
    19. 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:
    1. Private Sub Command1_Click()
    2.    
    3.     Dim d As Boolean
    4.     Dim i As Integer
    5.    
    6.     For i = 0 To 24999
    7.         d = sysDoEventsIf(i, 100)
    8.         List1.AddItem "Item " & i, i
    9.             If d = True Then Label1.Caption = "Items: " & List1.ListCount
    10.     Next i
    11.    
    12.     Label1.Caption = "Items: " & List1.ListCount
    13.  
    14. 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

  2. #2
    Oi, fat-rag! bushmobile's Avatar
    Join Date
    Mar 2004
    Location
    on the poop deck
    Posts
    5,592

    Re: Way around DoEvents taking forever

    this is typically done with Mod:
    VB Code:
    1. Private Sub Command1_Click()
    2.     Dim I As Integer
    3.    
    4.     For I = 0 To 24999
    5.         List1.AddItem "Item " & I
    6.         If I Mod 1000 = 0 Then DoEvents
    7.     Next I
    8. End Sub

  3. #3

    Thread Starter
    Hyperactive Member BrendanDavis's Avatar
    Join Date
    Oct 2006
    Location
    Florida
    Posts
    492

    Re: Way around DoEvents taking forever

    Quote Originally Posted by bushmobile
    this is typically done with Mod:
    VB Code:
    1. Private Sub Command1_Click()
    2.     Dim I As Integer
    3.    
    4.     For I = 0 To 24999
    5.         List1.AddItem "Item " & I
    6.         If I Mod 1000 = 0 Then DoEvents
    7.     Next I
    8. 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)?

  4. #4

  5. #5
    PowerPoster
    Join Date
    Feb 2002
    Location
    Canada, Toronto
    Posts
    5,803

    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:
    1. If I Mod 1000 = 0 Then DoEvents
    Executes DoEvents every 1000'th time, because only then the reminder is equal to 0...

  6. #6

    Thread Starter
    Hyperactive Member BrendanDavis's Avatar
    Join Date
    Oct 2006
    Location
    Florida
    Posts
    492

    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.

  7. #7
    PowerPoster
    Join Date
    Feb 2002
    Location
    Canada, Toronto
    Posts
    5,803

    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.

  8. #8
    Oi, fat-rag! bushmobile's Avatar
    Join Date
    Mar 2004
    Location
    on the poop deck
    Posts
    5,592

    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:
    1. Private Sub Command1_Click()
    2.     Dim N As Long, lTimer As Long, lRet As Long
    3.     lTimer = GetTickCount
    4.     For N = 0 To 20000000
    5.         lRet = N
    6.     Next N
    7.     Print GetTickCount - lTimer
    8. 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.

  9. #9
    "Digital Revolution"
    Join Date
    Mar 2005
    Posts
    4,471

    Re: Way around DoEvents taking forever

    Or use the GetInputState API function.

    VB Code:
    1. If GetInputState Then DoEvents

    There's an even better API function to use, but I forget what it is.

  10. #10
    Fanatic Member Comintern's Avatar
    Join Date
    Nov 2004
    Location
    Lincoln, NE
    Posts
    826

    Re: Way around DoEvents taking forever

    Quote 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
  •  



Click Here to Expand Forum to Full Width