Проблема со списком Excel - PullRequest
       16

Проблема со списком Excel

3 голосов
/ 08 сентября 2010

У меня есть форма в 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, которая чередуетсямежду истиной и ложью каждый раз, когда выполняется событие sub.Это похоже на хрупкое решение проблемы.Есть ли лучший способ?

Ответы [ 4 ]

1 голос
/ 23 сентября 2014

Это сработало для меня, вместо присвоения значения я назначаю свойство 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
1 голос
/ 08 сентября 2010

Вы на правильном пути, используя логическое значение 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 голос
/ 09 сентября 2010

Я нашел простой способ решить эту проблему. Не похоже, что это должно работать, но если я просто переназначу значение поля со списком после перестройки списка, оно не отбрасывает выбранное значение.

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
0 голосов
/ 08 сентября 2010

Используйте взамен GotFocus ().

 Private Sub ComboBox1_GotFocus()
    MsgBox "caca"
 End Sub

Запускается, только когда комбо получает фокус.

НТН

...