简体   繁体   English

VBA Excel 根据最后一个逗号分割字符串

[英]VBA Excel split the string apart based on the last comma

I would like to split my string in Excel between the address and postcode.我想在地址和邮政编码之间拆分 Excel 中的字符串。 I want to keep the postcode separately.我想单独保留邮政编码。

By selecting the option - Data -Text to column - delimited - comma-separated - the whole string is divided by 4 pieces, as 3 commas occur.通过选择选项 - 数据 - 文本到列 - 分隔 - 逗号分隔 - 整个字符串除以 4 部分,因为出现 3 个逗号。

1 - 21 Willow Court, 1192 Christchurch Road, Bournemouth, BH7 6EG 1 - 21 Willow Court, 1192 Christchurch Road, 伯恩茅斯, BH7 6EG

I found, that it can be done in VBA Excel.我发现,它可以在 VBA Excel 中完成。

There are a few approaches below:下面有几种方法:

Excel VBA- remove part of the string Excel VBA-删除部分字符串

https://www.thespreadsheetguru.com/the-code-vault/2014/2/28/remove-last-character-from-string https://www.thespreadsheetguru.com/the-code-vault/2014/2/28/remove-last-character-from-string

How to delete last character in a string with VBA? 如何使用 VBA 删除字符串中的最后一个字符?

Removing last characters vba 删除最后一个字符 vba

How to i remove a text after '*' or '-' character using VBA in excel? 如何在 excel 中使用 VBA 删除“*”或“-”字符后的文本?

I prepared the VBA code like below:我准备了 VBA 代码,如下所示:

   Sub Textremove()
   Dim c As Variant
   For Each c In Range("D1:D100")
   c.Value = Left(c.Value, InStr(c.Value, ",") - 1)
   Next c
   End Sub

I am receiving only:我只收到:

1 - 21 Willow Court 1 - 21 柳苑

and the error Invalid procedure call or argument, debugging the following line:和错误无效的过程调用或参数,调试以下行:

     c.Value = Left(c.Value, InStr(c.Value, ",") - 1)

So the breakdown occurs after the first comma instead of the last one.因此,故障发生在第一个逗号而不是最后一个逗号之后。

I found an answer regarding this error:我找到了有关此错误的答案:

invalid procedure call or argument left 留下无效的过程调用或参数

And when my code looks like this:当我的代码看起来像这样时:

  Sub Textremove()
  Dim c As Variant
  For Each c In Range("D1:D100")
  If InStr(c.Value, ",") > 0 Then
  c.Value = Left(c.Value, InStr(c.Value, ",") - 1)
  End If
  Next c
  End Sub

Then error doesn't occur anymore, but I am still getting the stuff until the first comma instead of the last one.然后错误不再发生,但我仍然得到这些东西,直到第一个逗号而不是最后一个逗号。

When I change the code a bit:当我稍微更改代码时:

 Sub Textremove()
 Dim c As Variant
 For Each c In Range("D1:D100")
 If InStr(c.Value, ",") > 0 Then
 c.Value = Right(c.Value, InStr(c.Value, ","))
 End If
 Next c
 End Sub

I am getting 2 sentences from the right我从右边得到 2 个句子

Bournemouth, BH7 6EG伯恩茅斯,BH7 6EG

which are not fixed and change depending on the total length of the string.它们不是固定的,会根据字符串的总长度而变化。

How can I receive the string till the last comma instead of the first one?我怎样才能接收到最后一个逗号而不是第一个逗号的字符串? How can I split the whole string between the address and postcode separately?如何分别拆分地址和邮政编码之间的整个字符串?

A good example is here:一个很好的例子在这里:

https://trumpexcel.com/vba-split-function/ https://trumpexcel.com/vba-split-function/

  Sub CommaSeparator()
  Dim TextStrng As String
  Dim Result() As String
  Dim DisplayText As String
  Dim i As Long
  TextStrng = Sheets("Final").Range("D1")
  Result = Split(TextStrng, ",", 1)
  For i = LBound(Result()) To UBound(Result())
  DisplayText = DisplayText & Result(i) & vbNewLine
  Next i
  MsgBox DisplayText
  End Sub

It admittedly splits the whole address, but it is counted still from the first comma.诚然,它拆分了整个地址,但仍从第一个逗号开始计算。

In my case that works.就我而言,这是可行的。 I just added the UBound(Result())-1.我刚刚添加了 UBound(Result())-1。

Sub CommaSeparator()
  Dim TextStrng As String
  Dim Result() As String
  Dim DisplayText As String
  Dim i As Long
  TextStrng = Sheets("Final").Range("D1")
  Result = Split(TextStrng, ",")
  For i = LBound(Result()) To UBound(Result()) - 1
  DisplayText = DisplayText & Result(i) & vbNewLine
  Next i
  MsgBox DisplayText
End Sub

In case you need VBA, maybe use:如果您需要 VBA,可以使用:

Sub Test()

Dim str As String
Dim arr As Variant

str = "1 - 21 Willow Court, 1192 Christchurch Road, Bournemouth, BH7 6EG"
arr = Split(StrReverse(Replace(StrReverse(str), ",", "|", , 1)), "|")
    
End Sub

I reversed the whole string through StrReverse() , then used Replace() to replace only the 1st comma with a pipe-symbol (note the use of the Count parameter), reversed the string back and used a Split() .我通过StrReverse()反转了整个字符串,然后使用Replace()仅用管道符号替换第一个逗号(注意使用Count参数),将字符串反转并使用Split() This returns:这将返回:


An alternative would be to make use of the worksheetfunction REPLACE() instead of the VBA function which inconveniently is called the same.另一种方法是使用工作表函数REPLACE()而不是 VBA function 不方便地称为相同。

Sub Test()

Dim str As String: str = "1 - 21 Willow Court, 1192 Christchurch Road, Bournemouth, BH7 6EG"
Dim arr As Variant

arr = Split(Application.Replace(str, InStrRev(str, ","), 1, "|"), "|")

End Sub

The main difference is now that Application.Replace does take a parameter to start the replacement at without cutting of the preceding text.现在的主要区别在于Application.Replace确实需要一个参数来开始替换,而无需剪切前面的文本。 We can find our starting position using InstrRev() .我们可以使用InstrRev()找到我们的起始 position 。


Both options return:两个选项都返回:

在此处输入图像描述


Just for fun I'll chuck in an regex solution:只是为了好玩,我会加入一个正则表达式解决方案:

Sub Test()

Dim str As String: str = "1 - 21 Willow Court, 1192 Christchurch Road, Bournemouth, BH7 6EG"
Dim arr As Variant

With CreateObject("vbscript.regexp")
    .Global = True
    .Pattern = "^.*(?=,)|[^,]+$"
    Set arr = .Execute(str)
End With

End Sub

This will return a "MatchCollectionObject" where you can call your results through: arr(0) and arr(1) .这将返回一个“MatchCollectionObject”,您可以在其中通过以下方式调用您的结果: arr(0)arr(1) A little bit of explaination of the pattern:对模式的一点解释:

  • ^ - Start string anchor. ^ - 开始字符串锚。
  • .* - A greedy match of anything other than newline up to: .* - 除了换行符之外的任何内容的贪婪匹配:
  • (?=,) - Positive lookahead for a comma. (?=,) - 逗号的正向前瞻。
  • | - Or match: - 或匹配:
  • [^,]$ - Anything other than comma up to the end string anchor. [^,]$ - 除了逗号之外的任何内容,直到结束字符串锚点。

See the online demo查看在线演示

在此处输入图像描述

Use the array returned by Split to rebuild the string however you like it eg:使用Split返回的数组来重建你喜欢的字符串,例如:

Sub DoSplit()

s = "1 - 21 Willow Court, 1192 Christchurch Road, Bournemouth, BH7 6EG"
a = Split(s, ",")
finalString = a(0) & a(1) & a(2) & ", " & a(3)
MsgBox finalString

End Sub

I have sorted this in a different, 2-steps way.我以不同的两步方式对此进行了排序。

First of all, I split a whole address, by using the formula from here:首先,我使用此处的公式拆分了整个地址:

Split address field in Excel Excel中的拆分地址字段

Sub Split()
  Dim MyArray() As String
  Dim Ws As Worksheet
  Dim lRow As Long, i As Long, j As Long, c As Long

  '~~> Change this to the relevant sheet name
  Set Ws = ThisWorkbook.Sheets("Final")

  With Ws
    lRow = .Range("E" & .Rows.Count).End(xlUp).Row

    For i = 1 To lRow
        If InStr(1, .Range("E" & i).Value, ",", vbTextCompare) Then
            MyArray = Split(.Range("E" & i).Value, ",")
            c = 1
            For j = 0 To UBound(MyArray)
                .Cells(i, c).Value = MyArray(j)
                c = c + 1
            Next j
        End If
      Next i
   End With
 End Sub

and next, I merged what I needed by using this hint:接下来,我使用这个提示合并了我需要的东西:

Excel macro to concatenate one row at a time to end of file Excel 宏一次将一行连接到文件末尾

Sub Merge()
Dim LastRow As Long
Dim Ws As Worksheet

Set Ws = Sheets("Final")

LastRow = Ws.Range("A" & Ws.Rows.Count).End(xlUp).Row

'~~> If your range doesn't have a header
Ws.Range("H1:H" & LastRow).Formula = "=A1&B1&C1"

'~~> If it does then
Ws.Range("H2:H" & LastRow).Formula = "=A2&B2&C2"
End Sub

and finally, I received:最后,我收到了:

1 - 10 Haviland Court 104 Haviland Road Bournemouth 1 - 10 Haviland Court 104 Haviland Road 伯恩茅斯

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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