【问题标题】:splits cells after capital combination资本组合后分裂细胞
【发布时间】:2014-12-08 11:41:30
【问题描述】:

我有一个包含 200 行的文件,其值如下: ANTWERPEN 3 ABDIJ Abdijstraat 71-73 2020 9:00 18:00 9:00 18:00 9:00 18:00 9:00 18:00 9:00 19:00 9:00 19:00 我想将其拆分为单独的列。

  1. 我想为完全在大写字母中的部分设置 1 列。在这种特定情况下,这将是: ANTWERPEN 3 ABDIJ

  2. 后面的部分是另一列,直到 4 个数字字符。在这种情况下:Abdijstraat 71-73

我很高兴行值有这种区别来分隔地址,但我不知道如何做到这一点。

在第一个数字字符处拆分单元格时,我也遇到过类似的情况:

text to columns: split at the first number in the value

但现在我正在寻找一种双重解决方案,在第一列中包含 完全在大写字母中的第一部分,它代表城市,在第二列中我需要以大写字母开头但后跟非大写字符并在 4 个数字字符字符串之前结束的字符串

如果我能创建一个 vba 或 excel 代码/公式来为我做这件事,我会很高兴,但不幸的是,我做不到 :-(

所以我希望有人可以。

编辑

找到一些其他例程并对其进行修改和测试,帮助我创建了这个:

Sub doitall()
   Dim cell As Range, j As Integer, i As Integer, x As String
   Dim str As String
   Dim strlen As Integer
   Dim k As Integer
   Dim l As Integer
   Dim y As Integer
'   Dim v As Integer
'
'
'   For j = 1 To Cells(Rows.Count, 1).End(xlUp).Row
'      For Each cell In ActiveSheet.Range(Cells(1, 1), Cells(j, 1))
'         For i = 1 To Len(cell)
'         x = Mid(cell, i, 1)
'         If x = ":" Then Exit For
'      Next i
'      cell.Offset(0, 1) = Left(cell, i - 8)
'      Next cell
'   Next j

'geparkeerd
'            If l >= 65 And l <= 90 Then
'        If v > 1 Then
'        m = v - 1
'        l = Asc(Mid(Cells(j, 2), m, 1))
'        Else
'        l = 0
'        End If


For j = 1 To Cells(Rows.Count, 2).End(xlUp).Row
    For Each cell In ActiveSheet.Range(Cells(1, 2), Cells(j, 2))
        For v = 1 To Len(cell)
            k = Asc(Mid(cell, v, 1))
            If k >= 97 And k <= 122 Then
                If v < 1 Then
                Exit For
                Else: m = v - 1
                End If
                    l = Asc(Mid(cell, m, 1))
                    If l >= 65 And l <= 90 Then
                    y = Len(cell) - (v - 1)
                    cell.Offset(0, 1) = Mid(cell, m, y + 1)
                Else
                End If
            End If
        Next v
    Next cell
Next j

End Sub

第一部分在单元格值中找到“:”,并使用“:”左侧的所有字符减去8作为其旁边列中单元格的单元格值。

第二部分必须使用这个“新”值来区分城市名称和街道名称。幸运的是,街道名称总是以大写字母开头,后跟非大写字母。 幸运的是,城市名称完全是大写字母,这样更容易根据大写字母和非大写字母来分割价值。

我现在专注于第二部分。

第二部分所做的是检查每个单元格和单元格中的每个位置(如果它是非大写的)。如果是,则检查之前的头寸是否为资本。如果是,则必须使用大写字母中的所有字符作为下一列单元格中的新值。

这行得通。 但不是这个值: BELLE- ILE "Belle-Ile" Shop 22 -Quai des Vennes 1 该值的结果仅为Vennes 1

但是为什么呢? v 从 1 循环到单元格的长度。但从 1 开始,因此位置 1 位于单元格值的左侧。从这个例程中,结果实际上应该是Belle-Ile" Shop 22 -Quai des Vennes 1

有人对此有解释吗? 我现在将手动调整它,但我只是想知道它为什么返回这个值。

解决方案: v 必须从 len(cell) to 1 step -1 检查。在我改变它之后,它几乎可以完美地工作。 但我还是不明白为什么。我的阅读方式是 v 从最后一个位置开始测试,朝着单元格值的第一个位置工作。像这样,在我看来,我相信这个例程是行不通的。但不知何故它确实如此。关键是要理解为什么v 必须是len(cell) to 1 step -1 而不是1 to len(cell)

我希望有人能给我解释一下。

(我也将在我必须了解它之后尝试正则表达式解决方案)。

【问题讨论】:

    标签: string excel split


    【解决方案1】:

    我是正则表达式的新手,但以下内容适用于上面给出的输入行。毫无疑问,存在更优雅的解决方案,但这可能会让您朝着正确的方向前进。我发现在构建正则表达式模式时有用的 StackOverflow 链接:

    How to match "anything up until this sequence of characters" in a regular expression?

    Regex to match mixed case words

    Regex to match only uppercase "words" with some exceptions

    How to use Regular Expressions (Regex) in Microsoft Excel both in-cell and loops

    Function Part1(Myrange As Range) As String
    
        Dim regEx As New RegExp
        Dim strPattern As String
        Dim strInput As String
    
        strPattern = ".+?(?=[A-Z][a-z]+)"
    
        If strPattern <> "" Then
            strInput = Myrange.Value
    
            With regEx
                .Global = True
                .MultiLine = True
                .IgnoreCase = False
                .Pattern = strPattern
            End With
    
            If regEx.test(strInput) Then
                Set matches = regEx.Execute(strInput)
                For Each Match In matches
                    Part1 = Part1 & Match.Value
                Next
            Else
                Part1 = "Not matched"
            End If
        End If
    
    End Function
    
    Function Part2(Myrange As Range) As String
    
        Dim regEx As New RegExp
        Dim strPattern As String
        Dim strInput As String
        Dim strReplace As String
    
        strPattern = ".+?(?=[A-Z][a-z]+)"
    
        If strPattern <> "" Then
            strInput = Myrange.Value
            strReplace = ""
    
            With regEx
                .Global = True
                .MultiLine = True
                .IgnoreCase = False
                .Pattern = strPattern
            End With
    
            If regEx.test(strInput) Then
                Part2 = regEx.Replace(strInput, strReplace)
                regEx.Pattern = ".+?(?=[0-9]{4})"
                Set matches = regEx.Execute(Part2)
                For Each Match In matches
                    Part2 = Match.Value
                Next
            Else
                Part2 = "Not matched"
            End If
        End If
    
    End Function
    

    【讨论】:

    • 谢谢。我将阅读正则表达式是什么。并尝试您的解决方案。
    【解决方案2】:

    这就是我所拥有的,并且满足了我的“需要”:

    Sub doitall()
       Dim cell As Range, j As Integer, i As Integer, x As String
       Dim str As String
       Dim strlen As Integer
       Dim k As Integer
       Dim l As Integer
       Dim y As Integer
       Dim v As Integer
    
       For j = 1 To Cells(Rows.Count, 1).End(xlUp).Row
          For Each cell In ActiveSheet.Range(Cells(1, 1), Cells(j, 1))
             For i = 1 To Len(cell)
             x = Mid(cell, i, 1)
             If x = ":" Then Exit For
          Next i
          cell.Offset(0, 1) = Left(cell, i - 8)
          Next cell
       Next j
    
    For j = 1 To Cells(Rows.Count, 2).End(xlUp).Row
        For Each cell In ActiveSheet.Range(Cells(1, 2), Cells(j, 2))
            For v = Len(cell) To 1 Step -1
                k = Asc(Mid(cell, v, 1))
                If k >= 97 And k <= 122 Then
                    If v < 1 Then
                    Exit For
                    Else: m = v - 1
                    End If
                        l = Asc(Mid(cell, m, 1))
                        If l >= 65 And l <= 90 Then
                        y = Len(cell) - (v - 1)
                        cell.Offset(0, 1) = Mid(cell, m, y + 1)
                        cell.Offset(0, 2) = Left(cell, (m - 1))
                    Else
                    End If
                End If
            Next v
        Next cell
    Next j
    
    End Sub
    

    它几乎可以完美运行。除了在字符串中包含此例程未涵盖的某些其他字符的某些单元格。 但我相信也可以添加(检查操作空格、双引号等)

    【讨论】:

      猜你喜欢
      • 2015-05-15
      • 1970-01-01
      • 1970-01-01
      • 2017-08-30
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 2022-06-23
      • 1970-01-01
      相关资源
      最近更新 更多