与表列表相比,MS Access从长文本字段中提取多个匹配的文本字符串

问题描述 投票:0回答:1

问题:查询无法提取在长文本字段中找到的所有受限制的单词。它从表格列中得到约100个值的限制词。

样本数据

表:具有长文本字段的RecipeTable:RecipeText

RecipeText的示例内容:将大头菜,韭菜,胡萝卜和卷心菜加入InstantBot®中。密封并在高压下煮4分钟。快速释放蒸汽。将牛腩切成薄片,然后转移到盘子上。将蔬菜排列在肉周围,撒上欧芹,边上加入酸奶油,辣根和芥末。

所需结果:想要将RecipeText字段与表中的短文本字段RestrictedItem中的每个值进行比较:RestrictedTable。

RestrictedTable.RestrictedItem包含100个值。假设这个练习包含6个:牛奶,烤,勺子,胡萝卜,芥末和蒸汽。

查询会发现这些匹配的单词没有特定顺序的单个记录:胡萝卜芥末蒸汽

我试过thisHow to find words in a memo field with microsoft access

结果:在“长文本”字段中仅查找多个匹配项中的一个。

期望结果:查找在长文本字符串中提取的所有匹配单词。重复和通配符都没问题。区分大小写很糟糕。

试图示例:

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

喜欢和之后是我认为问题所在。我尝试使用%,括号,空格等无济于事。

我成了这个:

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。
sql ms-access access-vba access
1个回答
0
投票

下面的代码是两种查找备忘录字段中所有受限单词的方法。虽然这可以在没有登台/工作表的情况下以编程方式完成,但我建议使用临时或永久表来通过VBA中的拆分功能从备忘录字段中提取单词(在考虑标点符号和其他数据清理之后)。

将备注字段中的单词拆分为数组后,可以将它们插入到具有RecipeTable外键引用的单独表中。如果需要,这可以是临时表或永久表,并且可以是工作流程过程的一部分。可以将类似PendingReview的字段添加到RecipeTable以处理新记录,然后标记为false,以便不再处理它们。

将单词添加到另一个表后,可以通过外键将其加入RecipeTable,并且您应该拥有受限制单词的所有匹配项。

获得信息后,您可以存储统计信息并从临时表中丢弃工作记录,或删除工作记录,直到再次运行该过程。

您可以在VBA中使用限制词的字典查找完成所有操作,即查询限制词表,添加到词典然后循环通过匹配备注字段中的每个词与小写或不区分大小写的比较,但它可能需要而。

下面的第一个代码片段

(如果您需要编译时间检查,那么您必须引用Microsoft 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。

因此,从备忘录字段中构建一个分隔词的工作表。具有对配方表的外键引用然后通过RestrictedItem将RestrictedTable加入WorkTable。

如果需要,这可以是对make表或临时表永久表的查询。等等

所以这样的东西会给你匹配,限制表中的任何单词:

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

MS Access Split Function

此时,您可以执行计数,总和和其他数据。

对不起,我以为我有示例代码,但我找不到它。我不得不在大学前几年使用VBA和Access(字数统计/排名分配)做类似的事情,但我找不到它。现在我用SQL Server做数字表,XML / JSON功能或全文搜索功能。

希望如果您需要限制MS Access中的工作,这可能有助于指明您正确的方向。

如果您不习惯使用ADODB或DAO记录集,则可以使用外键和单词构建CSV分隔文件,然后将该文件导入工作表。

© www.soinside.com 2019 - 2024. All rights reserved.