MrSnurb が提供する例は良いスタートですが、多くの問題があります。たとえば、コントロールが無効になったり、表示されなかったりする可能性があります (setfocus がクラッシュします)。タブを使用するとフォーカスが得られます(必要に応じてタブインデックスを設定できます)。フォーム上の次または前のコントロールに移動するために使用できる2つの「単純な」ルーチン(および追加の機能)を呼び出しました(コンテナ(フレームなど)のコントロールで動作するかどうかは実際には確認していません) 、そのため、追加のチェックが必要になる場合があります..
'##############################################################################
'##
'## Function fnControlCanHaveFocus
'##
'##############################################################################
'A separate routine, because On Error goto doesn't work with this type of
'error in the IDE within a For Each loop,
'even if you have set 'Only break on unhandled' errors
Private Function fnControlCanHaveFocus(ByRef ctrl As Control) As Boolean
On Error GoTo ErrorHandling
'--------------------------------------------------------------
'Check for properties which lets a control get a focus
'For now also Check TabStop even though the control CAN have focus if this is off
fnControlCanHaveFocus = (ctrl.TabStop And _
ctrl.Enabled And _
ctrl.Visible)
Exit Function
ErrorHandling:
fnControlCanHaveFocus = False
End Function
'##############################################################################
'##
'## Sub pSetFocusToNextControl
'##
'##############################################################################
Private Sub pSetFocusToNextControl(ByRef frm As Form)
Dim ctrl As Control
Dim ctrlFirst As Control
Dim ctrlNext As Control
'--------------------------------------------------------------
'Is there even an active control?
If Not frm.ActiveControl Is Nothing Then
'--------------------------------------------------------------
'Try and find the First and next control which can receive focus
Set ctrlFirst = Nothing
Set ctrlNext = Nothing
For Each ctrl In frm.Controls
'--------------------------------------------------------------
'Can this control have focus?
If fnControlCanHaveFocus(ctrl) And _
Not ctrl Is frm.ActiveControl Then
'--------------------------------------------------------------
'Check for Next control
If ctrl.TabIndex > frm.ActiveControl.TabIndex Then
If ctrlNext Is Nothing Then
Set ctrlNext = ctrl
ElseIf ctrlNext.TabIndex > ctrl.TabIndex Then
Set ctrlNext = ctrl
End If 'ElseIf ctrlNext.TabIndex>ctrl.TabIndex
End If 'If ctrl.TabIndex>frm.ActiveControl.TabIndex
'--------------------------------------------------------------
'Check for first control
If ctrlFirst Is Nothing Then
Set ctrlFirst = ctrl
ElseIf ctrlFirst.TabIndex < ctrl.TabIndex Then
Set ctrlFirst = ctrl
End If 'ElseIf ctrlFirst.TabIndex<ctrl.TabIndex
End If 'If fnControlCanHaveFocus(ctrl) And...
Next ctrl
'--------------------------------------------------------------
'Is there a next control to set focus to?
If Not ctrlNext Is Nothing Then
Call ctrlNext.SetFocus
'--------------------------------------------------------------
'No next control, but a first control to jump to?
ElseIf Not ctrlFirst Is Nothing Then
Call ctrlFirst.SetFocus
End If 'ElseIf Not ctrlFirst Is Nothing
End If 'If Not frm.ActiveControl Is Nothing
End Sub
'##############################################################################
'##
'## Sub pSetFocusToPreviousControl
'##
'##############################################################################
Private Sub pSetFocusToPreviousControl(ByRef frm As Form)
Dim ctrl As Control
Dim ctrlLast As Control
Dim ctrlPrevious As Control
'--------------------------------------------------------------
'Is there even an active control?
If Not frm.ActiveControl Is Nothing Then
'--------------------------------------------------------------
'Try and find the Last and previous control which can receive focus
Set ctrlLast = Nothing
Set ctrlPrevious = Nothing
For Each ctrl In frm.Controls
'--------------------------------------------------------------
'Can this control have focus?
If fnControlCanHaveFocus(ctrl) And _
Not ctrl Is frm.ActiveControl Then
'--------------------------------------------------------------
'Check for Previous control
If ctrl.TabIndex < frm.ActiveControl.TabIndex Then
If ctrlPrevious Is Nothing Then
Set ctrlPrevious = ctrl
ElseIf ctrlPrevious.TabIndex < ctrl.TabIndex Then
Set ctrlPrevious = ctrl
End If 'ElseIf ctrlPrevious.TabIndex<ctrl.TabIndex
End If 'If ctrl.TabIndex<frm.ActiveControl.TabIndex
'--------------------------------------------------------------
'Check for Last control
If ctrlLast Is Nothing Then
Set ctrlLast = ctrl
ElseIf ctrlLast.TabIndex > ctrl.TabIndex Then
Set ctrlLast = ctrl
End If 'ElseIf ctrlLast.TabIndex>ctrl.TabIndex
End If 'If fnControlCanHaveFocus(ctrl) And...
Next ctrl
'--------------------------------------------------------------
'Is there a previous control to set focus to?
If Not ctrlPrevious Is Nothing Then
Call ctrlPrevious.SetFocus
'--------------------------------------------------------------
'No previous control but a Last control to jump to?
ElseIf Not ctrlLast Is Nothing Then
Call ctrlLast.SetFocus
End If 'ElseIf Not ctrlLast Is Nothing
End If 'If Not frm.ActiveControl Is Nothing
End Sub
たとえば、次のように使用します。
Private Sub txt_KeyDown(Index As Integer, KeyCode As Integer, Shift As Integer)
Select Case KeyCode
Case vbKeyDown, _
vbKeyReturn
Call pSetFocusToNextControl(Me)
KeyCode = 0
Case vbKeyUp
Call pSetFocusToPreviousControl(Me)
KeyCode = 0
End Select
End Sub