VB6Parse / Library / Interaction / doevents

VB6 Library Reference

DoEvents Function

Yields execution so that the operating system can process other events and messages.

Syntax

DoEvents()

Parameters

None.

Return Value

Returns an Integer representing the number of open forms in stand-alone versions of Visual Basic. Returns 0 in all other applications.

Remarks

The DoEvents function temporarily yields execution to the operating system, allowing it to process other events such as user input, timers, and system messages. This is essential for keeping an application responsive during long-running operations.

Important Characteristics:

When to Use DoEvents

When NOT to Use DoEvents

Examples

Basic Usage

' Process large dataset while keeping UI responsive
Dim i As Long
For i = 1 To 100000
ProcessRecord i

' Yield every 100 iterations
If i Mod 100 = 0 Then
DoEvents
End If
Next i

' Simple DoEvents call
DoEvents

' Check return value (rarely used)
Dim formCount As Integer
formCount = DoEvents()

Progress Bar Update

Sub ProcessWithProgress()
Dim i As Long
Dim total As Long

total = 10000
ProgressBar1.Min = 0
ProgressBar1.Max = total

For i = 1 To total
ProcessItem i

' Update progress bar
ProgressBar1.Value = i
lblStatus.Caption = "Processing " & i & " of " & total

' Allow UI to refresh
DoEvents
Next i

MsgBox "Processing complete!"
End Sub

File Processing

Sub ProcessLargeFile(filePath As String)
Dim fileNum As Integer
Dim line As String
Dim lineCount As Long

fileNum = FreeFile
Open filePath For Input As #fileNum

lineCount = 0
Do Until EOF(fileNum)
Line Input #fileNum, line
ProcessLine line
lineCount = lineCount + 1

' Yield every 100 lines
If lineCount Mod 100 = 0 Then
DoEvents
End If
Loop

Close #fileNum
End Sub

Common Patterns

Cancellable Long Operation

Private cancelOperation As Boolean

Sub PerformCancellableOperation()
Dim i As Long
cancelOperation = False
cmdCancel.Enabled = True

For i = 1 To 100000
If cancelOperation Then
MsgBox "Operation cancelled"
Exit For
End If

ProcessItem i

If i Mod 100 = 0 Then
DoEvents  ' Allows cancel button to be clicked
End If
Next i

cmdCancel.Enabled = False
End Sub

Private Sub cmdCancel_Click()
cancelOperation = True
End Sub

Batch Import with Status

Sub ImportRecords(records As Variant)
Dim i As Long
Dim startTime As Double

startTime = Timer

For i = LBound(records) To UBound(records)
ImportRecord records(i)

' Update status every 50 records
If i Mod 50 = 0 Then
lblStatus.Caption = "Imported " & i & " records..."
DoEvents
End If
Next i

lblStatus.Caption = "Import complete: " & UBound(records) - LBound(records) + 1 & _
" records in " & Format(Timer - startTime, "0.00") & " seconds"
End Sub

Prevent UI Freeze During Calculation

Function CalculateComplexResult(data As Variant) As Double
Dim i As Long
Dim result As Double
Dim iterations As Long

iterations = 0
result = 0

For i = LBound(data) To UBound(data)
result = result + PerformComplexCalculation(data(i))
iterations = iterations + 1

' Yield periodically
If iterations Mod 500 = 0 Then
DoEvents
End If
Next i

CalculateComplexResult = result
End Function

Database Batch Update

Sub UpdateRecordsBatch(rs As ADODB.Recordset)
Dim count As Long

count = 0
Do Until rs.EOF
rs("Status") = "Processed"
rs("ProcessDate") = Date
rs.Update

count = count + 1
If count Mod 25 = 0 Then
lblProgress.Caption = count & " records updated"
DoEvents
End If

rs.MoveNext
Loop
End Sub

Search Operation with Live Results

Sub SearchFiles(rootPath As String, searchTerm As String)
Dim fileName As String
Dim matchCount As Long

matchCount = 0
lstResults.Clear

fileName = Dir(rootPath & "\*.*")
Do While fileName <> ""
If InStr(1, fileName, searchTerm, vbTextCompare) > 0 Then
lstResults.AddItem fileName
matchCount = matchCount + 1
End If

fileName = Dir
DoEvents  ' Keep UI responsive, allow viewing results
Loop

lblStatus.Caption = matchCount & " matches found"
End Sub

Report Generation

Sub GenerateReport(data As Collection)
Dim item As Variant
Dim lineNum As Long

lineNum = 0

For Each item In data
WriteReportLine item
lineNum = lineNum + 1

If lineNum Mod 20 = 0 Then
lblProgress.Caption = "Generated " & lineNum & " lines..."
DoEvents
End If
Next item
End Sub

Animation or Visual Feedback

Sub ShowProcessingAnimation()
Dim i As Integer

For i = 1 To 100
' Update visual indicator
shpIndicator.Left = i * 50
DoEvents

' Simulate work
Sleep 10
Next i
End Sub

Multi-Step Process

Sub MultiStepProcess()
lblStatus.Caption = "Step 1: Loading data..."
DoEvents
LoadData

lblStatus.Caption = "Step 2: Processing data..."
DoEvents
ProcessData

lblStatus.Caption = "Step 3: Saving results..."
DoEvents
SaveResults

lblStatus.Caption = "Complete!"
DoEvents
End Sub

Advanced Usage

Prevent Reentrancy

Private isProcessing As Boolean

Sub SafeProcessWithDoEvents()
' Prevent re-entry
If isProcessing Then
MsgBox "Already processing"
Exit Sub
End If

isProcessing = True

Dim i As Long
For i = 1 To 10000
ProcessItem i

If i Mod 100 = 0 Then
DoEvents
End If
Next i

isProcessing = False
End Sub

Throttled DoEvents

Sub ProcessWithThrottledDoEvents()
Dim i As Long
Dim lastDoEvents As Double
Dim doEventsInterval As Double

doEventsInterval = 0.1  ' 100ms
lastDoEvents = Timer

For i = 1 To 100000
ProcessItem i

' DoEvents based on time, not iteration count
If Timer - lastDoEvents > doEventsInterval Then
DoEvents
lastDoEvents = Timer
End If
Next i
End Sub

Disable Controls During Processing

Sub ProcessWithDisabledControls()
' Disable controls to prevent reentrancy
DisableControls

Dim i As Long
For i = 1 To 10000
ProcessItem i

If i Mod 100 = 0 Then
UpdateProgress i
DoEvents  ' Safe because controls are disabled
End If
Next i

EnableControls
End Sub

Sub DisableControls()
Dim ctrl As Control
For Each ctrl In Me.Controls
If TypeOf ctrl Is CommandButton Then
ctrl.Enabled = False
End If
Next ctrl
End Sub

Sub EnableControls()
Dim ctrl As Control
For Each ctrl In Me.Controls
If TypeOf ctrl Is CommandButton Then
ctrl.Enabled = True
End If
Next ctrl
End Sub

Background Processing Simulation

' Simulates background processing using DoEvents
Private processingComplete As Boolean

Sub StartBackgroundTask()
processingComplete = False

' Start the "background" task
ProcessInBackground

' Show modal dialog that waits
Do Until processingComplete
DoEvents
Sleep 10  ' Small delay to reduce CPU usage
Loop

MsgBox "Background task complete"
End Sub

Sub ProcessInBackground()
Dim i As Long
For i = 1 To 10000
ProcessItem i

If i Mod 100 = 0 Then
DoEvents
End If
Next i

processingComplete = True
End Sub

Smart DoEvents with CPU Management

Sub ProcessWithCPUManagement()
Dim i As Long
Dim processingTime As Double
Dim doEventsTime As Double

For i = 1 To 100000
processingTime = Timer
ProcessItem i
processingTime = Timer - processingTime

' DoEvents if processing takes significant time
If processingTime > 0.05 Then  ' More than 50ms
doEventsTime = Timer
DoEvents
doEventsTime = Timer - doEventsTime

' Adjust strategy if DoEvents takes too long
If doEventsTime > processingTime * 0.1 Then
' DoEvents overhead is too high, reduce frequency
' (implementation-specific logic here)
End If
End If
Next i
End Sub

Export with User Interaction

Sub ExportDataWithOptions()
Dim i As Long
Dim exportCount As Long

exportCount = 0

For i = 1 To RecordCount
If chkIncludeDeleted.Value = vbChecked Or Not IsDeleted(i) Then
ExportRecord i
exportCount = exportCount + 1
End If

' Update UI and allow user to change options
If i Mod 50 = 0 Then
lblProgress.Caption = exportCount & " records exported"
DoEvents
' User can check/uncheck options, affecting subsequent exports
End If
Next i
End Sub

Error Handling

Sub ProcessWithErrorHandling()
On Error GoTo ErrorHandler

Dim i As Long
For i = 1 To 10000
ProcessItem i

If i Mod 100 = 0 Then
DoEvents
End If
Next i

Exit Sub

ErrorHandler:
' DoEvents can trigger errors if event handlers fail
MsgBox "Error during processing: " & Err.Description
Resume Next
End Sub

Common Errors

Performance Considerations

Best Practices

Call Periodically, Not Every Iteration

' Good - DoEvents every 100 iterations
For i = 1 To 100000
ProcessItem i
If i Mod 100 = 0 Then DoEvents
Next i

' Bad - DoEvents every iteration (slow)
For i = 1 To 100000
ProcessItem i
DoEvents  ' Too frequent!
Next i

Protect Against Reentrancy

' Good - Use flag to prevent reentrancy
Private isProcessing As Boolean

Sub Process()
If isProcessing Then Exit Sub
isProcessing = True
' ... processing with DoEvents ...
isProcessing = False
End Sub

' Bad - No protection
Sub Process()
' ... processing with DoEvents ...
' Can be called again through DoEvents
End Sub

Disable User Input When Needed

' Good - Disable controls that could cause problems
cmdProcess.Enabled = False
For i = 1 To 10000
ProcessItem i
If i Mod 100 = 0 Then DoEvents
Next i
cmdProcess.Enabled = True

Consider Alternatives

' For very long operations, consider:
' 1. Timer control for asynchronous processing
' 2. Threading (in modern applications)
' 3. Breaking into smaller chunks with callbacks
' 4. Progress forms with asynchronous updates

Comparison with Other Approaches

DoEvents vs Timer Control

' DoEvents - Synchronous, blocks until complete
For i = 1 To 10000
ProcessItem i
If i Mod 100 = 0 Then DoEvents
Next i

' Timer - Asynchronous, processes in chunks
Private currentIndex As Long

Private Sub Timer1_Timer()
Dim i As Long
For i = currentIndex To currentIndex + 99
If i > 10000 Then
Timer1.Enabled = False
Exit Sub
End If
ProcessItem i
Next i
currentIndex = i
End Sub

DoEvents vs Application.Wait (Excel VBA)

' DoEvents - Yields immediately
DoEvents

' Application.Wait - Yields for specific duration
Application.Wait Now + TimeValue("00:00:01")

Limitations

← Back to Interaction | View all functions