[英]Parsing a string in MSAccess VBA with varying numbers of delimiters
In MSAccess VBA, I'm trying to parse a name field into last, first, middle.在 MSAccess VBA 中,我试图将名称字段解析为最后、第一、中间。 The problem is that the incoming format is not consistent:
问题是传入的格式不一致:
Jones John Q
Doe Jane
Smith Robert X
This is what I'm doing这就是我正在做的
Dim rsNames As DAO.Recordset
Set rsNames = CurrentDb.OpenRecordset("SELECT * FROM tblInput")
If Not (rsNames.EOF And rsNames.BOF) Then
rsNames.MoveFirst
Do Until rsNames.EOF = True
strFullName = rsNames!Name
intLength = Len(strFullName)
intSpacePos = InStr(strFullName, " ")
strLname = Left(strFullName, intSpacePos - 1)
strFname = Mid(strFullName, intSpacePos, intLength - (intSpacePos - 1))
strFname = Trim(strFname)
If Len(strFname) + Len(strLname) + (intSpacePos - 1) < intLength Then
strMI = Right(strFullName, 1)
End If
rsNames.Edit
rsNames!LastName = strLname
rsNames!FirstName = strFname
rsNames!MiddleInitial = strMI
rsNames.Update
rsNames.MoveNext
Loop
Results结果
LastName: Jones
FirstName: John Q
Middle Initial: Q
LastName: Doe
FirstName: Jane
Middle Initial: E
If I change this line strFname = Mid(strFullName, intSpacePos, intLength - (intSpacePos - 1))
to strFname = Mid(strFullName, intSpacePos, intLength - (intSpacePos)
, the lines with middle initials parse correctly, but the lines without middle initials cut off the last character of the first name and move it to the middle initial field (Doe Jan E)
如果我将这一行
strFname = Mid(strFullName, intSpacePos, intLength - (intSpacePos - 1))
更改为strFname = Mid(strFullName, intSpacePos, intLength - (intSpacePos)
,则带有中间首字母的行解析正确,但没有中间首字母的行切断名字的最后一个字符并将其移动到中间的初始字段(Doe Jan E)
I've tried using split and replace but neither works properly because of the varying numbers of spaces separating the fields.我尝试过使用拆分和替换,但由于分隔字段的空格数量不同,它们都不能正常工作。 I'm wondering if my only option is to read the string character by character and building the individual fields that way, but before I go down that path, am I missing something obvious?
我想知道我唯一的选择是否是逐个字符地读取字符串并以这种方式构建各个字段,但是在我 go 沿着这条路走之前,我是否遗漏了一些明显的东西? I have no control over the incoming file.
我无法控制传入的文件。
I'll propose you to use split() function, in this manner:我建议您以这种方式使用 split() function:
Dim rsNames As DAO.Recordset
Dim strLname As String, strFname As String, strMI As String
Dim i As Integer
Dim x, arr As Variant
Set rsNames = CurrentDb.OpenRecordset("SELECT * FROM tblInput")
If Not (rsNames.EOF And rsNames.BOF) Then
'rsNames.MoveFirst
Do Until rsNames.EOF = True
arr = Split(rsNames!Name)
strLname = ""
strFname = ""
strMI = ""
i = 0
For Each x In arr
If (x <> "") Then
If (i = 0) Then
strLname = x
ElseIf (i = 1) Then
strFname = x
Else
strMI = x
End If
i = i + 1
End If
'
If (i > 2) Then
Exit For
End If
Next
'
rsNames.Edit
rsNames!LastName = strLname
rsNames!FirstName = strFname
rsNames!MiddleInitial = strMI
rsNames.Update
rsNames.MoveNext
Loop
End If
rsNames.Close
Set rsNames = Nothing
We use a loop to find non empty split strings as LastName, FirstName and Middle initial.我们使用循环来查找非空拆分字符串,例如姓氏、名字和中间名首字母。
This pure VBA code avoids us to use extra VBScript.RegExp
replacement.这个纯 VBA 代码避免我们使用额外的
VBScript.RegExp
替换。
I would lean towards using RegEx and Split:我倾向于使用 RegEx 和 Split:
Private Sub Test()
Dim strFullName As String
Dim NameParts As Variant
strFullName = "Jones John Q"
With CreateObject("vbscript.regexp")
.Pattern = "\s+"
.Global = True
strFullName = .Replace(strFullName, " ")
End With
NameParts = Split(strFullName, " ")
End Sub
NameParts is an array containing Last, First, and possibly Middle names. NameParts 是一个包含姓氏、名字和可能的中间名的数组。
Are First Name and Last Name always in the same position?名字和姓氏总是在同一个 position 中吗? If so, the use of split can be use to determine the existence of the middle, i may be missing something though, i'd go for
如果是这样,可以使用 split 来确定中间的存在,但我可能会遗漏一些东西,我会选择 go
Dim a() As String
a() = Split(s, Chr(32))
strLastName = a(0)
strFirstName = a(1)
If UBound(a) = 2 Then
strMiddle = a(2)
Else
strMiddle = ""
End If
Debug.Print strFirstName, strMiddle, strLastName
or something a bit less elegant或者不那么优雅的东西
If Len(s) - Len(Replace(s, Chr(32), "")) = 2 Then
strMiddle = Right(s, Len(s) - InStrRev(s, Chr(32)))
End If
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.