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

时间:2019-03-05 04:23:36

标签: sql ms-access access-vba access

问题:查询无法提取“长文本”字段中出现的所有所有限制词。它从〜100个值的表列中获取限制词。

样本数据

表格:带有长文本的RecipeTable字段:RecipeText

RecipeText字段的示例内容:将大头菜,韭菜,胡萝卜和卷心菜添加到InstantPot®中。密封并在高压下烹饪4分钟。快速释放蒸汽。将牛ket切成薄片,并转移到食用盘中。将蔬菜放在肉周围,撒上欧芹,并在旁边加酸奶油,辣根和芥末。

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

RestrictedTable.RestrictedItem包含100个值。假设此练习包含6种:牛奶,烤面包,汤匙,胡萝卜,芥末和蒸汽。

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

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

结果:在“长文本”字段中仅仅找到1 个匹配项。

所需结果:查找在长文本字符串中提取的 ALL 个匹配词。复制和通配符都可以。区分大小写是不好的。

尝试的示例:

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 List进行比较,并在同一表格上填写一个空字段RestrictedFound。

1 个答案:

答案 0 :(得分:0)

下面的代码是找到备注字段中所有受限制单词的两种方法。尽管所有这些都可以通过编程来完成,而不需要暂存/工作表,但我还是建议使用临时表或永久表通过VBA中的split函数从备忘字段中提取单词(在考虑了标点符号和其他数据清理之后)。

将备注字段中的单词拆分为数组后,可以将其插入到带有RecipeTable的外键的单独表中。这可以是临时表,也可以是永久表,可以作为工作流程的一部分。可以将诸如PendingReview之类的字段添加到RecipeTable中以处理新记录,然后再将其标记为false,这样就不会再次对其进行处理。

将单词添加到另一个表后,可以将其加入RecipeTable 通过外键输入,那么您应该具有所有匹配的限制词。

一旦获得了信息,就可以存储统计信息并从临时表中丢弃工作记录,或者删除工作记录,直到再次运行该流程为止。

您可以在VBA中使用受限词的词典查找来完成所有操作,即查询受限词表,添加到词典中,然后通过匹配备注字段中的每个单词以小写或不区分大小写的方式进行循环,但是可能需要一段时间。

下面的第一个代码段

如果要进行编译时检查,则必须引用Microsoft脚本运行时,我的路径是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表或staging表永久表的查询。等

这样,这样就可以为您匹配限制表中的任何单词提供匹配:

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(字数统计/排名分配)来做类似的事情,但是我找不到它。如今,我将使用带数字表,XML / JSON功能或全文搜索功能的SQL Server来执行此类工作。

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

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