本人在作一个数据库录入界面时候,根据用户的需求ComboBox需要做成在获得焦点,自动弹出下拉列表,用户只用通过数字键,输入数据对应的编号,当达到编号满足的位数时,自动选择编号所对应的数据,然后焦点传过下一个TabIndex,例:在“优势树种”字段中有“红松”“云杉”“白杨”三种数,红松对应的编号为1,云杉对的编号为2,白杨编号为3,当代表“优势树种”的ComboBox获得焦点时,自动开打下拉列表,显示三个树种,这时我键入数字键2,编号的最大位数为1,满足了编号位数,则在ComboBox框中显示云杉,同时传出焦点。功能已基本实现,但问题在于,在送出焦点后,ComboBox框内必不是总会正常按预想的显示“云杉”贴出部份代码,请高手们多多赐教:
1。ComboBox装入数据代码:
'将数据转换显示为对应下列表框信息
Public Sub AddInfo(ByVal aCtl As Control, ByVal aTabInfo As String)
'aTabInfo 为表名,aCtl 为控件名即ComboBox名
Dim rsInfo As New ADODB.Recordset
Dim StrSQL As String
StrSQL = "Select * From " & aTabInfo
Set rsInfo = g_connAdo.Execute(StrSQL)
'rsInfo!Desc为数据名称,即“云杉”,rsInfo!SeqId为数据编号,即2
aCtl.Clear
Do While Not rsInfo.EOF
aCtl.AddItem Trim(rsInfo!Desc)
aCtl.ItemData(aCtl.ListCount - 1) = rsInfo!SeqId
rsInfo.MoveNext
Loop
2。获得焦点后,自动打开下拉列表,在调用的API函数
'代码打开CBO下拉框
Public Const CB_SHOWDROPDOWN = &H14F
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
' 如果想打开下拉列表,使用:
' SendMessage Combo1.hwnd, CB_SHOWDROPDOWN, 1, CLng(0)
' 如果想关闭下拉列表,使用:
' SendMessage Combo1.hwnd, CB_SHOWDROPDOWN, 0, CLng(0)
在上一个控件失去后调用GotFocus事件
Private Sub cboTreeDegB_GotFocus()
SendMessage ActiveControl.hwnd, CB_SHOWDROPDOWN, 1, CLng(0)
End Sub
3。记录输入数据函数
在KeyPress事件中调用
Private Sub cboTreeDegB_KeyPress(KeyAscii As Integer)
speedinput ActiveControl, KeyAscii, 1
End Sub
'利用数字键快速输入
Public Sub speedinput(ByVal aCtl As Control, KeyAscii As Integer, Optional Length As Integer)
'm_intSel 为模块级变量,用以记录输入数据
Dim intCnt As Integer
If KeyAscii >= 48 And KeyAscii <= 57 And m_intSel < 999 Then
m_intSel = CLng(CStr(m_intSel) & CStr(Int(Chr(KeyAscii))))
End If
With aCtl
'当输入回车时,显示输入的编号对应值,焦点传到下一个TabIndex
If KeyAscii = 13 Then
For intCnt = 0 To .ListCount - 1
If Int(m_intSel) = .ItemData(intCnt) Then
.ListIndex = intCnt
m_intSel = 0
Exit For
End If
Next
m_intSel = 0
End If
If Len(CStr(m_intSel)) = Length Then
For intCnt = 0 To .ListCount - 1
If Int(m_intSel) = .ItemData(intCnt) Then
.ListIndex = intCnt
m_intSel = 0
Exit For
End If
Next
m_intSel = 0
SendKeys "{TAB}"
End If
End With
KeyAscii = 0
End Sub我现在考虑是否是因为调用了API函数,而倒置数据发生了冲突,而产生无法正常显示
请各位多多指教
1。ComboBox装入数据代码:
'将数据转换显示为对应下列表框信息
Public Sub AddInfo(ByVal aCtl As Control, ByVal aTabInfo As String)
'aTabInfo 为表名,aCtl 为控件名即ComboBox名
Dim rsInfo As New ADODB.Recordset
Dim StrSQL As String
StrSQL = "Select * From " & aTabInfo
Set rsInfo = g_connAdo.Execute(StrSQL)
'rsInfo!Desc为数据名称,即“云杉”,rsInfo!SeqId为数据编号,即2
aCtl.Clear
Do While Not rsInfo.EOF
aCtl.AddItem Trim(rsInfo!Desc)
aCtl.ItemData(aCtl.ListCount - 1) = rsInfo!SeqId
rsInfo.MoveNext
Loop
2。获得焦点后,自动打开下拉列表,在调用的API函数
'代码打开CBO下拉框
Public Const CB_SHOWDROPDOWN = &H14F
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
' 如果想打开下拉列表,使用:
' SendMessage Combo1.hwnd, CB_SHOWDROPDOWN, 1, CLng(0)
' 如果想关闭下拉列表,使用:
' SendMessage Combo1.hwnd, CB_SHOWDROPDOWN, 0, CLng(0)
在上一个控件失去后调用GotFocus事件
Private Sub cboTreeDegB_GotFocus()
SendMessage ActiveControl.hwnd, CB_SHOWDROPDOWN, 1, CLng(0)
End Sub
3。记录输入数据函数
在KeyPress事件中调用
Private Sub cboTreeDegB_KeyPress(KeyAscii As Integer)
speedinput ActiveControl, KeyAscii, 1
End Sub
'利用数字键快速输入
Public Sub speedinput(ByVal aCtl As Control, KeyAscii As Integer, Optional Length As Integer)
'm_intSel 为模块级变量,用以记录输入数据
Dim intCnt As Integer
If KeyAscii >= 48 And KeyAscii <= 57 And m_intSel < 999 Then
m_intSel = CLng(CStr(m_intSel) & CStr(Int(Chr(KeyAscii))))
End If
With aCtl
'当输入回车时,显示输入的编号对应值,焦点传到下一个TabIndex
If KeyAscii = 13 Then
For intCnt = 0 To .ListCount - 1
If Int(m_intSel) = .ItemData(intCnt) Then
.ListIndex = intCnt
m_intSel = 0
Exit For
End If
Next
m_intSel = 0
End If
If Len(CStr(m_intSel)) = Length Then
For intCnt = 0 To .ListCount - 1
If Int(m_intSel) = .ItemData(intCnt) Then
.ListIndex = intCnt
m_intSel = 0
Exit For
End If
Next
m_intSel = 0
SendKeys "{TAB}"
End If
End With
KeyAscii = 0
End Sub我现在考虑是否是因为调用了API函数,而倒置数据发生了冲突,而产生无法正常显示
请各位多多指教
解决方案 »
- 高手请进,关于xml节点数据问题。
- 关于VB用CDO发送邮件
- 如何获取打印机纸张信息?
- 怎么用软件来阻止“关机”,“重起”!
- 请问包含多个图标的图标文件里的其它图标怎么显示?
- 水晶报表,WIN98,汉字重叠问题的解决,虽没彻底,但够用,散分
- vb如何通过二进制的方式打开dbf文件
- toolbar问题:在windows字体设为小字体时,toolbar内出现错乱
- 每一次启动WORD、ACCESS等OFFICE软件时总出现Windows正在安装,正在安装WORD、ACCESS组件等信息
- 谁来帮我 如何能作一个从(0,0)开始x,y轴有刻度没网格的曲线图 谢谢 !
- 实时曲线的问题
- 如何让DATAGRID中的数据根有分类显示,在不同分类的数据之间显示分类名称
Do While Not rsInfo.EOF
aCtl.AddItem rsInfo!SeqId & vbTab & Trim(rsInfo!Desc)
aCtl.ItemData(aCtl.NewIndex) = rsInfo!SeqId
rsInfo.MoveNext
Loop
Public Const CB_SETTOPINDEX = &H15CPublic Sub cboShow(ByVal strText As String, cbo As ComboBox, Optional intUsual As Integer = 0)
'把strtext的内容赋给cbo两,并且是cbo发生单击事件'intUsual :是从开始开始查找还是到着找 0-从序号0开始,1-从末尾开始查找Dim intStyle As Integer
Dim i As IntegerstrText = Trim(strText)
If cbo.ListCount > 0 Then
If intUsual = 0 Then
i = SendMessageStr(cbo.hWnd, CB_FINDSTRINGEXACT, -1, ByVal strText)
cbo.ListIndex = i
' For i = 0 To cbo.ListCount - 1
'
' If Trim(cbo.List(i)) = strText Then
' cbo.ListIndex = i '相当于点击
' Exit For
' End If
'
' Next i
Else
For i = cbo.ListCount - 1 To 0 Step -1 If Trim(cbo.List(i)) = strText Then
cbo.ListIndex = i '相当于点击
Exit For
End If Next i
End If
End If
End Sub
比如按2的时候,直接显示云杉,不要drop以后再显示,好运:)
还是把我的程序思想讲一下吧:首先我会在数据库里存一张辅助用表,存入名称和对应编号,如:红松对应的编号为1,云杉对的编号为2,白杨编号为3。在窗体load的时候,把名称加入list,把编号加入itemdate,代码如下:
Public Sub AddInfo(ByVal aCtl As Control, ByVal aTabInfo As String)
'aTabInfo 为表名,aCtl 为控件名即ComboBox名
Dim rsInfo As New ADODB.Recordset
Dim StrSQL As String
StrSQL = "Select * From " & aTabInfo
Set rsInfo = g_connAdo.Execute(StrSQL)
'rsInfo!Desc为数据名称,即“云杉”,rsInfo!SeqId为数据编号,即2
aCtl.Clear
Do While Not rsInfo.EOF
aCtl.AddItem Trim(rsInfo!Desc)
aCtl.ItemData(aCtl.ListCount - 1) = rsInfo!SeqId
rsInfo.MoveNext
Loop
界面由一系列文本框和列表框组成,提供数据录入接口,用户最先的需求是:各个控件由一定的顺序排列之后,当按下回车键的时候,焦点自动跳到下一个输入口(即文本框或列表框)我的解决方式是设置from的keypress属性为真,按排列顺序设置各式各控件的tabindex值,然后添加了from的keydown事件,代码如下:
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
On Error GoTo ErrH:
If KeyCode = 13 Then
SendKeys "{TAB}"
'设置按ESC取消CBO的选项
ElseIf KeyCode = vbKeyEscape Then
If Left(ActiveControl.Name, 3) = "cbo" Then
ActiveControl.ListIndex = -1
End If
ElseIf KeyCode = vbKeyF6 Then
End If
Exit Sub
ErrH:
End Sub
接着处理,获得焦点后,打开列表框下拉列表,我使用的是COMBO的GotFocus事件
SendMessage ActiveControl.hwnd, CB_SHOWDROPDOWN, 1, CLng(0)
然后处理,用户在下拉列表中选取自已需要的项目。这时用户提出了两个要求,1不用鼠标直接在键盘中输入数字编号,即可完成选取,2推测功能,如上例中编号只有1位字长,则我输入一位数字后不用回车,直接在COMBO中显示选项,并将焦点传出,我用keypress事件处理:
Private Sub cboTreeDegB_KeyPress(KeyAscii As Integer)
speedinput ActiveControl, KeyAscii, 1
End Sub
'利用数字键快速输入
Public Sub speedinput(ByVal aCtl As Control, KeyAscii As Integer, Optional Length As Integer)
'm_intSel 为模块级变量,用以记录输入数据
Dim intCnt As Integer
If KeyAscii >= 48 And KeyAscii <= 57 And m_intSel < 999 Then
m_intSel = CLng(CStr(m_intSel) & CStr(Int(Chr(KeyAscii))))
End If
With aCtl
'当输入回车时,显示输入的编号对应值,焦点传到下一个TabIndex
If KeyAscii = 13 Then
For intCnt = 0 To .ListCount - 1
If Int(m_intSel) = .ItemData(intCnt) Then
.ListIndex = intCnt
m_intSel = 0
Exit For
End If
Next
m_intSel = 0
End If
‘推测功能实现
If Len(CStr(m_intSel)) = Length Then
For intCnt = 0 To .ListCount - 1
If Int(m_intSel) = .ItemData(intCnt) Then
.ListIndex = intCnt
m_intSel = 0
Exit For
End If
Next
m_intSel = 0
SendKeys "{TAB}"
End If
End With
KeyAscii = 0
End Sub
现在的问题是,在没有加入API和推测功能之前,输入数字编号并相应显示没有任何问题,加入这两段代码之后,有很多情况下,列表框并没有改变当前的选项显示状态。但实际上列表框该内容已经被选中了,我的依据是在该列表框被选择之后,我又做了另外一个推算功能。如:我选择“云杉”后,在另一个列表框中,将相应显示出树种的所属科目如“针叶树种”,和其它几个推算,代码如下:
'根据亚林种推出林种
Private Sub CboTypeC_Validate(Cancel As Boolean)
Dim intSel As Integer
Dim intCnt As Integer
If cboTypeC.ListIndex <> -1 Then
'推林种
Select Case cboTypeC.ItemData(cboTypeC.ListIndex)
Case 11 To 13
intSel = 1
Case 14
intSel = 4
Case 15 To 19
intSel = 5
Case 20 To 27
intSel = 2
Case 31 To 39
intSel = 3
End Select
With cboPlantCls
For intCnt = 0 To .ListCount - 1
If intSel = .ItemData(intCnt) Then
.ListIndex = intCnt
intSel = 0
Exit For
End If
Next
intSel = 0
End With
'推事权
Select Case cboTypeC.ItemData(cboTypeC.ListIndex)
Case 20
intSel = 2
Case Is > 20
intSel = 1
End Select
With cboRelief
For intCnt = 0 To .ListCount - 1
If intSel = .ItemData(intCnt) Then
.ListIndex = intCnt
intSel = 0
Exit For
End If
Next
intSel = 0
End With
'推保护等级
Select Case cboTypeC.ItemData(cboTypeC.ListIndex)
Case 20
intSel = 2
Case Is > 20
intSel = 1
End Select
With cboSafeDeg
For intCnt = 0 To .ListCount - 1
If intSel = .ItemData(intCnt) Then
.ListIndex = intCnt
intSel = 0
Exit For
End If
Next
intSel = 0
End With
'推森林类别
Select Case cboTypeC.ItemData(cboTypeC.ListIndex)
Case 20 To 42
intSel = 2
Case 11, 12, 13, 14, 15, 16, 17, 18, 19
intSel = 1
End Select
With cboIrrigation
For intCnt = 0 To .ListCount - 1
If intSel = .ItemData(intCnt) Then
.ListIndex = intCnt
intSel = 0
Exit For
End If
Next
intSel = 0
End With
End If
End Sub
我当在该列表框中输入2时,其它几个列表框都相应该显示出对应的数据,但是该列表框却没有显示出“云杉”,至今没有找到问题的根源