A function like this cannot change formatting.
It could be done with a macro. This prompts the user to select two cells or two ranges that are the same size.
Code:[COLOR=darkblue]Sub[/COLOR] CHARDIFS() [COLOR=darkblue]Dim[/COLOR] rngA [COLOR=darkblue]As[/COLOR] Range, rngB [COLOR=darkblue]As[/COLOR] Range [COLOR=darkblue]Dim[/COLOR] strA [COLOR=darkblue]As[/COLOR] [COLOR=darkblue]String[/COLOR], strB [COLOR=darkblue]As[/COLOR] [COLOR=darkblue]String[/COLOR] [COLOR=darkblue]Dim[/COLOR] i [COLOR=darkblue]As[/COLOR] [COLOR=darkblue]Long[/COLOR], r [COLOR=darkblue]As[/COLOR] [COLOR=darkblue]Long[/COLOR], c [COLOR=darkblue]As[/COLOR] Long [COLOR=darkblue]On[/COLOR] [COLOR=darkblue]Error[/COLOR] [COLOR=darkblue]Resume[/COLOR] [COLOR=darkblue]Next[/COLOR] [COLOR=darkblue]Set[/COLOR] rngA = Application.InputBox("Select the 1st cell(s) to compare to.", "Select Range A", Type:=8) [COLOR=darkblue]If[/COLOR] rngA [COLOR=darkblue]Is[/COLOR] [COLOR=darkblue]Nothing[/COLOR] [COLOR=darkblue]Then[/COLOR] [COLOR=darkblue]Exit[/COLOR] [COLOR=darkblue]Sub[/COLOR] [COLOR=darkblue]Do[/COLOR] [COLOR=darkblue]Set[/COLOR] rngB = Application.InputBox("Select the 2nd cell(s) to compare.", "Select Range B", Type:=8) [COLOR=darkblue]If[/COLOR] rngB [COLOR=darkblue]Is[/COLOR] [COLOR=darkblue]Nothing[/COLOR] [COLOR=darkblue]Then[/COLOR] [COLOR=darkblue]Exit[/COLOR] [COLOR=darkblue]Sub[/COLOR] [COLOR=darkblue]If[/COLOR] rngA.Columns.Count = rngB.Columns.Count And rngA.Rows.Count = rngB.Rows.Count [COLOR=darkblue]Then[/COLOR] [COLOR=darkblue]Exit[/COLOR] [COLOR=darkblue]Do[/COLOR] MsgBox "Range B muct have the same number of rows and columns as Range A.", vbExclamation, "Different Size Ranges" [COLOR=darkblue]Set[/COLOR] rngB = [COLOR=darkblue]Nothing[/COLOR] [COLOR=darkblue]Loop[/COLOR] [COLOR=darkblue]On[/COLOR] [COLOR=darkblue]Error[/COLOR] [COLOR=darkblue]Resume[/COLOR] [COLOR=darkblue]Next[/COLOR] [COLOR=darkblue]For[/COLOR] c = 1 [COLOR=darkblue]To[/COLOR] rngA.Columns.Count [COLOR=darkblue]For[/COLOR] r = 1 [COLOR=darkblue]To[/COLOR] rngA.Rows.Count strA = rngA(r, c).Value strB = rngB(r, c).Value [COLOR=darkblue]For[/COLOR] i = 1 [COLOR=darkblue]To[/COLOR] Len(strB) [COLOR=darkblue]If[/COLOR] i > Len(strA) [COLOR=darkblue]Or[/COLOR] UCase(Mid(strA, i, 1)) <> UCase(Mid(strB, i, 1)) [COLOR=darkblue]Then[/COLOR] rngB(r, c).Characters(Start:=i, Length:=1).Font.ColorIndex = 3 [COLOR=darkblue]End[/COLOR] [COLOR=darkblue]If[/COLOR] [COLOR=darkblue]Next[/COLOR] i, r, c [COLOR=darkblue]End[/COLOR] [COLOR=darkblue]Sub[/COLOR]
Hello,
I have been using the Sub CHARDIFS to great happiness. Thank you AlphaFrog for your help. I'm using them to compare DNA sequences and it works like a charm. Now however, I'm comparing such long strings (about 150 characters) that it's hard to see the differences. Would it be possible to change the Sub to output:
A1: AGCTAG
B1: AGTTAG
New B1: ..T...
Thank you very much in advance!
[COLOR=darkblue]Sub[/COLOR] CHARDIFS()
[COLOR=darkblue]Dim[/COLOR] rngA [COLOR=darkblue]As[/COLOR] Range, rngB [COLOR=darkblue]As[/COLOR] Range
[COLOR=darkblue]Dim[/COLOR] strA [COLOR=darkblue]As[/COLOR] [COLOR=darkblue]String[/COLOR], strB [COLOR=darkblue]As[/COLOR] [COLOR=darkblue]String[/COLOR]
[COLOR=darkblue]Dim[/COLOR] i [COLOR=darkblue]As[/COLOR] [COLOR=darkblue]Long[/COLOR], r [COLOR=darkblue]As[/COLOR] [COLOR=darkblue]Long[/COLOR], c [COLOR=darkblue]As[/COLOR] Long
[COLOR=darkblue]On[/COLOR] [COLOR=darkblue]Error[/COLOR] [COLOR=darkblue]Resume[/COLOR] [COLOR=darkblue]Next[/COLOR]
[COLOR=darkblue]Set[/COLOR] rngA = Application.InputBox("Select the 1st cell(s) to compare to.", "Select Range A", Type:=8)
[COLOR=darkblue]If[/COLOR] rngA [COLOR=darkblue]Is[/COLOR] [COLOR=darkblue]Nothing[/COLOR] [COLOR=darkblue]Then[/COLOR] [COLOR=darkblue]Exit[/COLOR] [COLOR=darkblue]Sub[/COLOR]
[COLOR=darkblue]Do[/COLOR]
[COLOR=darkblue]Set[/COLOR] rngB = Application.InputBox("Select the 2nd cell(s) to compare.", "Select Range B", Type:=8)
[COLOR=darkblue]If[/COLOR] rngB [COLOR=darkblue]Is[/COLOR] [COLOR=darkblue]Nothing[/COLOR] [COLOR=darkblue]Then[/COLOR] [COLOR=darkblue]Exit[/COLOR] [COLOR=darkblue]Sub[/COLOR]
[COLOR=darkblue]If[/COLOR] rngA.Columns.Count = rngB.Columns.Count And rngA.Rows.Count = rngB.Rows.Count [COLOR=darkblue]Then[/COLOR] [COLOR=darkblue]Exit[/COLOR] [COLOR=darkblue]Do[/COLOR]
MsgBox "Range B muct have the same number of rows and columns as Range A.", vbExclamation, "Different Size Ranges"
[COLOR=darkblue]Set[/COLOR] rngB = [COLOR=darkblue]Nothing[/COLOR]
[COLOR=darkblue]Loop[/COLOR]
[COLOR=darkblue]On[/COLOR] [COLOR=darkblue]Error[/COLOR] [COLOR=darkblue]Resume[/COLOR] [COLOR=darkblue]Next[/COLOR]
[COLOR=darkblue]For[/COLOR] c = 1 [COLOR=darkblue]To[/COLOR] rngA.Columns.Count
[COLOR=darkblue]For[/COLOR] r = 1 [COLOR=darkblue]To[/COLOR] rngA.Rows.Count
strA = rngA(r, c).Value
strB = rngB(r, c).Value
[COLOR=darkblue]For[/COLOR] i = 1 [COLOR=darkblue]To[/COLOR] Len(strB)
[COLOR=darkblue]If[/COLOR] i > Len(strA) [COLOR=darkblue]Or[/COLOR] UCase(Mid(strA, i, 1)) <> UCase(Mid(strB, i, 1)) [COLOR=darkblue]Then[/COLOR]
[COLOR=green]'rngB(r, c).Characters(Start:=i, Length:=1).Font.ColorIndex = 3[/COLOR]
[COLOR=darkblue]Else[/COLOR]
rngB(r, c).Characters(Start:=i, Length:=1).Text = "."
[COLOR=darkblue]End[/COLOR] [COLOR=darkblue]If[/COLOR]
[COLOR=darkblue]Next[/COLOR] i, r, c
[COLOR=darkblue]End[/COLOR] [COLOR=darkblue]Sub[/COLOR]
Hi Psynomi. You're welcome and thanks for the feedback.
Try this...
Code:[COLOR=darkblue]Sub[/COLOR] CHARDIFS() [COLOR=darkblue]Dim[/COLOR] rngA [COLOR=darkblue]As[/COLOR] Range, rngB [COLOR=darkblue]As[/COLOR] Range [COLOR=darkblue]Dim[/COLOR] strA [COLOR=darkblue]As[/COLOR] [COLOR=darkblue]String[/COLOR], strB [COLOR=darkblue]As[/COLOR] [COLOR=darkblue]String[/COLOR] [COLOR=darkblue]Dim[/COLOR] i [COLOR=darkblue]As[/COLOR] [COLOR=darkblue]Long[/COLOR], r [COLOR=darkblue]As[/COLOR] [COLOR=darkblue]Long[/COLOR], c [COLOR=darkblue]As[/COLOR] Long [COLOR=darkblue]On[/COLOR] [COLOR=darkblue]Error[/COLOR] [COLOR=darkblue]Resume[/COLOR] [COLOR=darkblue]Next[/COLOR] [COLOR=darkblue]Set[/COLOR] rngA = Application.InputBox("Select the 1st cell(s) to compare to.", "Select Range A", Type:=8) [COLOR=darkblue]If[/COLOR] rngA [COLOR=darkblue]Is[/COLOR] [COLOR=darkblue]Nothing[/COLOR] [COLOR=darkblue]Then[/COLOR] [COLOR=darkblue]Exit[/COLOR] [COLOR=darkblue]Sub[/COLOR] [COLOR=darkblue]Do[/COLOR] [COLOR=darkblue]Set[/COLOR] rngB = Application.InputBox("Select the 2nd cell(s) to compare.", "Select Range B", Type:=8) [COLOR=darkblue]If[/COLOR] rngB [COLOR=darkblue]Is[/COLOR] [COLOR=darkblue]Nothing[/COLOR] [COLOR=darkblue]Then[/COLOR] [COLOR=darkblue]Exit[/COLOR] [COLOR=darkblue]Sub[/COLOR] [COLOR=darkblue]If[/COLOR] rngA.Columns.Count = rngB.Columns.Count And rngA.Rows.Count = rngB.Rows.Count [COLOR=darkblue]Then[/COLOR] [COLOR=darkblue]Exit[/COLOR] [COLOR=darkblue]Do[/COLOR] MsgBox "Range B muct have the same number of rows and columns as Range A.", vbExclamation, "Different Size Ranges" [COLOR=darkblue]Set[/COLOR] rngB = [COLOR=darkblue]Nothing[/COLOR] [COLOR=darkblue]Loop[/COLOR] [COLOR=darkblue]On[/COLOR] [COLOR=darkblue]Error[/COLOR] [COLOR=darkblue]Resume[/COLOR] [COLOR=darkblue]Next[/COLOR] [COLOR=darkblue]For[/COLOR] c = 1 [COLOR=darkblue]To[/COLOR] rngA.Columns.Count [COLOR=darkblue]For[/COLOR] r = 1 [COLOR=darkblue]To[/COLOR] rngA.Rows.Count strA = rngA(r, c).Value strB = rngB(r, c).Value [COLOR=darkblue]For[/COLOR] i = 1 [COLOR=darkblue]To[/COLOR] Len(strB) [COLOR=darkblue]If[/COLOR] i > Len(strA) [COLOR=darkblue]Or[/COLOR] UCase(Mid(strA, i, 1)) <> UCase(Mid(strB, i, 1)) [COLOR=darkblue]Then[/COLOR] [COLOR=green]'rngB(r, c).Characters(Start:=i, Length:=1).Font.ColorIndex = 3[/COLOR] [COLOR=darkblue]Else[/COLOR] rngB(r, c).Characters(Start:=i, Length:=1).Text = "." [COLOR=darkblue]End[/COLOR] [COLOR=darkblue]If[/COLOR] [COLOR=darkblue]Next[/COLOR] i, r, c [COLOR=darkblue]End[/COLOR] [COLOR=darkblue]Sub[/COLOR]
The WORDDIF function compares words and not individual characters. It returned ABC in your example because it evaluates ABC as a word that doesn't exist in the sentence ABCDEF.
This CHARDIF function does a case insensitive 1-to-1 character comparison.
Code:[COLOR=darkblue]Function[/COLOR] CHARDIF(rngA [COLOR=darkblue]As[/COLOR] Range, rngB [COLOR=darkblue]As[/COLOR] Range) [COLOR=darkblue]As[/COLOR] [COLOR=darkblue]String[/COLOR] [COLOR=darkblue]Dim[/COLOR] strA [COLOR=darkblue]As[/COLOR] [COLOR=darkblue]String[/COLOR], strB [COLOR=darkblue]As[/COLOR] [COLOR=darkblue]String[/COLOR] [COLOR=darkblue]Dim[/COLOR] i [COLOR=darkblue]As[/COLOR] [COLOR=darkblue]Long[/COLOR], strTemp As [COLOR=darkblue]String[/COLOR] strA = rngA.Value strB = rngB.Value [COLOR=darkblue]If[/COLOR] Len(strA) > Len(strB) [COLOR=darkblue]Then[/COLOR] strTemp = strA strA = strB strB = strTemp strTemp = "" [COLOR=darkblue]End[/COLOR] [COLOR=darkblue]If[/COLOR] [COLOR=darkblue]For[/COLOR] i = 1 [COLOR=darkblue]To[/COLOR] Len(strB) [COLOR=darkblue]If[/COLOR] i > Len(strA) [COLOR=darkblue]Then[/COLOR] strTemp = strTemp & Mid(strB, i, 1) [COLOR=darkblue]ElseIf[/COLOR] UCase(Mid(strA, i, 1)) <> UCase(Mid(strB, i, 1)) [COLOR=darkblue]Then[/COLOR] strTemp = strTemp & Mid(strB, i, 1) [COLOR=darkblue]End[/COLOR] [COLOR=darkblue]If[/COLOR] [COLOR=darkblue]Next[/COLOR] i CHARDIF = strTemp [COLOR=darkblue]End[/COLOR] [COLOR=darkblue]Function[/COLOR]
This function is great. We work with a lot of URLs in my business and it's auto comparing differences at scale. This works pretty well for spotting differences at the end of a URL do you think it could spot differences in the middle of a URL?
Hi and welcome to the forum. I don't follow what you are describing. Perhaps you could elaborate with examples.
[COLOR=darkblue]Function[/COLOR] URLDIF(rngA [COLOR=darkblue]As[/COLOR] Range, rngB [COLOR=darkblue]As[/COLOR] Range) [COLOR=darkblue]As[/COLOR] [COLOR=darkblue]String[/COLOR]
[COLOR=darkblue]Dim[/COLOR] WordsA [COLOR=darkblue]As[/COLOR] [COLOR=darkblue]Variant[/COLOR], WordsB [COLOR=darkblue]As[/COLOR] [COLOR=darkblue]Variant[/COLOR]
[COLOR=darkblue]Dim[/COLOR] ndxA [COLOR=darkblue]As[/COLOR] [COLOR=darkblue]Long[/COLOR], bJoin [COLOR=darkblue]As[/COLOR] [COLOR=darkblue]Boolean[/COLOR], strTemp As [COLOR=darkblue]String[/COLOR]
WordsA = Split(rngA.Text, "/")
WordsB = Split(rngB.Text, "/")
[COLOR=darkblue]For[/COLOR] ndxA = [COLOR=darkblue]LBound[/COLOR](WordsA) [COLOR=darkblue]To[/COLOR] [COLOR=darkblue]UBound[/COLOR](WordsA)
[COLOR=darkblue]If[/COLOR] [COLOR=darkblue]UBound[/COLOR](WordsB) < ndxA [COLOR=darkblue]Then[/COLOR] [COLOR=darkblue]Exit[/COLOR] [COLOR=darkblue]For[/COLOR]
[COLOR=darkblue]If[/COLOR] [COLOR=darkblue]StrComp[/COLOR](WordsA(ndxA), WordsB(ndxA), vbTextCompare) = 0 [COLOR=darkblue]Then[/COLOR]
WordsA(ndxA) = vbNullString
[COLOR=darkblue]Else[/COLOR]
bJoin = [COLOR=darkblue]True[/COLOR]
[COLOR=darkblue]End[/COLOR] [COLOR=darkblue]If[/COLOR]
[COLOR=darkblue]Next[/COLOR] ndxA
[COLOR=darkblue]If[/COLOR] bJoin [COLOR=darkblue]Then[/COLOR] URLDIF = Join(WordsA, "/")
[COLOR=darkblue]End[/COLOR] [COLOR=darkblue]Function[/COLOR]