0
votes

I have a list of colors in column N of my spreadsheet and in each row/cell the list looks something along the lines of:

Medium Blue=Blue,Light Blue=Blue,Medium Green=Green,Medium Orange=Orange,Medium Orange=Burnt Orange,Medium Gray=Stainless,Dark Red=Burnt Orange

I'm trying to look through each cell, find all instances of ='s and compare the string after ='s until the next comma (ex: it would look at "=ESP,") to see if this value occurs multiple times throughout the same cell (it's ok if the same values are in different cells). If the value occurs multiple times within the same cell I need to remove the string after the ='s and replace it with what's before the ='s. After all that is done, I also need to make sure that there are no two like values ("Light Blue & Medium Blue=Light Blue" are considered the same). So, the above String should look like this when correct (Leaving the trailing comma):

Medium Blue=Blue,Light Blue=Light Blue,Medium Green=Green,Medium Orange=Orange,Medium Orange=Burnt Orange,Medium Gray=Stainless,Dark Red=Dark Red

 '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

I keep getting a "Run-time error '13': Type mismatch" Error. Also, I'm pretty sure if this did work it still wouldn't catch values at the end of the string since there is not another comma to find after the last ='s.

edit

My function

 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
2
Where do you get the error, what line?BruceWayne
'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' It seems to point towards the CountIf in that lineCaffeinatedMike

2 Answers

2
votes

Here's a different approach using Split()

EDIT: added detecting single values vs =-separated pairs

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
0
votes

Thanks to all of the effort and help from @Tim Williams I've been able to build off of what he gave me and finally constructed a function that suits my needs. I'll post this here in case someone else needs it

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

Thank you again Tim Williams for all your help!