Rambler's Top100
Форум: MS ACCESSVBVBA MS OfficeMS SQL server
Новые сообщения: 0000

Форум: MS ACCESS

Вопросы связанные с MS ACCESS

Обновить визитку
Участники «Online»
Все участники

 
 

Доброго времени суток, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: еще вопрос о выкидном списке
 
 автор: joka   (17.03.2009 в 12:08)   личное сообщение
 
 

на форме есть выкидной список, в нем источник строк (select id, ФИО from сотрудники), при этом первый столбец ширины 0, т.е. в списке видны только фамилии.
вопрос:
можно ли сделать так чтобы при вводе букв производился автоматический отбор из всего списка фамилий начинающихся на эти буквы и этот укороченный список предлагался открытием пользователю?

Me![ПолеВыборСотрудника].DropDown можно открыть список, а вот как быть с уменьшением числа записей? надо налету менять RecordSource? или есть другие варианты решения?

  Ответить  
 
 автор: Lukas   (17.03.2009 в 12:12)   личное сообщение
 
 


выкидной список


Очередной перл.

  Ответить  
 
 автор: Мюллер   (17.03.2009 в 12:18)   личное сообщение
18 Кб.
 
 

Можно нга лету менять рекордсоурс списка. Вот пример - уже был на этом форуме ( или другом ) . От туда можно подчерпнуть решение.

  Ответить  
 
 автор: joka   (17.03.2009 в 13:12)   личное сообщение
 
 

спасибо пойду погляжу пример :)

  Ответить  
 
 автор: joka   (17.03.2009 в 13:49)   личное сообщение
 
 

сделал так

Private Sub ПолеВыбораСотрудника_Change()
Dim strWhere, strSQL1, strSQL2 As String
If Len([ПолеВыбораСотрудника].Text) <> 0 Or Not IsNull([ПолеВыбораСотрудника].Text) Then
strSQL1 = "SELECT id, ФИО FROM Usys_sotr"
strSQL2 = " ORDER BY Usys_sotr.ФИО;"
strWhere = " WHERE Left(ФИО," & Len([ПолеВыбораСотрудника].Text) & ") = '" & [ПолеВыбораСотрудника].Text & "'"
Me![ПолеВыбораСотрудника].RowSource = strSQL1 & strWhere & strSQL2
Me![ПолеВыбораСотрудника].Dropdown
End If
End Sub

работает но как то криво не пойму почему???
завел двух сотрудников например петров и петрухин...
набираю до "петр" в списке показывает только одного петрова. набираю "петру" вываливается один петрухин...
а если начинать стирать символы, список начинает показывать обоих ...
помогите разобраться в чем дело:(

  Ответить  
 
 автор: Мюллер   (17.03.2009 в 14:32)   личное сообщение
 
 

Так ведь вы хотите выбрать по частичному, а не полному совпадению Вместе с тем в запросе вы задаете условие на полное совпадение. Задайте вместо равенства - Like [Forms]![Имя_вашей_формы]![ПолеВыбораСотрудника].Text & "*".

А кривая работа получается потому, что аксовский комбобокс сам отбирает значения на частичное совпадение при вводе в него букв.

  Ответить  
 
 автор: joka   (17.03.2009 в 15:00)   личное сообщение
 
 

Like вроде я тоже пробовал уже.
все равно спасибо за подсказку!

  Ответить  
 
 автор: Анатолий (Киев)   (17.03.2009 в 13:00)   личное сообщение
 
 

Но зачем вам эта морока?
Если ваш "выкидной список" (правильные термины "Поле со списком" или Combobox ) отсортирован по фамилиям, то при вводе каждого символа Акс сам перемешает указатель на 1-ю подходящую строку в открытом (DropDown) списе и ниже вы видите все остальные варианты.

  Ответить  
 
 автор: joka   (17.03.2009 в 13:07)   личное сообщение
 
 

в открытом методом DropDown я вижу все скажем 16 записей, что не очень удобно для глаза пользователя (хотя конечно первая строка подходящая там выделена, как вы и говорите), вот и возникла идея, нельзя ли сделать так, набрал "пет" из всег осписка сотрудников произвелся отбор.. и выкинуло для пользователя только начинающихся с "пет"...

  Ответить  
 
 автор: Palarm   (17.03.2009 в 15:22)   личное сообщение
 
 

А кривая работа получается потому, что аксовский комбобокс сам отбирает значения на частичное совпадение при вводе в него букв.


Поставить свойство в настройках "автоподстановка" в "Нет".

  Ответить  
 
 автор: joka   (17.03.2009 в 15:36)   личное сообщение
 
 


Поставить свойство в настройках "автоподстановка" в "Нет".



Да Вы правы! Так работает спасибо:)

осталось только отслеживать теперь RecordSource и после апдейта вертать его в зад:) а то список остается из одной двух фамилий:) собственно в зависимости от того что ввели:)

  Ответить  
 
 автор: joka   (17.03.2009 в 15:51)   личное сообщение
 
 

сделал так
Private Sub ПолеВыбораСотрудника_Change()
Dim strWhere, strSQL1, strSQL2 As String
If Len([ПолеВыбораСотрудника].Text) <> 0 Or Not IsNull([ПолеВыбораСотрудника].Text) Then
strSQL1 = "SELECT id, ФИО FROM Usys_sotr"
strSQL2 = " ORDER BY Usys_sotr.ФИО;"
strWhere = " WHERE ФИО Like '" & Me![ПолеВыбораСотрудника].Text & "*' "
Me![ПолеВыбораСотрудника].RowSource = strSQL1 & strWhere & strSQL2
Me![ПолеВыбораСотрудника].Dropdown
End If
End Sub

Private Sub ПолеВыбораСотрудника_LostFocus()
'возврат RecordSource к исходному значению
Me![ПолеВыбораСотрудника].RowSource = "SELECT id, ФИО FROM Usys_sotr ORDER BY Usys_sotr.ФИО;"
Me![ПолеВыбораСотрудника].Requery
End Sub

вроде все работает нормально, осталлся такой только момент. Ввожу первые буквы фамилии, в списке происходит отбор, список открывается. А далее если выбор осуществить клавишами вверх-вниз и потом нажатием ввод то все нормально.
а если выбор осуществить мышкой из предложенных фамилий, то лишний раз срабатывает DropDown. Приходится давить мышкой куда нибудь чтобы сбросить фокус...
Это конечно уже не глюк, но можно ли как нибудь избежать этого? Ведь если выбор с клавиш то список нормально закрывается.

  Ответить  
 
 автор: Мюллер   (17.03.2009 в 16:01)   личное сообщение
 
 


если выбор осуществить мышкой из предложенных фамилий, то лишний раз срабатывает DropDown


А енто потому, что при клике мышом у вас осуществляется лишний раз событие Change(). отседова и лишний дроп-даун.

Вааще-то если вы уж так хотите выбирать по вводимиы данным - то , ИМХО, лучше использовать сочетание текстового поля, кнопки и списка. В текстовое поле вводится искомый параметр и по нажатию кнопки список делается видимиы и формируется его рекордсоурс. Если в текстовое поле не введено ничего - в список по нажатию на кнопку выводятся все записи. Таким образом будет работать коррктнее. А то всякие LоstFocusы() - это извращение.

  Ответить  
 
 автор: joka   (17.03.2009 в 16:19)   личное сообщение
 
 

может вы и правы!
кстати лишний дроп-даун можно проскакивать на автомате используя SetFocus, то есть принудительно переставив его в какое нибудь другое поле, тогда все обновится и закроется список, но вот пока не могу понять куда его примостить, бывает возникает ошибка...

  Ответить  
 
 автор: Lukas   (17.03.2009 в 16:38)   личное сообщение
 
 


лишний дроп-даун


Задействовать логическую переменную, на получение фокуса=True, на после обновления=False.
Осуществлять действия после проверки значения переменной.

+
Описать все это отдельным классом.
При открытии формы объявлять столько переменных класса, сколько комбобоксов в форме, передавать ссылку на комбобокс в класс. А если с событиями, то вообще супер получится.

  Ответить  
 
 автор: joka   (17.03.2009 в 17:34)   личное сообщение
 
 

все вроде заработало! только кроме логической переменной еще потребовалось на после обновления добавить передачу фокуса!
кто захочет гемороя вот полный код
Private Sub ПолеВыбораСотрудника_AfterUpdate()
'поиск записи, соответствующей этому элементу управления.
If Not IsNull(Me![ПолеВыбораСотрудника]) Then
With Me.RecordsetClone
.FindFirst "id = " & Me![ПолеВыбораСотрудника]
If Not .NoMatch Then Me.Bookmark = .Bookmark
End With
Else
If MsgBox("Не выбрана фамилия сотрудника. Выбор осуществить невозможно", vbInformation, "Внимание") = vbOK Then
End If
ПолеВыбораСотрудника.Value = id
End If
'подсчет значений
With Me.RecordsetClone
If Not .BOF Or Not .EOF Then .MoveLast
RecCount.Caption = .RecordCount
End With
bolvar = False
'передача фокуса в поле ФИО на форме
If Not IsNull([ПолеВыбораСотрудника]) Then Me.полеФ.SetFocus
End Sub

Private Sub ПолеВыбораСотрудника_Change()
If bolvar Then
Dim strWhere, strSQL1, strSQL2 As String
'Me![ПолеВыбораСотрудника].RowSource = ""
If Len([ПолеВыбораСотрудника].Text) <> 0 Or Not IsNull([ПолеВыбораСотрудника].Text) Then
strSQL1 = "SELECT id, ФИО FROM Usys_sotr"
strSQL2 = " ORDER BY Usys_sotr.ФИО;"
strWhere = " WHERE ФИО Like '" & Me![ПолеВыбораСотрудника].Text & "*' "
'" WHERE Left(ФИО," & Len([ПолеВыбораСотрудника].Text) & ") = '" & [ПолеВыбораСотрудника].Text & "'"
Me![ПолеВыбораСотрудника].RowSource = strSQL1 & strWhere & strSQL2
Me![ПолеВыбораСотрудника].Dropdown
End If
End If
End Sub

Private Sub ПолеВыбораСотрудника_GotFocus()
bolvar = True
End Sub

Private Sub ПолеВыбораСотрудника_LostFocus()
'возврат RecordSource к исходному значению
Me![ПолеВыбораСотрудника].RowSource = "SELECT id, ФИО FROM Usys_sotr ORDER BY Usys_sotr.ФИО;"
Me![ПолеВыбораСотрудника].Requery
End Sub

  Ответить  
 
 автор: час   (17.03.2009 в 20:04)   личное сообщение
 
 

А может Вас устроит такой вариант
http://hiprog.com/index.php?option=com_content&task=view&id=251661615&Itemid=35

  Ответить  
 
 автор: joka   (17.03.2009 в 20:53)   личное сообщение
 
 


А может Вас устроит такой вариант
http://hiprog.com/index.php?option=com_content&task=view&id=251661615&Itemid=35


нет это не подходит форма по другому устроена, этот вариант я первым делом посмотрел:) он же на главной странице:)


Описать все это отдельным классом.
При открытии формы объявлять столько переменных класса, сколько комбобоксов в форме, передавать ссылку на комбобокс в класс. А если с событиями, то вообще супер получится.

  Ответить  
 
 автор: joka   (17.03.2009 в 20:54)   личное сообщение
 
 


Описать все это отдельным классом.
При открытии формы объявлять столько переменных класса, сколько комбобоксов в форме, передавать ссылку на комбобокс в класс. А если с событиями, то вообще супер получится.



а вот в этом совсем не силен, хотя о че речь идет представляю... было бы правда прикольно, но сам сделать не смогу:(

  Ответить  
 
 автор: Гамлет   (17.03.2009 в 22:51)   личное сообщение
 
 

Чтобы лишний раз не срабатывал DropDown, можно Me![ПолеВыбораСотрудника].Dropdown убрать из события Change и повесить на KeyUp

  Ответить  
 
 автор: joka   (18.03.2009 в 12:14)   личное сообщение
 
 


Чтобы лишний раз не срабатывал DropDown, можно Me![ПолеВыбораСотрудника].Dropdown убрать из события Change и повесить на KeyUp

так событие дроп-даун отрабатывает так что список моргает при выпадении и пользователь не успевает нажать ничего и ничего не выбрать.

А вообще, обращаюсь всем тем кто помог написать указанный выше код.. выявил новую свою недоработку, которую пока не знаю как решить:)
теперь при наборе букв, список выкидывается и видны отобранные фамилии, выбор можно осуществить мышкой и тогда все работает хорошо.
а вот клавишей вниз дальше второй записи данный код не позволяет спуститься. При нажатии ее происходит выбор второй в списке записи, после чего сразу происходит отбор ее одно и все пользователь уже не видит всех тех что ему показали в первый раз, а хотелось бы чтобы не только мышка работала а можно было по предложенному списку пройтись и курсорными клавишами.. можно как нибудь это реализовать??? может в коде недоработка?

  Ответить  
 
 автор: Мюллер   (18.03.2009 в 13:52)   личное сообщение
 
 

Так и будет происходить. При нажатии клавиши срабатывает событие change() вашего комбобокса и меняет источник записей. В нем( источнике записей ) содержится только одна запись, которую вы и выбрали.

  Ответить  
 
 автор: Гамлет   (18.03.2009 в 22:18)   личное сообщение
17 Кб.
 
 

а вот клавишей вниз дальше второй записи данный код не позволяет спуститься


Глянь атач

  Ответить  
 
 автор: joka   (19.03.2009 в 12:03)   личное сообщение
 
 

ООО спасибо!!! на первый взгляд именно то что хотелосьбы, посмотрел Ваш аттач вродевсе рабтает! попробую прикрутить к своей форме

  Ответить  
 
 автор: joka   (19.03.2009 в 13:21)   личное сообщение
 
 

есть тут тоже недоделка:( если осуществлять выбор мышкой, то фокус остается в поле со списком и соответственно не обновляется рекорд-соурс...

  Ответить  
 
 автор: joka   (19.03.2009 в 14:37)   личное сообщение
 
 

Господа эксперты ну подскажите что делать!?
вот к какому коду сейчсас пришел...
Private Sub ПолеВыбораСотрудника_AfterUpdate()
'возврат RecordSource к исходному значению
Me![ПолеВыбораСотрудника].RowSource = "SELECT id, ФИО FROM Usys_sotr ORDER BY Usys_sotr.ФИО;"
Me![ПолеВыбораСотрудника].Requery
'сброс существующего фильтра при его наличии
If Me.FilterOn Then
Me.Filter = ""
Me.FilterOn = False
ПолеФильтр = ""
ПолеФильтр.BackColor = 16777215
End If
'поиск записи, соответствующей этому элементу управления.
If Not IsNull(Me![ПолеВыбораСотрудника]) Then
With Me.RecordsetClone
.FindFirst "id = " & Me![ПолеВыбораСотрудника]
If Not .NoMatch Then Me.Bookmark = .Bookmark
End With
Else
If MsgBox("Не выбрана фамилия сотрудника. Выбор осуществить невозможно", vbInformation, "Внимание") = vbOK Then
End If
ПолеВыбораСотрудника.Value = id
End If
'подсчет значений
With Me.RecordsetClone
If Not .BOF Or Not .EOF Then .MoveLast
RecCount.Caption = .RecordCount
End With
End Sub

Private Sub ПолеВыбораСотрудника_Change()
If var_long = 40 Then Exit Sub
If var_long = 38 Then Exit Sub
Dim strWhere, strSQL1, strSQL2 As String
If Len([ПолеВыбораСотрудника].Text) <> 0 Or Not IsNull([ПолеВыбораСотрудника].Text) Then
strSQL1 = "SELECT id, ФИО FROM Usys_sotr"
strSQL2 = " ORDER BY Usys_sotr.ФИО;"
strWhere = " WHERE ФИО Like '" & Me![ПолеВыбораСотрудника].Text & "*' "
Me![ПолеВыбораСотрудника].RowSource = strSQL1 & strWhere & strSQL2
End If
End Sub


Private Sub ПолеВыбораСотрудника_KeyDown(KeyCode As Integer, Shift As Integer)
var_long = KeyCode
End Sub

Private Sub ПолеВыбораСотрудника_KeyUp(KeyCode As Integer, Shift As Integer)
Me![ПолеВыбораСотрудника].Dropdown
End Sub

Private Sub ПолеВыбораСотрудника_LostFocus()
'возврат RecordSource к исходному значению
Me![ПолеВыбораСотрудника].RowSource = "SELECT id, ФИО FROM Usys_sotr ORDER BY Usys_sotr.ФИО;"
Me![ПолеВыбораСотрудника].Requery
End Sub

есть две проблемы:
1. после выбора мышкой не обновляется источник строк так как фокус не уходит из поля со списком. (если самому тыкнуть куда нибудь на форме, то есть сбросить фокус со списка. источник строк обновляется и все ок)
2. этот кусок кода


'поиск записи, соответствующей этому элементу управления.
If Not IsNull(Me![ПолеВыбораСотрудника]) Then
With Me.RecordsetClone
.FindFirst "id = " & Me![ПолеВыбораСотрудника]
If Not .NoMatch Then Me.Bookmark = .Bookmark
End With
Else
If MsgBox("Не выбрана фамилия сотрудника. Выбор осуществить невозможно", vbInformation, "Внимание") = vbOK Then
End If
ПолеВыбораСотрудника.Value = id
End If
вызывает дополнительное выпадение списка почему-то.. не понимаю почему:( то есть если этот кусок закоментить список будет отрабатывать нормально (за исключением пункта 1), но тогда не обновляются в соответсвии с выбором данные на форме самой...

  Ответить  
 
 автор: joka   (19.03.2009 в 20:12)   личное сообщение
 
 

может надо объединить афтер апдейт с изменением??? и весь код разместить в обработчике "изменение"???

  Ответить  
 
 автор: joka   (20.03.2009 в 12:05)   личное сообщение
 
 

все заработало! СПАСИБО ВСЕМ КТО ПОМОГ!

  Ответить  
 
 автор: Гамлет   (20.03.2009 в 19:09)   личное сообщение
 
 

если осуществлять выбор мышкой, то фокус остается в поле со списком и соответственно не обновляется рекорд-соурс

Покажи как поборол, плиз

  Ответить  
 
 автор: joka   (23.03.2009 в 11:14)   личное сообщение
 
 

Вот весь код, использовать булевую переменную и соотвественно if с ней тебе наверно ненадо, просто у меня в афтер апдейт там дополнительное событие Change возникало... тебе надо добавить наверно только обновление на получение фокуса и отловить нажатие мыши и проверять его в Change.


Private Sub ПолеВыбораСотрудника_AfterUpdate()
'возврат RecordSource к исходному значению
Me![ПолеВыбораСотрудника].RowSource = "SELECT id, ФИО FROM Usys_sotr ORDER BY Usys_sotr.ФИО;"
Me![ПолеВыбораСотрудника].Requery
'поиск записи, соответствующей этому элементу управления.
If Not IsNull(Me![ПолеВыбораСотрудника]) Then
With Me.RecordsetClone
.FindFirst "id = " & Me![ПолеВыбораСотрудника]
If Not .NoMatch Then Me.Bookmark = .Bookmark
End With
Else 'подстановка текущего значения в случае отсутствия ФИО, соответствующего введеному тексту
Me![ПолеВыбораСотрудника] = id
End If
'подсчет значений
With Me.RecordsetClone
If Not .BOF Or Not .EOF Then .MoveLast
RecCount.Caption = .RecordCount
End With
End Sub

Private Sub ПолеВыбораСотрудника_Change()
Dim strWhere, strSQL1, strSQL2 As String
If var_long = 40 Then Exit Sub
If var_long = 38 Then Exit Sub
'осуществление динамического отбора записей по введеным символам
If (Not bolvar) Or (var_long <> -1) Then
If Len([ПолеВыбораСотрудника].Text) <> 0 Or Not IsNull([ПолеВыбораСотрудника].Text) Then
strSQL1 = "SELECT id, ФИО FROM Usys_sotr"
strSQL2 = " ORDER BY Usys_sotr.ФИО;"
strWhere = " WHERE ФИО Like '" & Me![ПолеВыбораСотрудника].Text & "*' "
Me![ПолеВыбораСотрудника].RowSource = strSQL1 & strWhere & strSQL2
Me![ПолеВыбораСотрудника].Dropdown
End If
End If
bolvar = False
End Sub

Private Sub ПолеВыбораСотрудника_GotFocus()
Me![ПолеВыбораСотрудника].RowSource = "SELECT id, ФИО FROM Usys_sotr ORDER BY Usys_sotr.ФИО;"
Me![ПолеВыбораСотрудника].Requery
End Sub

Private Sub ПолеВыбораСотрудника_KeyDown(KeyCode As Integer, Shift As Integer)
var_long = KeyCode
End Sub

Private Sub ПолеВыбораСотрудника_LostFocus()
Me![ПолеВыбораСотрудника].RowSource = "SELECT id, ФИО FROM Usys_sotr ORDER BY Usys_sotr.ФИО;"
Me![ПолеВыбораСотрудника].Requery
End Sub

Private Sub ПолеВыбораСотрудника_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
bolvar = True
var_long = -1
End Sub

  Ответить  
HiProg.com - Технологии программирования
Rambler's Top100 TopList