Подстановка из большого списка - нужны идеи

Андрей Артемьев
Дата: 20.11.2006 20:44:24
Разрабатывается проект adp на Access 2003 в связке с MS SQL 2000. В нем есть большая таблица t1, содержащая список из n*100000 документов:
id - ключ
bso_sn - номер документа (№, выдан,источник) - строка
Имеется ленточная форма, отображающая таблицу t2 выдачи документов вида:
agent - указатель на сотрудника, получающего документ
bso -  указатель на id документа (t2.bso-t1.id)

В форме в каждой строке следует выбрать выдаваемый документ. Что получается:

1. Поле t2.bso со списком подстановки - тривиальное решение.
Не удается из-за величины t1 - в поле отображаются далеко не все документы.

2. Поле t2.bso со списком подстановки с попыткой менять RecordSource по ходу ввода в зависимости от введенного значения - чтобы список получился поменьше, но туда попали бы и уже выбранные в других записях документы, и выбираемый.
Не получается, т.к. access категорически отказывается обновлять RecordSource пока не сохранено редактируемое значение.

3. Вариант 2 с "LimitToList=No" в поле со списком - чтобы принималось любое значение, а RowSorce корректировался после записи. Крайне неудобно, поскольку придется работать не с t2.bso=t1.id, а с t1.bso_sn - источник данных формы усложнится и отрабатывать будет очень медленно.

4. Свободное поле ввода не связанное с каким-либо источником данных, поле t2.bso не отображается. Пользователь вводит документ вручную в свободное поле, далее в его обработчике AfterUpdate анализируется введенный текст (трактуется как t1.bso_sn), по нему выбирается t1.id и подставляется в форму.
Этот вариант работает, но приходится отказаться от ленточной формы в пользу обычной, т.к. поле, не связанное и источником данных, отображается одинаково во всех строках. Делать это очень не хочется - теряется удобство и наглядность

Прошу подсказать, какие еще возможны пути решения?
mds_world
Дата: 20.11.2006 21:21:41
Не уверен,что правильно понял задачу. Теи не менее.
Если совместить вар.4 - свободное поле и вложенную табличную или ленточную подформу линкующуюся со значением в свободном поле. Такой вариант вы просматривали?
proposed amendment
Дата: 20.11.2006 21:33:22
Андрей Артемьев
Прошу подсказать, какие еще возможны пути решения?


вариант 4 возможен в ленточных формах если прибегнуть к некоторым ухищрениям...
вадя
Дата: 20.11.2006 22:46:44
не совсем понятно, что Вы хотите получить,
и создается впечатление, что Вы не осознаете, что у Вас получится.

автор
В форме в каждой строке следует выбрать выдаваемый документ. Что получается


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

Одиночная? тогда какие проблемы? свободное поле со списом.
вадя
Дата: 20.11.2006 22:54:03
или вы заполняете таблицу и в одно из полей Вы хотите вводить данные из другой таблицы?

автор
. Поле t2.bso со списком подстановки - тривиальное решение.
Не удается из-за величины t1 - в поле отображаются далеко не все документы


что значит отображаются далеко не все документы?



автор
2. Поле t2.bso со списком подстановки с попыткой менять RecordSource по ходу ввода в зависимости от введенного значения - чтобы список получился поменьше, но туда попали бы и уже выбранные в других записях документы, и выбираемый.
Не получается, т.к. access категорически отказывается обновлять RecordSource пока не сохранено редактируемое значение.


тоже не правда. делается элементарно. Вы что-то не правильно делаете. или используете не все события , которые предоставляет Вам акс.
Allll
Дата: 21.11.2006 09:26:50
Андрей Артемьев
1. Поле t2.bso со списком подстановки - тривиальное решение.
Не удается из-за величины t1 - в поле отображаются далеко не все документы.

Стандартная настройка Access - показывать 1000 строк в списке.
Андрей Артемьев
2. Поле t2.bso со списком подстановки с попыткой менять RecordSource по ходу ввода в зависимости от введенного значения - чтобы список получился поменьше, но туда попали бы и уже выбранные в других записях документы, и выбираемый.
Не получается, т.к. access категорически отказывается обновлять RecordSource пока не сохранено редактируемое значение.

Не понятно, при чём тут RecordSource, нужно менять RowSource поля со списком:
Private Sub Form_Load()
' пусть покажет первые 1000 строк
ПолеСоСписком0.RowSource = "SELECT id, bso_sn FROM t1;"
' или вполне хватит и 100 строк, чтобы быстрее работало
' ПолеСоСписком0.RowSource = "SELECT TOP 100 tblPass.PassNumber FROM tblPass;"
End Sub

Private Sub ПолеСоСписком0_Change()
' при вводе каждого символа в списке будут показаны только строки удовлетворяющие условиям отбора
ПолеСоСписком0.RowSource = "SELECT id, bso_sn FROM t1 WHERE (((bso_sn) Like '" & ПолеСоСписком0.text & "*'));"
' наверное, имеет смысл тоже ограничивать с помощью TOP 100
End Sub

И в целом, смысл этого пункта, остался для меня загадкой.
Андрей Артемьев
3. Вариант 2 с "LimitToList=No" в поле со списком - чтобы принималось любое значение, а RowSorce корректировался после записи. Крайне неудобно, поскольку придется работать не с t2.bso=t1.id, а с t1.bso_sn - источник данных формы усложнится и отрабатывать будет очень медленно.

Видимо, не в том событии меняли RowSource.
Allll
Дата: 21.11.2006 09:28:12
' пусть покажет первые 1000 строк
ПолеСоСписком0.RowSource = "SELECT id, bso_sn FROM t1;"
' или вполне хватит и 100 строк, чтобы быстрее работало
' ПолеСоСписком0.RowSource = "SELECT TOP 100 id, bso_sn FROM t1;"
End Sub

Private Sub ПолеСоСписком0_Change()
' при вводе каждого символа в списке будут показаны только строки удовлетворяющие условиям отбора
ПолеСоСписком0.RowSource = "SELECT id, bso_sn FROM t1 WHERE (((bso_sn) Like '" & ПолеСоСписком0.text & "*'));"
' наверное, имеет смысл тоже ограничивать с помощью TOP 100
End Sub
Гаишник
Дата: 21.11.2006 10:17:17
Андрей Артемьев
...Этот вариант работает, но приходится отказаться от ленточной формы в пользу обычной, т.к. поле, не связанное и источником данных, отображается одинаково во всех строках.

Но это поле может быть размещено в заголовке или примечании формы...
Андрей Артемьев
Дата: 21.11.2006 11:57:58
Чего хочется добиться.
Ленточная форма, о которой идет речь описывает ситуацию выдачи документов строгой отчетности сотрудникам:
 сотрудник_1     дата     документ_0123456
сотрудник_1 дата документ_0127777
сотрудник_2 дата документ_5555456
сотрудник_3 дата документ_0199956
сотрудник_3 дата ????????????????
Т.е. в каждой строке нужно сопоставить сотрудника из списка сотрудников и документ их списка документов. Названия всех документов сходны и имеют вид "АБВ xxxxxx", где xxxxxx-номер, поэтому наиболее быстрый способ их выбора - просто набрать на клавиатуре. Простота и скорость работы для будущего оператора базы будет очень важны, по сути человек полдня будет заниматься только этим.

Вадя
что значит отображаются далеко не все документы?

В списках и полях со списками access отображает по умолчанию только 1000 строк, максимальное значение - 32766. У меня же документов сотни тысяч, поэтому для многих из них поле со списком просто остается пустым.

Alll
lНе понятно, при чём тут RecordSource, нужно менять RowSource поля со списком

Пардон, здесь у меня опечатка, конечно я имел в виду RowSource.
Беда в том, что заранее нельзя никак ограничить выбор. В приведенном выше примере 4 документа уже выданы и должны корректно отображаться. А что за документы будут выбраны пятым и последующими заранее (до открытия ленточной формы) неизвестно. Поэтому если пользоваться полем со списков, то его RowSource должен содержать все.
Пункт 3 - это попытка ограничить RowSource "по ходу ввода" примерно так, как Вы и написали. Но пока ввод в поле не закончен, изменить RowSource не удается - на последовательность команд
поле_со_списком.RowSource="новый_запрос"
поле_со_списком.Requery
access отвечает, что пока поле редактируется, менять источник строк нельзя.
Делать это пытался в OnChange, OnNotInList, OnKeyPress.

Гаишник
Но это поле может быть размещено в заголовке или примечании формы...

Да, это выход, но крайне неудобный для будущего оператора. Если ввод организовать в заголовке или примечании формы, а в ленточной части только показывать результаты, то теряется наглядность. Обсуждаемая форма - лишь часть другой и места для нее остается немного.

mds_world
совместить вар.4 - свободное поле и вложенную табличную или ленточную подформу линкующуюся со значением в свободном поле

В чистом виде такой вариант не пройдет, поскольку свободное поле будет отображаться в каждой строке ленточной формы и в каждой иметь одинаковое содержание - в этом то и проблема 4 варианта.
Но сама идея использования вложенной подформы весьма заманчива... В ней можно отобразить сколько угодно строк, а показывать в главной форме можно лишь одну, чем для оператора и будет достигнута иллюзия одного поля ввода. Только один существенный вопрос: как сделать так, чтобы по мере набора номера документа "АБВ xxxxxx" в этой вложенной подформе происходило автоматическое перемещение на запись с этим документом? Использовать OnKeyPress и анализировать уже введенную часть или есть способ проще?
mds_world
Дата: 21.11.2006 12:02:02
Есть вариант значительно проще. Использовать свойство Text в событии Change.

Второе. Я не предлагал использовать свободное поле на ленточной форме, нет, конечно на главной. И с ним линковать вложенную подформу