专为易于使用而设计的 Microsoft 关系数据库管理系统系列。
注:此回复已自动翻译。因此,它可能包含语法错误或表达尴尬。
你好 @何尧
为了在数据表选择中正确识别第2列和第3列,尤其是在列被隐藏或重新排序时,我避免直接依赖SelLeft,而是使用了ColumnOrder。逻辑如下:
把SelLeft调整为0起始的数据索引:
用一个辅助函数来:
- 只筛选可见控件(ColumnHidden = False)
- 按ColumnOrder排序(实际显示顺序)
- 返回请求位置的控件名称
然后:
- 第2列 > leftIdx + 1
- 第3列 > leftIdx + 2
Sub GetSelectedColumnNames()
Dim frm As Form: Set frm = Screen.ActiveForm
Dim leftIdx As Long
Dim ctrlName2 As String, ctrlName3 As String
If frm.SelWidth < 2 Then
MsgBox "Please select AT LEAST 2 or 3 columns!", vbInformation
Exit Sub
End If
leftIdx = frm.SelLeft - 2
Debug.Print "--- NEW TEST RUN (Strictly Position 2 & 3 Only) ---"
ctrlName2 = GetControlNameAtDataColumn(frm, leftIdx + 1)
Debug.Print " Position 2 (SelLeft=" & (frm.SelLeft + 1) & "): " & ctrlName2
If frm.SelWidth >= 3 Then
ctrlName3 = GetControlNameAtDataColumn(frm, leftIdx + 2)
Debug.Print " Position 3 (SelLeft=" & (frm.SelLeft + 2) & "): " & ctrlName3
End If
End Sub
Function GetControlNameAtDataColumn(frm As Form, dataIdx As Long) As String
Dim ctrl As Control
Dim arrNames() As String, arrOrders() As Long
Dim count As Long: count = 0
For Each ctrl In frm.Controls
If ctrl.ControlType = acTextBox Or ctrl.ControlType = acComboBox Or ctrl.ControlType = acCheckBox Then
If ctrl.ColumnHidden = False Then
ReDim Preserve arrNames(count)
ReDim Preserve arrOrders(count)
arrNames(count) = ctrl.Name
arrOrders(count) = ctrl.ColumnOrder
count = count + 1
End If
End If
Next ctrl
Dim a As Long, b As Long
Dim tempOrder As Long, tempName As String
For a = 0 To count - 2
For b = a + 1 To count - 1
If arrOrders(a) > arrOrders(b) Then
tempOrder = arrOrders(a): arrOrders(a) = arrOrders(b): arrOrders(b) = tempOrder
tempName = arrNames(a): arrNames(a) = arrNames(b): arrNames(b) = tempName
End If
Next b
Next a
If dataIdx >= 0 And dataIdx < count Then
GetControlNameAtDataColumn = arrNames(dataIdx)
Else
GetControlNameAtDataColumn = "[Out of Bounds / Hidden]"
End If
End Function
对于问题2,不使用通过 SendKeys 的键盘快捷键(在进入空单元格编辑模式时会失败),这种方法是直接将选定边界强制写入表单属性。
Sub AutoSelectThreeColumns()
On Error Resume Next
If Screen.ActiveControl Is Nothing Then Exit Sub
Dim currentCtrl As Control, startPos As Long
Set currentCtrl = Screen.ActiveControl
' Get the visual position of the active control
If currentCtrl.ColumnOrder = 0 Then
Dim otherCtrl As Control
startPos = 1
For Each otherCtrl In Me.Controls
If (otherCtrl.ControlType = acTextBox Or otherCtrl.ControlType = acComboBox Or otherCtrl.ControlType = acCheckBox) Then
If otherCtrl.Left < currentCtrl.Left Then startPos = startPos + 1
End If
Next otherCtrl
Else
startPos = currentCtrl.ColumnOrder
End If
' Force Access UI to natively draw a 3-column highlight instantly
Me.SelLeft = startPos
Me.SelWidth = 3
Set currentCtrl = Nothing
End Sub
希望这些信息对你有帮助,并能指引你走上正确的方向。请随意尝试一下,如果与你的情况不符,请告诉我。
注意:如果您希望收到本帖相关的邮件通知,请按照我们文档中的步骤启用电子邮件通知。