简体   繁体   English

使用不同数量的分隔符解析 MSAccess VBA 中的字符串

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM