Excel组合框问题

时间:2010-09-08 18:05:36

标签: vba combobox excel-vba excel

我在Excel中有一个带有组合框控件的表单。我希望在使用已作为LIKE条件键入的组合框打开组合框时从数据库表中填充值。这是我到目前为止DropButtonClick事件实现此目的的代码。

Private Sub cboVariety_DropButtonClick()
    Static search_text As String
    Static is_open As Boolean
    Dim rs As New Recordset

    If is_open Then
        is_open = False
        Exit Sub
    End If
    is_open = True

    If search_text = cboVariety Then Exit Sub
    search_text = cboVariety

    cboVariety.Clear
    cboVariety.AddItem search_text
    If Len(search_text) > 2 Then
        rs.Open _
            "SELECT Name FROM tbl_Varieties " & _
            "WHERE Name LIKE '%" & search_text & "%' " & _
            "ORDER BY Name", connect_string, adOpenStatic
        Do Until rs.EOF
            If rs!Name <> search_text Then cboVariety.AddItem rs!Name
            rs.MoveNext
        Loop
        rs.Close
    End If
End Sub

问题是DropButtonClick事件在组合框打开和关闭时都会触发。如果在组合框关闭时执行此子程序,清除组合框的代码将导致用户的选择被删除。

我正在尝试使用is_open变量判断何时关闭该框,每次执行事件子时,该变量在true和false之间交替。这似乎是解决问题的一个简单方法。还有更好的方法吗?

4 个答案:

答案 0 :(得分:1)

通过使用is_open布尔来跟踪组合框的状态,你走在正确的轨道上,但你真正想要跟踪的是“我应该用数据库数据重新填充组合框的状态” ?“

您希望何时填充列表框?目前,您希望每次用户单击下拉框时都填充列表框(不考虑您的is_open状态变量)。这真的是你想要的吗?

我想你真正想要的是让组合框仅在其他内容发生变化后更新 。也许您只希望在首次打开表单时更新下拉列表。也许您只希望在搜索框中的文本发生更改时更改数据。如果是这种情况,您需要根据实际想要执行更新的状态来建立逻辑。

例如,假设您只想在搜索框中的文本发生更改时才更新组合框。我目前不是在看Excel,但让我们假装你有一个名为txtSearch的文本框,其中包含Text属性。我首先添加一个模块或类级变量来维护上一个文本条目的状态:

Private mPreviousSearchText As String

然后我会更新我的事件代码:

Private Sub cboVariety_DropButtonClick()                                      
    Dim rs As New Recordset                    
    Dim search_text As String

              search_text = txtSearch.Text

    If mPreviousSearchText = search_text Then                      
       'The current search matches the previous search,'
       'so we do not need to perform the update.'
        Exit Sub                    
    End If                                                    

    cboVariety.Clear                    
    cboVariety.AddItem search_text                    
    If Len(search_text) > 2 Then                    
        rs.Open _                    
            "SELECT Name FROM tbl_Varieties " & _
            "WHERE Name LIKE '%" & search_text & "%' " & _
            "ORDER BY Name", connect_string, adOpenStatic
        Do Until rs.EOF                    
            If rs!Name <> search_text Then cboVariety.AddItem rs!Name
            rs.MoveNext                    
        Loop                    
        rs.Close                                
    End If             
    'Set the previousSearchText var to be the search_text so that it does'
    'not run unless the value of my text box changes.'
    mPreviousSearchText = search_text 
End Sub

完整的一点是在您真正想要执行更新时建立并找出一种方法将您的逻辑决策与您想要执行操作的状态相关联,这只是巧合地与用户点击下拉框相关。

答案 1 :(得分:1)

我找到了解决这个问题的简单方法。它似乎不应该工作,但如果我在重建列表后重新分配组合框的值,它不会丢弃所选的值。

Private Sub cboVariety_DropButtonClick()
    Static search_text As String
    Dim rs As New Recordset

    If search_text = cboVariety Then Exit Sub
    search_text = cboVariety

    cboVariety.Clear
    If Len(search_text) > 2 Then
        rs.Open _
            "SELECT Name FROM tbl_Varieties " & _
            "WHERE Name LIKE '%" & search_text & "%' " & _
            "ORDER BY Name", connect_string, adOpenStatic
        Do Until rs.EOF
            cboVariety.AddItem rs!Name
            rs.MoveNext
        Loop
        rs.Close
    End If

    '' Reassign cboVariety in case this event was triggered by combo close
    cboVariety = search_text
End Sub

答案 2 :(得分:1)

这对我有用,而不是分配值,我指定ListIndex属性。

index = cb.ListIndex

cb.Clear

while condition
    cb.AddItem item
Wend

If index < cbLinia.ListCount Then
    cb.ListIndex = index
Else
    cb.ListIndex = -1
End If

答案 3 :(得分:0)

改为使用GotFocus()。

 Private Sub ComboBox1_GotFocus()
    MsgBox "caca"
 End Sub

仅在组合获得焦点时触发。

HTH