• Hi All

    Please note that at the Chandoo.org Forums there is Zero Tolerance to Spam

    Post Spam and you Will Be Deleted as a User

    Hui...

  • When starting a new post, to receive a quicker and more targeted answer, Please include a sample file in the initial post.

Identifying the Unique values in Rows

Rajesh S

Member
Dear Team,

Please refer the attached sample file. Need the result as given in the Column P.

Tried multiple ways but could not succeed. Can anyone help me with this formula?

Thanks

Regards

S Rajesh
 

Attachments

  • Test file.xlsx
    9.7 KB · Views: 15
Hi Marc,
Advanced filter cannot be used here as I have 1.5 L records where this exercise to be performed.

Regards

S Rajesh
 
Rajesh,
Attached sheet has formula in cell (Q:X)which will extract unique values.
Concatenation in P col is not done yet, need change. as i am leaving now i can check tonight or tomrrow.
as you are saying entries are more than 1 lac and formula is Array, it will consume considerable amount of time to execute.
PS: Formula taken from other site. Not mine.
 

Attachments

  • Test file (2).xlsx
    11.8 KB · Views: 8
Thanks Ashhu. This should help. Will apply this formula across & revert if need be.. Thanks for your immediate response.
 
Hi !​
Hi Marc,
Advanced filter cannot be used here as I have 1.5 L records where this exercise to be performed.
When I saw your attachment, I knew it wasn't possible with a filter …
I deleted my post 'cause I thought you hadn't time to read it …

I can provide you a personal function via VBA but called in a cell formula
or just a VBA procedure called by a button or manually
(both no need some helper column) …
 
Hi:

There are lot of ready made functions available on web, here is one from @jindon

Code:
Function ConcatUniq(ByRef rng As Range, _
    ByVal myJoin As String, Optional ord As Boolean = True) As String
    Dim r As Range
    With CreateObject("System.Collections.ArrayList")
        For Each r In rng
            If Not .Contains(CStr(r.Value)) Then .Add CStr(r.Value)
        Next
        .Sort
        If Not ord Then .Reverse
        ConcatUniq = Join$(.ToArray, myJoin)
    End With
End Function
http://www.ozgrid.com/forum/showthread.php?t=160873&page=2
Thanks
 
It requires some modification to satisfy op's requirement.
Code:
Function ConcatUniq(ByRef rng As Range, _
    ByVal myJoin As String, Optional ord As Boolean = True) As String
    Dim r As Range
    With CreateObject("System.Collections.ArrayList")
        For Each r In rng
            If (r<>"") * (r<>0) * (Not .Contains(CStr(r.Value))) Then .Add CStr(r.Value)
        Next
        .Sort
        If Not ord Then .Reverse
        ConcatUniq = Join$(.ToArray, myJoin)
    End With
End Function

However, for this case, the following would be better...
=ConcatUniq(C3:O3,", ")
Code:
Function ConcatUniq(ByVal rng As Range, ByVal myJoin As String) As String
    Dim r As Range
    With CreateObject("Scripting.Dictionary")
        .CompareMode = 1
        For Each r In rng
            If (r <> "") * (r <> 0) * (Not .exists(r.Value)) Then .Item(r.Value) = Empty
        Next
        ConcatUniq = Join(.keys, myJoin)
    End With
End Function
 
Just to clean the line.
Code:
Function ConcatUniq(ByVal rng As Range, ByVal myJoin AsString) As String
   Dim r As Range
   With CreateObject("Scripting.Dictionary")
        .CompareMode = 1
       For Each r In rng
           If (r <> "") * (r <> 0)  Then .Item(r.Value) = Empty
       Next
        ConcatUniq = Join(.keys, myJoin)
   End With
End Function
 
Rajesh, to test a personal function you must first create in VBE
a standard module then paste to it function code …

Formula to enter in P3 cell : =RowUnique(C3:O3)
Copy down …

As they are very few cells by row, with only Excel basics
no external Windows object so works too on MAC :​
Code:
Function RowUnique$(Rg As Range)
        VA = Filter(Evaluate(Replace("IF(#<>0,#)", "#", Rg.Rows(1).Address)), False, False)
        If UBound(VA) < 0 Then Exit Function
        S$ = VA(0)
        VA = Filter(VA, VA(0), False)
    Do Until UBound(VA) < 0
         S = S & ", " & VA(0)
        VA = Filter(VA, VA(0), False)
    Loop
         RowUnique = S
End Function

Or​
Code:
Function RowUnique$(Rg As Range)
        VA = Filter(Evaluate(Replace("IF(#<>0,#)", "#", Rg.Rows(1).Address)), False, False)
        If UBound(VA) < 0 Then Exit Function
        ReDim RU$(1 To UBound(VA) + 1)
    For Each V In VA
        If IsError(Application.Match(V, RU, 0)) Then N% = N% + 1: RU(N) = V
    Next
         ReDim Preserve RU(1 To N)
         RowUnique = Join(RU, ", ")
End Function
Do you like it ? So thanks to click on bottom right Like !
 
Fast & able to complete the 1.5L lines in 2 mins.
Without a function but with a global procedure using jindon's way
(Dictionary object) and an array variable may be the fastest …

Try this third function using an inner Collection (like a Dictionary) :​
Code:
Function RowUnique$(Rg As Range)
         Dim oRow As New Collection, N%, S$, V, VA
         VA = Filter(Evaluate(Replace("IF(#<>0,#)", "#", Rg.Rows(1).Address)), False, False)
         If UBound(VA) < 0 Then Exit Function
         On Error Resume Next
         For Each V In VA:  oRow.Add V, V:  Next
         On Error GoTo 0
         S = oRow(1)
         For N = 2 To oRow.Count:  S = S & ", " & oRow(N):  Next
         RowUnique = S
End Function
You may Like it …
 
If Evaluate method, one line should be enough...
Code:
Function ConcatUniq(ByVal rng As Range, ByVal myJoin As String) As String
    ConcatUniq = Join(Filter(rng.Parent.Evaluate("if((" & rng.Address & "<>0)*(countif(offset(" & rng.Address & ",,,,column(" & _
    [a1].Resize(, rng.Columns.Count).Address & "))," & rng.Address & ")=1)," & rng.Address & ",char(2))"), Chr(2), 0), myJoin)
End Function
 

Attachments

  • Test file with code.xlsm
    18.3 KB · Views: 6
Back
Top