【问题标题】:Excel VBA split after second spaceExcel VBA 在第二个空格后拆分
【发布时间】:2021-08-20 06:08:15
【问题描述】:

我正在尝试拆分我的列,以便名称

詹姆斯·约翰·多伊

只出来

詹姆斯·约翰

使用下面的公式,但它只留下名字,我希望它在第二次出现“空格”时拆分。

Sub Split1()
Dim r As Range

For Each r In Range("A2:A" & Cells(Rows.count, "A").End(xlUp).Row).Cells.SpecialCells(xlCellTypeConstants)
    r.Value = Split(r.Value, " ")(0)
    
Next r

谁能帮帮我?

谢谢

【问题讨论】:

    标签: excel vba split


    【解决方案1】:

    您可以尝试使用left & find 来获取字符串值直到第二个空格,而不是split 函数

    代码修改:

    Dim r As Range
    Dim s As String, newText As String
    Dim Length As Long
    
    For Each r In Range("A2:A" & Cells(Rows.Count, "A").End(xlUp).Row).Cells.SpecialCells(xlCellTypeConstants)
        s = r.Value
        Length = Application.WorksheetFunction.Find(" ", s, Application.WorksheetFunction.Find(" ", s) + 1)
        
        r.Value = Left(s, Length)
    Next r
    

    样本输出:

    【讨论】:

    • 这非常有效,非常感谢 Kin!
    • 欢迎,类似excel功能:)
    • VBA 有自己的功能,例如要获取第二次出现空格之前的字符数,请使用 Length = InStr(InStr(1, s, " ") + 1, s, " ")(类似于您的解决方案)或获取最后一次出现空格之前的字符数,请使用 Length = InStrRev(s, " ") - 1)
    • @VBasic2008,我从来不知道instr 像find 一样工作,反正我对excel 中的find 函数很满意,两者都可以互换使用
    【解决方案2】:

    有几种方法可以将三个单词的短语变成前两个单词。

    让我们从您的Split() 方法开始。 该函数返回一个数组。您尝试访问索引的特定方法只会返回一个单词。

    你可以放入一个数组,然后组合数组元素:

    For Each r In Range(...)
    
        Dim retVal() As String
        retVal = Split(r.Value)
        r.Value = retVal(0) & " " & retVal(1)
    
    Next r
    

    您可以使用Replace() 删除最后一个单词:

    For Each r In Range(...)
    
        r.Value = Replace(r.Value, Split(r.Value)(2), "")
    
    Next
    

    或者你甚至可以使用正则表达式:

    With CreateObject("VBScript.RegExp")
    
        .Pattern = "\s[^\s]+$"
        For Each r in Range(...)
            r.Value = .Replace(r.Value, "")
        Next
        
    End With
    

    在正则表达式中,\s 表示单个空格字符,[^...] 括号表示“不包括”,我们在括号内放置了一个\s,这样可以匹配任何 非空格字符,后跟+表示1次或多次,最后$表示字符串结束。本质上,您想要匹配位于字符串$ 末尾的单词[^\s]+,前面有一个空格\s,并通过.Replace() 方法将其删除。实际上,您也可以简单地使用模式\s\S+$,它本质上是相同的(\S 表示任何大写的非空格字符)。

    【讨论】:

    • 感谢 K.David!我从中学到了很多东西,都尝试了它们,它们工作得很好。不过,我想知道,是否有办法在您的 retval 或模式方法中将最后一个单词也更改为单个字符?要将 James John Doe 更改为 James J?
    • 是的,您可以将行的最后一部分更改为Left(retVal(1), 1)
    • @KelvinC 如果您想使用模式方法,您可以将 .Pattern 行替换为:.Pattern = "^(\S+\s\w).*" 并将替换行替换为 r.Value = .Replace(r.Value, "$1")
    • 顺便说一句,如果您愿意,可以可视化并了解有关此正则表达式及其工作原理的更多信息,您可以单击此处:Your customized RegEx link by Regex101.com。本网站右侧有一个解释部分,您可以查看。
    • @K.Dᴀᴠɪs 喜欢你有用的概述 :+);仅供参考,发布了一种较晚的方法,只是为了丰富已发布和有效解决方案的选择。
    【解决方案3】:

    提取拆分数组的第一个和第三个标记的进一步方法

    这种方法得益于Application.Index 的高级可能性,允许指示任何新的行或列顺序;想要的列在此处由最后一个基于 1 的(列)参数 Array(1, 3) 反映:

    Function GetFirstLast(s As String) As String
        GetFirstLast = Join(Application.Index(Split(s), 0, Array(1, 3)))
    End Function
    
    

    调用示例:

    Debug.Print GetFirstLast("James John Doe")

    导致

    James Doe 在 VB 编辑器的即时窗口中。

    【讨论】:

    • 这个方法不错。没想到会用这个
    • 感谢您的反馈;事实上,Application.Index() 为 1-dim 和 2-dim 数组提供了一整套重组可能性(请参阅帖子列表some pecularities。请注意,Application.Index 返回基于 1 的数组(如果是 2-dim 数组,它会重新基于两个维度)。 @K.Dᴀᴠɪs
    猜你喜欢
    • 1970-01-01
    • 2018-03-13
    • 2021-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-12
    • 2016-03-26
    • 2012-01-08
    相关资源
    最近更新 更多