2017-10-05 19 views
0

Je travaille sur un formulaire utilisateur avec plusieurs zones de texte, qui sont disposées comme un graphique Excel. J'ai défini les TabIndex, et ils fonctionnent parfaitement avec TAB/shift + TAB. Cependant, la réaction des touches fléchées n'est pas ce à quoi je m'attendais. Je ces zones de texte nommé comme celui-ci:Touche fléchée dans une zone de texte d'un formulaire utilisateur, VBA

boxA1 boxB1 boxC1 boxD1 
boxA2 boxB2 boxC2 boxD2 ... 
boxA3 boxB3 boxC3 boxD3 
      : 
      : 

Si l'on suppose que l'accent est mis à boxB1. Lorsque j'appuie sur la touche fléchée vers le bas, je souhaite que la mise au point se fasse à la case B2, mais elle ira à boxA3 ou à quelque chose.

J'ai essayé ce code:

Private Sub boxB1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer) 
    Select Case KeyCode 
     Case vbKeyDown 
      boxB2.SetFocus 
     Case vbKeyUp 
      boxA10.SetFocus 
    End Select 
End Sub 

Il fonctionne très bien, cependant, s'il n'y a que plusieurs zones de texte dans ma forme, c'est une solution grande et claire. Mais il y a environ 70 textboxes dans mon formulaire, cela rendra mon code grand et vraiment dupliqué. Y a-t-il des paramètres que je peux ajuster pour faire les choses correctement? Ou y at-il une fonction que je peux utiliser comme ci-dessous? Juste sudo, tu sais.

Private Sub name_i_KeyDown(ByVal KeyCode as MSForms.ReturnInteger, ByVal Shift As Integer) 
    Select Case KeyCode 
     Case vbKeyDown 
      Controls("name_" & i+1).SetFocus 
     Case vbKeyUp 
      Controls("name_" & i-1).SetFocus 
    End Select 
End Sub 

Merci!

+0

Vous auriez besoin d'un module de classe contenant un gestionnaire keyDown/up générique que vous liez à chaque zone de texte. Pour une idée de comment cela fonctionne, voir: http://jkp-ads.com/Articles/ControlHandler00.asp – jkpieterse

Répondre

1

Vous êtes sur la bonne voie. Ajouter le dessous de deux années UDF dans votre module de formulaire:

Sub SetTextBoxFocus(ByVal KeyCode As MSForms.ReturnInteger) 
    Dim sPrevControl As String 
    Dim sNextControl As String 
    Dim sBoxToSet As String 
    Dim oC As Control 

    ' Cater for TAB key press. Setting it so that it behaves like vbKeyDown. Remove this If condition if not required 
    If Asc(KeyCode) = 57 Then 
     KeyCode = vbKeyDown 
    End If 

    ' We only want to check if pressed key was either vbKeyDown or vbKeyUp and the key was pressed on a TextBox 
    If TypeName(Me.ActiveControl) = "TextBox" And (KeyCode = vbKeyDown Or KeyCode = vbKeyUp) Then 

     With Me.ActiveControl 

      ' Lets set both previous and next text box names 
      If InStr(1, .Name, "boxD") > 0 Then 
       sPrevControl = "boxC" & GetNumFromString(.Name) 
       sNextControl = "boxA" & GetNumFromString(.Name) + 1 
      ElseIf InStr(1, .Name, "boxA") > 0 Then 
       sPrevControl = "boxD" & GetNumFromString(.Name) - 1 
       sNextControl = "boxB" & GetNumFromString(.Name) 
      Else 
       sPrevControl = "box" & Chr(Asc(Mid(.Name, 4, 1)) - 1) & GetNumFromString(.Name) 
       sNextControl = "box" & Chr(Asc(Mid(.Name, 4, 1)) + 1) & GetNumFromString(.Name) 
      End If 

      ' Bases on which key was pressed, lets set the name of the text box to move to 
      Select Case KeyCode 
       Case vbKeyDown: sBoxToSet = sNextControl 
       Case Else: sBoxToSet = sPrevControl 
      End Select 

      ' Loop through all controls in the form and set the focus to the control if found 
      For Each oC In Me.Controls 
       If oC.Name = sBoxToSet Then 
        oC.SetFocus 
        Exit For 
       End If 
      Next 

     End With 
    End If 

End Sub 

Function GetNumFromString(ByVal txt As String) As String 
    Dim oRe As New RegExp 

    With oRe 
     .pattern = "\d" 
     If .Test(txt) Then GetNumFromString = .Execute(txt)(0) 
    End With 

End Function 

Maintenant, en KeyDown pour chaque zone de texte, faire l'appel suivant: SetTextBoxFocus KeyCode. Cela devrait faire l'affaire

NOTE: J'ai boxD comme dernière zone de texte. Vous devriez changer cela à la dernière case de texte que vous avez dans la même ligne