我在一个字段上使用正则表达式函数运行查询,其中一行可能包含一个或多个匹配但我无法获取Access以返回任何匹配,除了集合中的第一个或最后一个(显示为随机的)我)。
示例数据:
tbl_1 (queried table)
row_1 abc1234567890 some text
row_2 abc1234567890 abc3459998887 some text
row_3 abc9991234567 abc8883456789 abc7778888664 some text
tbl_2 (currently returned results)
row_1 abc1234567890
row_2 abc1234567890
row_3 abc7778888664
tbl_2 (ideal returned results)
row_1 abc1234567890
row_2 abc1234567890
row_3 abc3459998887
row_4 abc9991234567
row_5 abc8883456789
row_6 abc7778888664
这是我的Access VBA代码:
Public Function OrderMatch(field As String)
Dim regx As New RegExp
Dim foundMatches As MatchCollection
Dim foundMatch As match
regx.IgnoreCase = True
regx.Global = True
regx.Multiline = True
regx.Pattern = "\b[A-Za-z]{2,3}\d{10,12}\b"
Set foundMatches = regx.Execute(field)
If regx.Test(field) Then
For Each foundMatch In foundMatches
OrderMatch = foundMatch.Value
Next
End If
End Function
我的SQL代码:
SELECT OrderMatch([tbl_1]![Field1]) AS Order INTO tbl_2
FROM tbl_1
WHERE OrderMatch([tbl_1]![Field1])<>False;
我不确定我的正则表达式模式是否错误,我的VBA代码错误,或者我的SQL代码错误。
答案 0 :(得分:1)
似乎您打算从tbl_1
中的字段中拆分多个文本匹配项,并将每个匹配项存储为tbl_2
中的单独行。使用Access查询执行此操作并不容易。请考虑使用VBA过程。在Access 2007中使用示例数据,此过程将您在tbl_2
(在名为Order
的文本字段中)中要求的内容存储起来。
Public Sub ParseAndStoreOrders()
Dim rsSrc As DAO.Recordset
Dim rsDst As DAO.Recordset
Dim db As DAO.database
Dim regx As Object ' RegExp
Dim foundMatches As Object ' MatchCollection
Dim foundMatch As Object ' Match
Set regx = CreateObject("VBScript.RegExp")
regx.IgnoreCase = True
regx.Global = True
regx.Multiline = True
regx.pattern = "\b[a-z]{2,3}\d{10,12}\b"
Set db = CurrentDb
Set rsSrc = db.OpenRecordset("tbl_1", dbOpenSnapshot)
Set rsDst = db.OpenRecordset("tbl_2", dbOpenTable, dbAppendOnly)
With rsSrc
Do While Not .EOF
If regx.Test(!field1) Then
Set foundMatches = regx.Execute(!field1)
For Each foundMatch In foundMatches
rsDst.AddNew
rsDst!Order = foundMatch.value
rsDst.Update
Next
End If
.MoveNext
Loop
.Close
End With
Set rsSrc = Nothing
rsDst.Close
Set rsDst = Nothing
Set db = Nothing
Set foundMatch = Nothing
Set foundMatches = Nothing
Set regx = Nothing
End Sub
将代码粘贴到标准代码模块中。然后将光标定位在过程体内并按 F5 运行它。
答案 1 :(得分:0)
此函数仅返回一个值,因为这是您使用逻辑设置它的方式。这将始终返回 last 匹配值。
For Each foundMatch In foundMatches
OrderMatch = foundMatch.Value
Next
即使您的函数隐式返回Variant
数据类型,它也不会返回数组,因为您没有为数组赋值。假设有2个以上的匹配,循环中的赋值语句OrderMatch = foundMatch.Value
将覆盖第二个匹配,第二个匹配第三个匹配等。
假设您要返回一组匹配值:
Dim matchVals() as Variant
Dim m as Long
For Each foundMatch In foundMatches
matchValues(m) = foundMatch.Value
m = m + 1
ReDim Preserve matchValues(m)
Next
OrderMatch = matchValues
答案 2 :(得分:0)
此循环
For Each foundMatch In foundMatches
OrderMatch = foundMatch.Value
Next
依次将所有结果分配给同一个变量OrderMatch
,它总是替换OrderMatch
的旧值。因此,该函数将始终返回最后一个匹配。
如果要返回所有值,请返回一个数组
Public Function OrderMatch(field As String) As String()
Dim results() As String
Dim i As Long
... get matches
ReDim results(0 To foundMatches.Count - 1) As String
If regx.test(field) Then
For i = 0 To foundMatches.Count - 1
results(i) = foundMatches(i).Value
Next
End If
OrderMatch = results
End Function
(我目前正在使用Access XP,因此我不知道索引是从1到Count还是从0到Count-1。)
<强>更新强>
始终指定函数的返回类型。这对于想要使用该功能的人(包括您,如果您必须在6个月内重新使用此功能)提供更多信息,并防止出现编码错误。如果真的是Variant
,请指定... As Variant
,以便明确您的意图。