2017-10-05 50 views
0

我正在处理一个带有多个文本框的用户窗体,它们的排列方式与Excel图表一样。 我已经设置了TabIndexes,并且它们与TAB/shift + TAB完美搭配。但是,按箭头键的反应并不是我所期望的。 我命名为这样的那些文本框:在用户窗体的文本框中的箭头键,VBA

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

假设焦点在boxB1。按下下箭头键时,我希望焦点转到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作为最后一个文本框。您应该将其更改为您在同一行中的最后一个文本框

相关问题