Я на самом деле объединил оба подхода.Я предупреждаю вас сейчас, это может быть многословно и может показаться излишним.Однако я обнаружил, что это хорошее общее решение, которое очень хорошо масштабируется .
Подход состоит из четырех таблиц:
PDLists (local to the front-end)
--------
K*PDListID Long
*PDListName Text (50)
CodeLen Long
*UserCanEdit Boolean [False]
*HasActiveCheck Boolean [False]
PDChoices (linked to the back-end)
---------
K*PDChoiceID Long AUTONUMBER
*PDListID Long
PDCode Text (10)
*PDDesc Text (255)
*Seq Long
*IsActive Boolean [True]
PDChoicesLocked (local to the front-end)
---------------
K*PDChoiceID Long AUTONUMBER
*PDListID Long
PDCode Text (10)
*PDDesc Text (255)
*Seq Long
*IsActive Boolean [True]
PDFields (local to the front-end)
--------
K*PDListID Long
K*TblName Text (50) Used to enforce referential integrity for fields that use code:description pair & to restrict length of text entry
K*FldName Text (50) Used to enforce referential integrity for fields that use code:description pair & to restrict length of text entry
LEGEND: K
: первичный ключ;*
: обязательное поле;[Foo]
: значение по умолчанию
PDLists
В первой таблице есть запись для каждой таблицы поиска.Поле CodeLen
(длина кода) используется для поиска, в котором вы хотите сохранить значимые сокращения.Например, вы должны установить CodeLen = 1
для поиска типа: N: North; E: East; S: South; W: West
.
Если UserCanEdit
- Истина, то варианты раскрывающегося списка сохраняются в серверной таблице PDChoices.В противном случае они хранятся в локальной таблице PDChoicesLocked.
У меня есть вспомогательная функция, которая генерирует инструкцию SQL для использования в комбинированных полях.Я передаю ему PDListID, и он проверяет поля CodeLen и UserCanEdit для создания соответствующего оператора SELECT.Вспомогательная функция просто печатает это в ближайшем окне, и я копирую и вставляю его туда, где мне это нужно.
PDListID PDListName CodeLen UserCanEdit HasActiveCheck
1 Cardinal Directions 1 True False
PDChoices / PDChoicesLocked
Единственное различие между этими двумя таблицами состоит в том, где они находятсянаходится (объяснено выше).Я мог бы объединить обе таблицы в одну на бэкэнде, но наличие локальной заблокированной таблицы означает, что я могу изменить эту таблицу во время разработки и гарантировать ее содержимое, даже если я разверну свою программу на разных клиентах.
Поле Seq
(последовательность) используется для пользовательской сортировки вариантов.А поле IsActive
позволяет скрывать варианты в раскрывающемся списке без потери ссылочной целостности, если эти поиски используются в настоящее время.
PDChoiceID PDListID PDCode PDDesc Seq IsActive
1 1 N North 1 True
2 1 E East 3 True
3 1 S South 2 True
4 1 W West 4 True
PDFields
Эта таблица существует для обеспечения ссылочной целостности.На самом деле это не может быть выполнено на уровне базы данных, поэтому оно применяется в форме, которую пользователи могут использовать для внесения изменений в варианты раскрывающегося списка.
PDListID TblName FieldName
1 StreetAddresses CardinalDirection
1 Locations CompassPoint
Форма раскрывающегося списка
Когда пользователи дваждыщелкните поле со списком с возможностью редактирования пользователем (т. е. UserCanEdit=True
), после чего будет загружена форма раскрывающегося списка.Заголовок формы установлен на PDListName
.Если CodeLen
не равно нулю, текстовое поле для кода поиска становится видимым.Если HasActiveCheck=True
, то отображается флажок, который позволяет пользователю переключать активный статус отдельных выпадающих меню.
У меня есть пользовательская функция, которая ограничивает количество символов, которые можно вводить в PDCode
поле на основе CodeLen
.Однако, если CodeLen
равно нулю, я проверяю, нужно ли ограничивать длину поля PDDesc
.Например, если тип поля поля Long, то я предполагаю, что я сохраняю PDChoiceID в поле и не ограничиваю длину PDDesc
.Но если указанное поле является полем Text / Varchar, тогда я получаю длину этого поля и соответственно ограничиваю длину PDDesc
.
Когда форма Pulldowns закрыта, я запрашиваю поле со списком, которое дважды вводит пользователь- щелкнул, чтобы у них был немедленный доступ к любым новым добавленным параметрам.
Резюме
У этого подхода есть один существенный недостаток: очень много работы, чтобы все сначала настроить.Однако большая часть этой работы заключается в предоставлении редактируемой пользователем таблицы в серверной части и формы, позволяющей пользователю обновлять эти варианты выбора.Если вы придерживаетесь только трех локальных таблиц, вы получаете масштабируемость и гибкость без тонны работы.
Плюсы :
- это гибкость ;значения могут быть сохранены в вашей основной таблице несколькими способами
- с помощью PDChoiceID
- с помощью PDCode
- с помощью PDDesc
- это 1080 * масштабируемый *;как только начальная настройка будет завершена, добавление новых поисков будет быстрым
- , оно станет мощным ;
- варианты можно удалить из выпадающего меню, не удаляя их, установив
IsActive=False
- порядок сортировки элементов полностью настраиваемый
- вы можете предоставить интерфейс, позволяющий пользователям вносить изменения в список, не жертвуя ссылочной целостностью
Минусы :
- первоначальная настройка требует больше усилий, чем две представленные вами опции
- , вы не можете обеспечить ссылочную целостность на уровне базы данных;Я не рассматриваю это как основной довод "против", потому что если вы будете осторожны, вы все равно сможете обеспечить ссылочную целостность на уровне приложений
Последнее замечание.Я понимаю, что в Access 2007 появилась функция, позволяющая пользователям добавлять элементы в поле со списком.С точки зрения разработчика, эта функция бесполезна, потому что изменения хранятся во внешнем интерфейсе (и это не обеспечивает ссылочную целостность).Мой подход сохраняет эти изменения в бэкэнде (там, где они есть), и я продолжаю использовать его, несмотря на новую функцию Access 2007.