Ms access: поле автозаполнения со значениями из другой таблицы - PullRequest
0 голосов
/ 22 января 2010

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

Я использую Ms Access 2003.

Предположим, у меня есть две таблицы:

Таблица1: идентификатор (автономный номер), [...], ключевые слова (памятка)

Таблица2: идентификатор (автономный номер), ключевое слово (текст)

Я хочу: 1) Когда пользователь вводит буквы в Table1.Keywords, которые моя база данных ищет в Table2.keyword для поиска ближайшего значения, и предлагает его автозаполнением (точно так же, как Google предлагает слово для поиска при вводе)

2) Когда пользователь нажимает «,», он может добавить еще одно ключевое слово в то же поле (и автозаполнение все еще выполняется для этого следующего значения)

3) Если он вводит ключевое слово, не включенное в Таблицу2, и нажимает «,», его спрашивают, хочет ли он добавить это значение в Таблицу2

Ну, я не уверен, что все это ясно ... может быть, это много вещей ...

Но я был бы признателен, если бы вы могли мне помочь ...

Заранее спасибо J.

Ответы [ 3 ]

1 голос
/ 23 января 2010

Было бы сложно сделать это с одним элементом управления, но с двумя элементами управления, выпадающим списком для выбора значения для добавления и текстовым полем, отображающим поле memo, вы можете получить событие AfterUpdate поля со списком, добавив запятую и выбранное значение для существующих данных. Примерно так:

  Private Sub cmbChooseKeyword_AfterUpdate()
    If Not IsNull(me!cmbChooseKeyword) Then
       Me!txtKeywordMemo = (Me!txtKeywordMemo + ", ") & Me!cmbChooseKeyword
    End If
  End Sub

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

  SELECT tblKeywords.*
  FROM tblKeywords
  WHERE InStr(Forms!MyForm!txtKeywordMemo, tblKeywords.Keyword) = 0;

Тогда вы добавите:

  Me.Dirty = False
  Me!cmbChooseKeyword.Requery

... в конце кода AfterUpdate выше (внутри End If):

  Private Sub cmbChooseKeyword_AfterUpdate()
    If Not IsNull(me!cmbChooseKeyword) Then
       Me!txtKeywordMemo = (Me!txtKeywordMemo + ", ") & Me!cmbChooseKeyword
       Me.Dirty = False
       Me!cmbChooseKeyword.Requery
    End If
  End Sub

... и вы захотите добавить запрос к событию OnCurrent вашей формы, а также (чтобы при получении записи в поле со списком уже отсутствовали все ключевые слова, которые уже есть в списке).

Теперь, несмотря на все сказанное, я бы полностью рекомендовал не делать этого. Это денормализованный способ хранения данных, и это приводит к проблемам:

  1. что если вы хотите удалить одно ключевое слово?

  2. что если вы хотите, чтобы ключевые слова сортировались в алфавитном порядке?

  3. что, если у вас есть сотни тысяч записей, и вы хотите искать это поле с помощью LIKE "* Keyword *" - будет слишком медленно (без индексов, и не будет использоваться хорошо, даже если есть) были)?

Вы действительно должны использовать правильную структуру «многие ко многим» с дополнительной таблицей между таблицей, в которой вы в настоящий момент храните памятку по ключевым словам, и таблицей списка ключевых слов. Это «объединяет» два, а затем даст вам список.

Затем можно использовать подчиненную форму с раскрывающимся списком для заполнения каждой строки таблицы объединения.

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

0 голосов
/ 22 января 2010

CodeSlave упоминает, как это будет работать. Но это будет работать только для одного значения. Там нет никакого способа сделать вещь, состоящую из нескольких слов, разделенных запятыми. Только одно слово за раз.

Что касается добавления новых значений. Элемент управления combobox поддерживает событие OnNotInList, которое может делать то, что вы говорите.

Сет

0 голосов
/ 22 января 2010

Почему бы не использовать «поле со списком» и установить для его типа источника строки значение «Таблица / запрос», а затем сделать источник строки запросом ко второй таблице. Просто убедитесь, что вы не включаете лимит в список.

...