MS Access извлекает несколько совпадающих текстовых строк из длинного текстового поля по сравнению со списком таблиц - PullRequest
0 голосов
/ 05 марта 2019

Проблема: запрос не может извлечь все ограниченных слов, найденных в длинном текстовом поле.Он получает запрещенные слова из столбца таблицы с ~ 100 значениями.

Пример данных

Таблица: RecipeTable с длинным текстом Поле: RecipeText

Пример Содержимое поля RecipeText: Добавить брюкву, лук-порей, морковь и капустув Instant Pot®.Запечатайте и готовьте под высоким давлением в течение 4 минут.Быстро выпустить пар.Тонко нарежьте грудинку поперек зерна и перенесите на блюдо.Разложите овощи вокруг мяса, посыпьте петрушкой и подайте со сметаной, хреном и горчицей по бокам.

Желаемый результат: Хотите сравнить поле RecipeText со всеми значениями в этомКраткое текстовое поле RestrictedItem в таблице: RestrictedTable.

RestrictedTable.RestrictedItem содержит 100 значений.Допустим, в этом упражнении содержится 6: молоко, выпечка, ложка, морковь, горчица и пар.

Запрос найдет эти совпадающие слова в произвольном порядке для одиночной записи: морковная горчица пара

Я пробовал это: Как найти слова в поле заметки с доступом Microsoft

Результат: Находит только 1 из множества совпадений в пределах LongТекстовое поле.

Желаемый результат : Найти ALL совпадающих слов, извлеченных в строке длинного текста.Дубликаты и подстановочные знаки в порядке.Чувствительность к регистру - это плохо.

Пример попытки:

SELECT a.Adjectives, b.Content
FROM A, B
WHERE b.Content Like "*" & a.[adjectives] & "*"

LIKE и после того, где я считаю, что проблема.Я пытался использовать%, круглые скобки, пробелы и т. Д. Безрезультатно.

Мой стал таким:

SELECT RecipeTable.RecipeText, RestrictedTable.RestrictedItem
FROM RecipeTable, RestrictedTable
WHERE RecipeTable.RecipeText LIKE  "*" & RestrictedTable.RestrictedItem & "*";

Примечания:

  1. Я могу найти много советов по поиску отдельных слов, но не сравнивать столбцы всей таблицы с одним полем.
  2. И еще много советов по поиску первой подстроки или n-й позиции, ноЯ хочу, чтобы все подстроки совпадали.Не позиция, и я боюсь, что применение обрезки и т. Д. Замедлит процесс поиска 100 слов и обрезки для каждого из них.
  3. У меня все нормально, я делаю это вычисляемое поле в моей форме, которое содержит поле RecipeText.
  4. Также отлично подходит для создания кнопки, которая запускает запрос для сравнения поля RecipeText со списком RestrictedTable.RestrictedItem и заполнения пустого поля RestrictedFound в той же форме.

1 Ответ

0 голосов
/ 05 марта 2019

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

После разбиения слов из мемо-поля на массив они могут быть вставлены в отдельную таблицу со ссылкой на внешний ключ RecipeTable.Это может быть временная таблица или постоянная при необходимости и может быть частью процесса рабочего процесса.Поле, такое как PendingReview, может быть добавлено в RecipeTable для обработки новых записей, а затем помечено как ложное, чтобы они больше не обрабатывались.

После добавления слов в другую таблицу ее можно присоединить к RecipeTable по внешнему ключу, и у вас должны быть все совпадения ограниченных слов.

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

Вы можете делать все это в VBA с помощью словаря поиска слов с ограничениями, т. Е. Запроса таблицы слов с ограничениями, добавления в словарь и последующего циклического сопоставления каждого слова в поле memo с сопоставлением без учета регистра в нижнем регистре или без регистра, но это может занять некоторое время.

Первый фрагмент кода ниже

( Если вы хотите проверять время компиляции, вы должны обратиться к Microsoft Run Scripting Runtime, мой путь C: \ Windows \ SysWOW64 \scrrun.dll )

Dim dic as Dictionary
Dim memoField as string
Dim words() as String
Dim matchCnt as Integer
'Other variables I didnt declare

'Code to populate dictionary
'Do Until rstRestricted.EOF
'  dic.add LCase$(rst("restrictedWord")), 0
'  rstRestricted.MoveNext
'Loop
'rstRestricted.Close
'Set rstRestricted = Nothing

Set rst = New adodb.Recordset
rst.Open "SELECT [MemoField] FROM RecipeTable;"
lngRowCnt = CLng(rst.RecordCount) - 1
For x = 0 to lngRowCnt
   memoField = LCase$(Nz(rst("MemoField")))
   'Replace punctuation like commas, periods
   'memoField = Replace(memoField, ",","")

   'Now split after data scrubbed
   words = Split(memoField, " ")
   intWordCnt = UBound(words)
   For z = 0 to intWordCnt
      If LenB(words(z)) <> 0 Then
          If dic.Exists(words(z) = True Then
              matchCnt = dic(words(z))
              dic(words(z)) = matchCnt + 1
          End If
      End If
   Next z
Next x

Dim WordKeys() as Variant
Dim y as Integer
Dim restrictedWord as string
Dim wordCnt as Integer

WordKeys = dic.Keys
For y = 0 to UBound(WordKeys) '-1
     restrictedWord = CStr(WordKeys(y))
     wordCnt = CInt(WordKeys(restrictedWord))
     'code to save or display stats
Next y

rst.Close
Set rst = Nothing
Set conn = Nothing

Я бы просто разделил все слова на рабочую таблицу с индексированным полем слова, а затем суммировал бы количество ограниченных слов.

Второй фрагмент кода

'Option Explicit 
Dim sql as String
Dim memoDelimitedData() as String
'Other variables declared

'Code to open Recordset table for recipe and also code to open 
'Work table with adOpenDynamic (SELECT * from WorkTable)

'loop through records to be processed
'Split Field (May need variant instead of array.  My Access VBA is rusty)
 words = Split(memoField, " ")
 intWordCnt = UBound(words)
 For x = 0 to intWordCnt
    With rstWorkTable
      .AddNew
      !Word = words(x)
      !ForeignKeyIdToRecipeTable = intForeignKeyId
      .Update
    End With
 Next x 

Затем, когда вы добавите записи рабочей таблицы, вы можете присоединиться к RecipeTable и RestrictedTable.

Итаксоздать WorkTable слов с разделителями из поля memo.Получите ссылку внешнего ключа на таблицу рецептов, затем присоедините таблицу RestrictedTable к таблице WorkTable с помощью RestrictedItem.

При необходимости это может быть запрос для таблицы создания или постоянной таблицы промежуточной таблицы.и т. д.

Итак, что-то вроде этого даст вам совпадения любых слов в вашей ограниченной таблице:

SELECT RecipeTable.RecipeText, RestrictedTable.RestrictedItem
FROM RecipeTable
  INNER JOIN WorkTable ON
   RecipeTable.Id = WorkTable.RecipeTableId
  INNER JOIN RestrictedTable ON
   WorkTable.ForeignKeyIdToRecipeTable = RestrictedTable.RestrictedItem

Функция разделения доступа MS

В этот момент вы можете делать подсчеты, суммы и другие данные.

Извините, я думал, что у меня есть пример кода, но я не смог его найти.Мне приходилось делать что-то подобное в колледже много месяцев назад, используя VBA и Access (Word Count / Ranking Assignment), но я не могу найти это.В настоящее время я бы делал такие вещи с SQL Server с таблицами чисел, функциональностью XML / JSON или возможностью полнотекстового поиска.

Надеемся, что это может помочь вам направить вас в правильном направлении, если вам нужно ограничить свою работу в MS Access.

Если вам неудобно работать с наборами записей ADODB или DAO, вы можете создатьФайл с разделителем CSV с внешним ключом и словом затем импортирует этот файл в рабочую таблицу.

...