【问题标题】:Splitting string twice拆分字符串两次
【发布时间】:2019-01-09 02:07:47
【问题描述】:

我正在尝试将 400 多行包含字母和数字的字符串分成不同的列。原始字符串如下所示:

Chicago today 1.01 1.33 1.90
Dallas today 1.76
San Antonio today 3.43 4.67 8.99 2.34 9.65 10.13

理想情况下,我的最终代码将在 A 列中生成城市名称,并将每个后续浮动在不同列中,如下所示:

 A            B    C   D    E    F    G
Chicago     1.01 1.33 1.90
Dallas      1.76
San Antonio 3.43 4.67 8.99 2.34 9.65 10.13

我使用“今天”这个词作为分隔符,因为它对最终产品一点也不重要,而且我能够将城市名称与数字分开,但所有数字现在都存在于 B 列中,而不是跨列分布。我尝试使用两个分隔符:“today”和“”,但是两个单词的城市名称也被拆分了。

Sub SplitName ( )

Dim Cpty  As String
Dim i As Integer
Dim Rate As Variant

Cpty = ActiveCell.Value

Rate = Split (City, “today”)

For i = 0 To UBound(Rate)
    Cels(1, i+1).Value = Rate (i)


Next i


End Sub

感谢任何帮助,谢谢!

【问题讨论】:

  • 拆分两次:第一次在“today”上拆分得到一个包含2个元素的字符串,第二次在“”上拆分
  • 试试TextToColumns。那要快得多。发布示例代码
  • 请注意,您发布的代码在“today” 中使用了这些花哨的引号“ ”,但VBA 只允许使用简单的" ",您必须替换它们。
  • 答案很多,你好像也太懒了。

标签: excel vba split


【解决方案1】:

我也可以玩吗? :)

我觉得这可能是最快的方式?

逻辑

  1. 在第 1 列中,将“今天”替换为“|”
  2. 使用“|”在 Col 1 上的列中添加文本作为分隔符
  3. 在第 2 列中,将“”替换为“|”
  4. 文本到列 2 上的“|”列作为分隔符

代码

Sub Sample()
    Dim ws As Worksheet

    Set ws = Sheet1

    With ws
        .Columns(1).Replace What:=" today ", Replacement:="|", LookAt:=xlPart, _
        SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False

        .Columns(1).TextToColumns Destination:=.Range("A1"), DataType:=xlDelimited, _
        TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
        Semicolon:=False, Comma:=False, Space:=False, Other:=True, OtherChar _
        :="|", FieldInfo:=Array(Array(1, 1), Array(2, 1)), TrailingMinusNumbers:=True

        .Columns(2).Replace What:=" ", Replacement:="|", LookAt:=xlPart, _
        SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
        ReplaceFormat:=False

        .Columns(2).TextToColumns Destination:=.Range("B1"), DataType:=xlDelimited, _
        TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
        Semicolon:=False, Comma:=False, Space:=False, Other:=True, OtherChar _
        :="|", FieldInfo:=Array(Array(1, 1), Array(2, 1), Array(3, 1), Array(4, 1), Array(5, _
        1), Array(6, 1), Array(7, 1)), TrailingMinusNumbers:=True
    End With
End Sub

截图

【讨论】:

  • 您好,感谢您的回答。只有一个问题:如果我有 n 个费率怎么办?我相信您的代码适用于 6 个速率(3.43、4.67、8.99、2.34、9.65、10.13),但是如果我有 n,那么我必须创建一个循环才能达到第 n 个值?
  • 技术上是的,但奇怪的是,用Array(Array(1, 1)) 替换Array(Array(1, 1), Array(2, 1), Array(3, 1), Array(4, 1), Array(5, _ 1), Array(6, 1), Array(7, 1)) 也可以:) 试一试,让我知道它是否适合您?否则我会给你一个稍微修改的代码。
【解决方案2】:

下面怎么样

例子

Option Explicit
Sub SplitName()
    Dim City As String
        City = ActiveCell.Value

    Dim Rate() As String
        Rate() = Split(City)

    Dim i As Long
    For i = LBound(Rate) To UBound(Rate)
      Debug.Print Rate(i) ' Print to Immediate window
      Cells(1, i + 1).Value = Rate(i)
    Next i

End Sub

【讨论】:

    【解决方案3】:

    在“今天”上拆分,然后在空间上拆分第二个(从零开始的一维数组中的 1),并确保您检索的是双精度而不是仅看起来像双精度的文本。

    Chicago today 1.01 1.33 1.90
    Dallas today 1.76
    San Antonio today 3.43 4.67 8.99 2.34 9.65 10.13
    
    for i=1 to lastrow
        arr1 = split(rasnge("A" & i), " today ")
        arr2 = split(arr1(1), " ")
        for j = lbound(arr2) to ubound(arr2)
            debug.print cdbl(arr2(j))
        next j
    next i
    

    【讨论】:

      【解决方案4】:

      双分割

      将一列范围内的单元格值拆分两次,并将结果复制到计算的列数。

      快速版本

      Sub SplitName()
      
          ' Source
          Const cSheet1 As Variant = "Sheet1"   ' Source Sheet Name/Index
          Const cCol As Variant = "A"           ' Source Column Letter/Number
          Const cFirst As Integer = 1           ' Source First Row
          Const cSplit1 As String = "today"     ' First Split String
          Const cSplit2 As String = " "         ' Second Split String
          ' Target
          Const cSheet2 As Variant = "Sheet1"   ' Target Sheet Name/Index
          Const cFirstCell As String = "B1"     ' Target Range First Cell
      
          Dim vntS As Variant   ' Source Array
          Dim vnt1 As Variant   ' First Split Array
          Dim vnt2 As Variant   ' Second Split Array
          Dim vntT As Variant   ' Target Array
          Dim lastR As Long     ' Source Last Row
          Dim i As Long         ' Arrays Row Counter
          Dim j As Integer      ' Target Array Column Counter
      
          ' Paste Source Range into Source Array.
          With Worksheets(cSheet1)
              lastR = .Cells(.Rows.Count, cCol).End(xlUp).Row
              vntS = .Range(.Cells(cFirst, cCol), .Cells(lastR, cCol))
          End With
      
          ' Calculate number of columns in Target Array.
          For i = 1 To UBound(vntS)
              vnt1 = Split(vntS(i, 1), cSplit1)
              vnt2 = Split(Trim(vnt1(1)), cSplit2)
              If j < UBound(vnt2) Then
                  j = UBound(vnt2)
              End If
          Next
          ' Increase the number by one because the first column will be the first
          ' string from First Split Array, and by another one because the
          ' Split Arrays are 0-based.
          j = j + 2
      
          ' Write Source Array to Target Array.
          ReDim vntT(1 To UBound(vntS), 1 To j)
          For i = 1 To UBound(vntS)
              vnt1 = Split(vntS(i, 1), cSplit1)
              vnt2 = Split(Trim(vnt1(1)), cSplit2)
              vntT(i, 1) = Trim(vnt1(0))
              For j = 0 To UBound(vnt2)
                  vntT(i, j + 2) = vnt2(j)
              Next
          Next
      
          ' Paste Target Array into Target Range calculated from Target First Cell.
          With Worksheets(cSheet2).Range(cFirstCell)
              .Resize(UBound(vntT), UBound(vntT, 2)) = vntT
          End With
      
      End Sub
      

      只是给定代码的更新

      Sub SplitName()
      
          Dim Cpty  As String
          Dim i As Integer
          Dim Rate As Variant
          Dim Rate2 As Variant
      
          Cpty = ActiveCell.Value
      
          Rate = Split(Cpty, "today")
          Rate2 = Split(Trim(Rate(1))) ' ***
      
          ' Write City
          Cells(1, 2).Value = Trim(Rate(0))
      
          ' Write Numbers
          For i = 0 To UBound(Rate2)
              Cells(1, i + 3).Value = Rate2(i)
          Next i
      
      End Sub
      

      *** 第二个拆分分隔符已被省略,因为默认为 " "。

      【讨论】:

        【解决方案5】:

        还有时间玩吗?

        第一步:在字符串中定位今天

        第二步:用特殊的(未使用的)分隔符替换所有不可告人的空间

        第三步:在那个特殊的分隔符上分割

        Function SplitCities(ByVal sRow As String) As String()
            Dim today_place As Long
            'Step 1: Look for "today"
            today_place = InStr(sRow, "today")
            'Step 2: Replace the space after today by "|".
            'Since Replace truncate the start of the string, I concatenate it using Left.
            'Here I have removed "today" from the result, but you can use change the values to keep it (use -1 and 0 as offsets)
            sRow = Left$(sRow, today_place - 2) & Replace(sRow, " ", "|", today_place + 5), "|"
            'Step 3: Split the result
            SplitCities = Split(sRow, "|")
        End Function
        

        在您的代码中使用 SplitCities 而不是 Split。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-04-14
          • 2022-01-25
          • 1970-01-01
          • 2014-01-16
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多