Unfortunately, there's no easy to keep the Mouse Wheel from scrolling through records. Microsoft's official solution (
found here) requires a compiled dll (
which you can get here).
If you are using Access2000 and below, the dll is really your only option. Access2002 (XP) and better gives you the ability to capture the Mouse Wheel event. You can't cancel the event, but you can trap it and with a little bit of creative coding you can trick Access into doing what you want.
The solution you require has three problems to address:
First, since you can't stop the Wheel from scrolling to another record, we need to trap the fact that the record movement happened as the result of a MouseWheel event and put the record back where it was. Unfortunately, this can't be done exclusively in the MouseWheel event handler since the record move doesn't happen until after the MouseWheel event completes. So we need to pass a note to the Current event of the form to tell it to go back to where it was.
Another problem we have is that if you scroll the Wheel really fast, it will scroll multiple records in a single MouseWheel event. For instance, you scroll the wheel really fast and it tells the MouseWheel event to scroll twelve lines. That will trigger four record movements (one record per three lines... the default setup for the mouse is to scroll three lines per tick of the wheel. If you have it set up to scroll a different number, you will need to change the code. I haven't taken the time to figure out how to find that value in VBA... it shouldn't be too hard I would assume). It won't just just four records, it will trigger four record movements, so we now have to tell the Current event to fix a record movement four times, not just once.
Lastly, when we manually move to a different record, the focus is taken from the controls on the form and given to the form itself. This means that in order to advance or regress fields, we need to know, at least, what field had the focus before the Wheel scrolled. We also need to set the focus back to that field and tab (or backtab) to the desired field. Additionally, because we have to do this after the record fix is complete, this needs to be done in the same event as the record fix. However, if we scroll up while on the first record, the MouseWheel event is fired, but the Current event is not (we can't move before the first record). The same goes for the last record. So in order to use the Wheel as a tab even when the record does not move, we need to add all this to our program logic in the MouseWheel event.
OK, enough talk... here's the solution:
Code:
Private booWheel As Boolean 'Was the record change was fired by the Wheel event
Private intCancel As Integer 'How many record fixes will we have to do per Wheel event
Private booForward As Boolean 'Did we scroll up or down
Private strControl As String 'What control had the focus before we scrolled
Private Sub Form_Current()
'Only process this if the Wheel triggered the event
If booWheel Then
'If there will be more than one record change, start a countdown
If intCancel > 1 Then
intCancel = intCancel - 1
'If this is the only (or last) record change then turn this off
Else
booWheel = False
End If
'Disable the Current event so out manual record change won't fire recursively
Me.OnCurrent = ""
'Manually change record based on the direction of the scroll
DoCmd.GoToRecord acDataForm, Me.Name, IIf(booForward, acPrevious, acNext)
'Enable the Current event so that this can fire again is needed
Me.OnCurrent = "[Event Procedure]"
'If this is the last (or only) record change then:
If Not booWheel Then
'Set the focus back to the original control and,
Me.Controls(strControl).SetFocus
'Tab or BackTab based in the direction of the scroll
If booForward Then SendKeys "{TAB}" Else SendKeys "+{TAB}"
End If
End If
End Sub
Private Sub Form_MouseWheel(ByVal Page As Boolean, ByVal Count As Long)
'First determine if we scrolled up or down.
booForward = Count > 0
'If we're at the first record and we scrolled up, then BackTab
If Me.Recordset.AbsolutePosition = 0 And Not booForward Then
SendKeys "+{TAB}"
'If we're at the last record and we scrolled down, then Tab
ElseIf Me.Recordset.AbsolutePosition = Me.Recordset.RecordCount And booForward Then
SendKeys "{TAB}"
'Else, send the Current event the data it needs to complete the operation
Else
booWheel = True 'Wheel event triggered record change
intCancel = Abs(Count / 3) 'Number of records that will be scrolled
strControl = Me.ActiveControl.Name 'Control that had the focus before event
End If
End Sub
Let us know if this helps.