【问题标题】:Find and remove multiple instances of words occurring after ='s and before comma查找并删除出现在 = 之后和逗号之前的多个单词实例
【发布时间】:2016-01-14 16:21:12
【问题描述】:

我在电子表格的 N 列中有一个颜色列表,在每一行/单元格中,该列表看起来类似于:

中蓝色=蓝色,浅蓝色=蓝色,中绿色=绿色,中橙色=橙色,中橙色=焦橙色,中灰色=不锈钢,深红色=焦橙色

我正在尝试查看每个单元格,找到 = 的所有实例并比较 = 之后的字符串直到下一个逗号(例如:它会查看“= ESP”)以查看该值是否在同一个单元格中多次出现(如果相同的值在不同的单元格中也没关系)。如果该值在同一个单元格中出现多次,我需要删除 = 之后的字符串并将其替换为 = 之前的字符串。完成所有这些之后,我还需要确保没有两个相似的值(“浅蓝色和中蓝色=浅蓝色”被认为是相同的)。所以,上面的字符串在正确的时候应该是这样的(留下尾随的逗号):

中蓝=蓝色,浅蓝=浅蓝,中绿=绿,中橙=橙,中橙=焦橙,中灰=不锈钢,深红=深红

 'This is to figure out how many times to loop through a cell (Number of occurances
 'of "=" in a given cell
 'LEN(N2)-LEN(SUBSTITUTE(N2,"=",""))
Dim endRange As Integer
Dim equalCount As Integer

endRange = ActiveSheet.Cells(Rows.Count, "N").End(xlUp).Row
'Loop through each row in the column
For N = 2 To endRange

'Skip over a row if there is nothing in the cell
If ActiveSheet.Range("N" & N).Value <> "" Then

    'Counts how many ='s there are in each cell
    equalCount = Len(ActiveSheet.Range("N" & N).Value) - Len(Application.WorksheetFunction.Substitute(ActiveSheet.Range("N" & N).Value, "=", ""))

    'Loops through a cell once for every ='s
    For c = 1 To equalCount
        Dim commaPos As Integer
        Dim equalPos As Integer

        'Find the next comma & that's immediately after the particular ='s
        commaPos = FindN(",", ActiveSheet.Range("N" & N).Value, (c))
        equalPos = FindN("=", ActiveSheet.Range("N" & N).Value, (c))

        'Search the cell to see how many instances of the value between the ='s and ,
        If (Application.WorksheetFunction.CountIf(InStr(ActiveSheet.Range("N" & N).Value, _
        Mid(Right(ActiveSheet.Range("N" & N).Value, commaPos), Left(ActiveSheet.Range("N" & N).Value, equalPos), _
        equalPos - commaPos)), ">1")) Then

        MsgBox ("Found a Duplicate!")
        End If

    Next c
End If

    Next N
    End Sub

我不断收到“运行时错误 '13':类型不匹配”错误。另外,我很确定如果这确实有效,它仍然不会捕获字符串末尾的值,因为在最后一个 = 之后没有另一个逗号可以找到。

编辑

我的功能

 Function FindN(sFindWhat As String, _
 sInputString As String, N As Integer) As Integer
 Dim J As Integer
 Application.Volatile
 FindN = 0
 For J = 1 To N
     FindN = InStr(FindN + 1, sInputString, sFindWhat)
     If FindN = 0 Then Exit For
 Next
 End Function

【问题讨论】:

  • 你在哪里得到错误,哪一行?
  • 'If (Application.WorksheetFunction.CountIf(InStr(ActiveSheet.Range("N" & N).Value, _ Mid(Right(ActiveSheet.Range("N" & N).Value, commaPos), Left(ActiveSheet.Range("N" & N).Value, equalPos), _ equalPos - commaPos)), ">1")) Then' 它似乎指向该行中的 CountIf

标签: vba excel


【解决方案1】:

这是使用Split()的另一种方法

编辑:添加了检测单个值与 = 分隔的对

Function FixItUp(v)
    Dim arr, e, b, a, rv, sep, arrV
    Dim ex As String

    arr = Split(v, ",")
    'loop over each pair of values
    For Each e In arr
        arrV = Split(e, "=")
        b = Trim(arrV(0))

        If UBound(arrV)>0 Then
            'is a =-separated pair of values...
            a = Trim(arrV(1))
            'seen the "after" before?
            If InStr(ex, Chr(0) & a & Chr(0)) > 0 Then
                a = b 'seen already, assign "after" = "before"
            Else
                ex = ex & Chr(0) & a & Chr(0)
            End If
            rv = rv & sep & b & "=" & a
        Else
            'deal with the single "b" value here....
        End If

        sep = "," 'separator is now a comma...
    Next e

    FixItUp = rv
End Function

【讨论】:

  • 这就像一个魅力。你是最棒的!我不敢相信我花了这么多时间思考如此复杂的方法。我现在感觉自己像个新手。谢谢!
  • 其实只有一个问题。它似乎给出了“#VALUE!”查看长度超过 160 个字符的字符串时出错。知道为什么吗?
  • 尝试从 Sub 而不是从工作簿单元格调用它 - 这应该会突出问题
  • 我试着像这样从 sub 调用它:Dim endRange As Integer endRange = ActiveSheet.Cells(Rows.Count, "N").End(xlUp).Row For cCell = 2 To 3 If ActiveSheet.Range("N" & cCell).Value "" Then ActiveSheet.Range("N" & cCell).Value = FixItUp(ActiveSheet.Range("N" & cCell).Value) End If Next cCell
  • 当我运行它时,我得到一个运行时错误 9 下标超出范围,它似乎指向函数中的这一行:a = Trim(Split(e, "=")(1)) .这是我试图运行它的文本,如果有区别的话:透明,中灰色=灰色,浅灰色=灰色,其他=ESP,中黄色=黄色镜头,其他=ESP,其他=ESP,中橙色=黄色镜头
【解决方案2】:

感谢@Tim Williams 的所有努力和帮助,我已经能够在他给我的基础上构建并最终构建了一个适合我需要的函数。我会在这里发布以防其他人需要它

Function CleanColor(v)
Dim arr, e, b, a, rv, sep, arrV
Dim ex As String

arr = Split(v, ",")
'loop over each pair of values
For Each e In arr
    'Split up values further by using equals as delimiter
    arrV = Split(e, "=")
    'Trimming space off alias if there is a space and setting alias to b
    b = Trim(arrV(0))
    'Looking at array bounds and if there more than 1 slot (slot 0) then we have an =-separated pair
    If UBound(arrV) > 0 Then
        'is a =-separated pair of values...
        a = Trim(arrV(1))
        'count how many times the "after" appears in the entire v string
        Dim count As Integer
        count = (Len(v) - Len(WorksheetFunction.Substitute(v, Chr(61) & a, ""))) / Len(Chr(61) & a)
        'seen the "after" before?
        If InStr(ex, Chr(0) & a & Chr(0)) > 0 Or count > 1 Then
            If b <> "Other" Then
                a = b 'seen already, assign "after" = "before"
            Else
                GoTo endFor
            End If
        Else
            ex = ex & Chr(0) & a & Chr(0)
        End If
        rv = rv & sep & b & "=" & a
    Else
        'deal with the single "b" value here....
        a = e
        'seen the single value before?
        If InStr(ex, Chr(0) & a & Chr(0)) > 0 Then
            ex = ex 'seen already, don't add to string
        Else
            ex = ex & Chr(0) & a & Chr(0)
            rv = rv & sep & b
        End If
        'rv = rv & sep & b

    End If

    sep = "," 'separator is now a comma...
endFor: Next e

CleanColor = rv
End Function

再次感谢蒂姆·威廉姆斯的所有帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-10
    • 2020-05-04
    • 1970-01-01
    • 1970-01-01
    • 2013-06-01
    • 1970-01-01
    相关资源
    最近更新 更多