查找 VBA 控件对象的部分或页面



如何确定控件对象(如acTextBox)是否是VBA中页面集合的成员?

当控件对象具有焦点时,将调用一个函数,以根据所使用的键的类型将焦点移动到下一个 control.tabindex。我设法使用发送键"{TAB}"执行此操作,但我想更改此设置,因为此方法会不断禁用键盘上的 NUMLOCK。

到目前为止,下面的函数有效,但该过程会考虑窗体中的所有控件。它应该只考虑从中调用函数的同一部分或页面中的控件。为此,我需要知道活动控件是否位于页面和/或部分中,如果是,则此页面/部分的名称或索引。我找不到执行此操作的代码。

Public Function GotoNextTab()
Dim ctlNext, ctlCurrent As Control
Dim frmCurrent As Form
Dim lngNextTab As Long
Set frmCurrent = Screen.Activeform
Set ctlCurrent = Forms(frmCurrent.Name).ActiveControl
lngNextTab = Val(ctlCurrent.TabIndex) + 1
Do Until lngNextTab = frmCurrent.Controls.Count
For Each ctlNext In frmCurrent.Controls
Select Case ctlNext.ControlType
Case acCheckBox, _
acComboBox, _
acCommandButton, _
acListBox, _
acOptionButton, _
acSubform, _
acTabCtl, _
acTextBox, _
acToggleButton
If ctlNext.TabIndex = lngNextTab Then
If ctlNext.TabStop = True Then
'Make sure that the focus can be set here!
If ctlNext.Visible = True And ctlNext.Enabled = True Then
ctlNext.SetFocus
Exit Function
Else
'Focus could not be moved, so increase lngNextTab
lngNextTab = lngNextTab + 1
End If
Else
'This was the last tab, so exit
Exit Function
End If
End If
End Select
Next ctlNext
Loop
End Function

考虑使用 TabControl.Pages() 集合来访问特定标签页上的控件。

下面是一个示例:首先找到活动控件的相应页面,循环遍历每个选项卡页中的所有控件;然后分配当前页面并循环遍历其所有控件。按名称检查是可靠的,因为窗体上带有或不带有选项卡的每个控件都必须是唯一的。

...
Dim currpage As Page
Dim tabCtrl As Control
Dim pagename As String
' FIND CURRENT PAGE OF ACTIVE CONTROL
For Each currpage In Forms!myForm!TabCtl.Pages
For Each tabctrl In currpage.Controls
If tabctrl.Name = ctlCurrent.Name
pagename = currpage.Name
End If
Next tabctrl     
Next currpage
If Len(pagename) > 0 Then
' ASSIGN CURRENT TAB PAGE
Set currpage = Forms!myForm!mytabCtl.Pages(pagename)
' LOOP THROUGH ALL CONTROLS ON CURRENT PAGE  
For Each tabctrl In currpage.Controls
'...PROCESS EACH CTRL OF CURRENT TAB PAGE
Next tabctrl      
Set tabctrl = Nothing
Set currpage = Nothing
End If

谢谢你的回答,这有助于我朝着正确的方向前进。我发现父属性总是引用一个级别的控件(在本例中为 Page 对象)。我仍然必须插入一个功能,以便在到达最后一个控件时返回到父控件集合中的第一个可用控件。到目前为止,它没有给出我想要的结果,所以我会坚持现在的程序。

Private Sub Form_Load()
KeyPreview = True
End Sub
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
Dim ctl As Control
If KeyCode = vbKeyReturn Then
'Disregard textboxes with multiple lines
Set ctl = Me.ActiveControl
If ctl.ControlType = acTextBox Then
If ctl.EnterKeyBehavior Then
Exit Sub
End If
End If
GotoNextTab
End If
End Sub
Public Function GotoNextTab()
' This function will move the focus to the next control if
' a) This control is a specified type
' b) The control is visible and enabled
' c) The control has a tabstop set to true
'
' If the controls are within a page (TabControl), the focus is cycled within the controls on that page.
' The function disregards sections as it is assumed that there is no need to cycle controls on a form header or footer
' The focus does not cycle within subforms.
On Error Resume Next
Dim ctlNext as Control
Dim ctlCurrent As Control
Dim frmCurrent As Form
Dim lngNextTab As Long
Set frmCurrent = Screen.Activeform
Set ctlCurrent = Forms(frmCurrent.Name).ActiveControl
If ctlCurrent.Parent.ControlType = acOptionGroup Then
Set ctlCurrent = ctlCurrent.Parent
End If
lngNextTab = ctlCurrent.TabIndex
Do Until lngNextTab > ctlCurrent.Parent.Controls.Count
lngNextTab = lngNextTab + 1
For Each ctlNext In ctlCurrent.Parent.Controls
Select Case ctlNext.ControlType
Case acCheckBox, _
acComboBox, _
acCommandButton, _
acListBox, _
acSubform, _
acTabCtl, _
acTextBox, _
acToggleButton, _
acOptionGroup
If ctlNext.TabIndex = lngNextTab Then
'Make sure that the focus can be set here!
If ctlNext.TabStop = True And ctlNext.Visible = True And ctlNext.Enabled = True Then
ctlNext.SetFocus
Exit Function
Else
Exit For 'restart for/next and search the next value
End If
End If
End Select
Next ctlNext
Loop
End Function

最新更新