2017-10-05 7 views
0

Ich arbeite an einem Benutzerformular mit mehreren Textfeldern, die genau wie ein Excel-Diagramm angeordnet sind. Ich habe die TabIndexes eingestellt, und sie funktionieren perfekt mit TAB/shift + TAB. Das Drücken der Pfeiltasten ist jedoch nicht das, was ich erwartet habe. Ich nannte diese Textfelder wie folgt aus:Pfeiltaste in einem Textfeld eines Benutzerformulars, VBA

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

Unter der Annahme, dass der Fokus auf boxB1 ist. Wenn ich die Abwärtspfeiltaste drücke, möchte ich, dass der Fokus auf BoxB2 geht, aber auf BoxA3 oder so.

Ich habe diesen Code versucht:

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 

es funktioniert gut, aber wenn es nur mehrere Textfelder in meiner Form ist, ist dies eine große und klare Lösung. Aber es gibt ungefähr 70 Textfelder in meiner Form, dadurch wird mein Code groß und wirklich dupliziert. Gibt es irgendwelche Parameter, die ich einstellen kann, um es richtig zu machen? Oder gibt es irgendeine Funktion, die ich verwenden kann, wie unten? Nur Sudo, weißt du?

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 

Vielen Dank!

+0

Sie benötigen ein Klassenmodul mit einem generischen keyDown/up-Handler, den Sie an jedes Textfeld anbinden. Eine Vorstellung davon, wie das funktioniert, finden Sie unter: http://jkp-ads.com/Articles/ControlHandler00.asp – jkpieterse

Antwort

1

Sie sind auf dem richtigen Weg. Fügen Sie die folgenden zwei UDF in dem Formular-Modul:

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 

nun in KeyDown für jede TextBox, den folgenden Aufruf: SetTextBoxFocus KeyCode. Dies sollte den Trick tun

HINWEIS: Ich habe boxD als das letzte Textfeld. Sie sollten das auf das letzte Textfeld ändern, das Sie in derselben Zeile haben

Verwandte Themen