2017-10-05 6 views
0

나는 엑셀 차트처럼 배열 된 여러 텍스트 상자가있는 userform을 만들고 있습니다. TabIndexes를 설정 했으므로 TAB/shift + Tab을 사용하여 완벽하게 작동합니다. 그러나, 화살표 키를 누르는 반응은 내가 예상 한 것이 아닙니다. 초점이 boxB1에 있다고 가정userform의 텍스트 상자에있는 화살표 키, VBA

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

: 이 같은 그 텍스트 상자를 지명했다. 아래쪽 화살표 키를 누르면 boxB2로 초점을 이동하지만 boxA3 등으로 이동합니다.

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 

그것은, 그러나, 단지 내 형태로 여러 텍스트 상자가있는 경우,이 위대하고 맑은 용액 괜찮 작품 :

나는이 코드를 시도했습니다. 하지만 내 양식에는 약 70 개의 텍스트 상자가 있습니다. 그러면 내 코드가 커지고 실제로 복제 될 것입니다. 맞도록 조정할 수있는 매개 변수가 있습니까? 또는 아래에서 사용할 수있는 기능이 있습니까? 그냥 sudo, 알 잖아.

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 

고마워요!

+0

각 텍스트 상자에 묶는 일반 keyDown/up 처리기가 포함 된 클래스 모듈이 필요합니다. 이것이 어떻게 작동하는지에 대한 아이디어는 http://jkp-ads.com/Articles/ControlHandler00.asp를 참조하십시오. – jkpieterse

답변

1

올바른 경로에 있습니다. 양식 모듈에서 두 UDF의의 아래를 추가

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 

지금에서 KeyDown 각 텍스트 상자를 들어, 다음 호출합니다 SetTextBoxFocus KeyCode합니다. 이것은 트릭을해야합니다

참고 : 나는 마지막 텍스트 상자에 boxD이 있습니다. 같은 행에있는 마지막 텍스트 상자로 변경해야합니다.