Finding unique values and inserting them in the first row for each user occurance

techie2013

New Member
Joined
Aug 8, 2013
Messages
34
I have a spread sheet with users' permissions and permission categories in two different columns. There are 200 permissions falling into 5 broad permission categories. Therefore, for each user my spread sheet currently looks like this:

User
Permission
Permission Category
User1
trade stocks
buy-sell
User1
import items
buy
User1
issue orders
sell
User2
distribute items
sell
User2
issue bills
sell
User3
order items
buy
User3
request delivery
buy

<TBODY>
</TBODY>

I would like to add a new column to the above spread sheet to list all unique values for each user in first row when user name occurs first. The resultant spread sheet should look like this:
User
Permission
Permission Category
Unique Permission
Categories
User1
trade stocks
buy-sell
buy-sell, buy,sell
User1
import items
buy
User1
issue orders
sell
User2
distribute items
sell
sell
User2
issue bills
sell
User3
order items
buy
buy
User3
request delivery
buy

<TBODY>
</TBODY>

This allows me to easily see what unique permissions each user has rather than get confused when I see their permission in earch row of the permissions column.

So basically, I need a formula or UDF that I would like to insert into the Unique-permission category column which will look at the user name and while the user name is the same it will look for all unique values in Permission Categories and list them in the last column (ignoring the duplicates).

Any help would be highly appreciated.

Thanks in advance.
 

Excel Facts

Copy PDF to Excel
Select data in PDF. Paste to Microsoft Word. Copy from Word and paste to Excel.
techie2013,

With you raw data already sorted/grouped per your screenshot.

Sample raw data:


Excel 2007
ABCD
1UserPermissionPermission Category
2User1trade stocksbuy-sell
3User1import itemsbuy
4User1issue orderssell
5User2distribute itemssell
6User2issue billssell
7User3order itemsbuy
8User3request deliverybuy
9
Sheet1


After the macro:


Excel 2007
ABCD
1UserPermissionPermission CategoryUnique Permission Categories
2User1trade stocksbuy-sellbuy-sell, buy, sell
3User1import itemsbuy
4User1issue orderssell
5User2distribute itemssellsell
6User2issue billssell
7User3order itemsbuybuy
8User3request deliverybuy
9
Sheet1


Please TEST this FIRST in a COPY of your workbook (always make a backup copy before trying new code, you never know what you might lose).

1. Copy the below code
2. Open your NEW workbook
3. Press the keys ALT + F11 to open the Visual Basic Editor
4. Press the keys ALT + I to activate the Insert menu
5. Press M to insert a Standard Module
6. Where the cursor is flashing, paste the code
7. Press the keys ALT + Q to exit the Editor, and return to Excel
8. To run the macro from Excel press ALT + F8 to display the Run Macro Dialog. Double Click the macro's name to Run it.

Code:
Option Explicit
Sub GetUniquePermissionCategories()
' hiker95, 01/03/2014
' http://www.mrexcel.com/forum/excel-questions/748181-finding-unique-values-inserting-them-first-row-each-user-occurance.html
Dim lr As Long, r As Long, n As Long, c As Range, rng As Range
Application.ScreenUpdating = False
Columns(4).ClearContents
Cells(1, 4) = "Unique Permission Categories"
lr = Cells(Rows.Count, 1).End(xlUp).Row
With CreateObject("Scripting.Dictionary")
  For r = 2 To lr
    n = Application.CountIf(Columns(1), Cells(r, 1).Value)
    If n = 1 Then
      Cells(r, 4) = Cells(r, 3)
    ElseIf n > 1 Then
      Set rng = Range("C" & r & ":C" & r + n - 1)
      For Each c In rng
        If c <> "" Then
          If Not .Exists(Trim(c.Value)) Then
            .Add c.Value, c.Value
          End If
        End If
      Next c
      Cells(r, 4) = Join(.Keys, ", ")
    End If
    r = r + n - 1
    .RemoveAll
  Next r
End With
Columns(4).AutoFit
Application.ScreenUpdating = True
End Sub

Before you use the macro with Excel 2007 or newer, save your workbook, Save As, a macro enabled workbook with the file extension .xlsm

Then run the GetUniquePermissionCategories macro.
 
Upvote 0
techie2013,

With you raw data already sorted/grouped per your screenshot.

Sample raw data:

Excel 2007
A
B
C
D
1
User
Permission
Permission Category
2
User1
trade stocks
buy-sell
3
User1
import items
buy
4
User1
issue orders
sell
5
User2
distribute items
sell
6
User2
issue bills
sell
7
User3
order items
buy
8
User3
request delivery
buy
9

<TBODY>
</TBODY>
Sheet1



After the macro:

Excel 2007
A
B
C
D
1
User
Permission
Permission Category
Unique Permission Categories
2
User1
trade stocks
buy-sell
buy-sell, buy, sell
3
User1
import items
buy
4
User1
issue orders
sell
5
User2
distribute items
sell
sell
6
User2
issue bills
sell
7
User3
order items
buy
buy
8
User3
request delivery
buy
9

<TBODY>
</TBODY>
Sheet1



Please TEST this FIRST in a COPY of your workbook (always make a backup copy before trying new code, you never know what you might lose).

1. Copy the below code
2. Open your NEW workbook
3. Press the keys ALT + F11 to open the Visual Basic Editor
4. Press the keys ALT + I to activate the Insert menu
5. Press M to insert a Standard Module
6. Where the cursor is flashing, paste the code
7. Press the keys ALT + Q to exit the Editor, and return to Excel
8. To run the macro from Excel press ALT + F8 to display the Run Macro Dialog. Double Click the macro's name to Run it.

Rich (BB code):
Option Explicit
Sub GetUniquePermissionCategories()
' hiker95, 01/03/2014
' http://www.mrexcel.com/forum/excel-questions/748181-finding-unique-values-inserting-them-first-row-each-user-occurance.html
Dim lr As Long, r As Long, n As Long, c As Range, rng As Range
Application.ScreenUpdating = False
Columns(4).ClearContents
Cells(1, 4) = "Unique Permission Categories"
lr = Cells(Rows.Count, 1).End(xlUp).Row
With CreateObject("Scripting.Dictionary")
  For r = 2 To lr
    n = Application.CountIf(Columns(1), Cells(r, 1).Value)
    If n = 1 Then
      Cells(r, 4) = Cells(r, 3)
    ElseIf n > 1 Then
      Set rng = Range("C" & r & ":C" & r + n - 1)
      For Each c In rng
        If c <> "" Then
          If Not .Exists(Trim(c.Value)) Then
            .Add c.Value, c.Value
          End If
        End If
      Next c
      Cells(r, 4) = Join(.Keys, ", ")
    End If
    r = r + n - 1
    .RemoveAll
  Next r
End With
Columns(4).AutoFit
Application.ScreenUpdating = True
End Sub

Before you use the macro with Excel 2007 or newer, save your workbook, Save As, a macro enabled workbook with the file extension .xlsm

Then run the GetUniquePermissionCategories macro.

Hi hiker95

Thank you so much for the macro. I think this would be a great solution to what I am trying to achieve. My actual spread sheet has more columns so I had to modify the macro as below:

Code:
Option Explicit
Sub GetUniqueTemplateAM()
' hiker95, 01/03/2014
' [URL]http://www.mrexcel.com/forum/excel-questions/748181-finding-unique-values-inserting-them-first-row-each-user-occurance.html[/URL]
Dim lr As Long, r As Long, n As Long, c As Range, rng As Range
Application.ScreenUpdating = False
Columns(9).ClearContents
Cells(1, 9) = "Unique Template AM"
lr = Cells(Rows.Count, 1).End(xlUp).Row
With CreateObject("Scripting.Dictionary")
  For r = 2 To lr
    n = Application.CountIf(Columns(1), Cells(r, 1).Value)
    If n = 1 Then
      Cells(r, 9) = Cells(r, 8)
    ElseIf n > 1 Then
      Set rng = Range("H" & r & ":H" & r + n - 1)
      For Each c In rng
        If c <> "" Then
          If Not .Exists(Trim(c.Value)) Then
            .Add c.Value, c.Value
          End If
        End If
      Next c
      Cells(r, 9) = Join(.Keys, ", ")
    End If
    r = r + n - 1
    .RemoveAll
  Next r
End With
Columns(9).AutoFit
Application.ScreenUpdating = True
End Sub

I am getting an Run-time error '13': Type mismatch. The macro inserts the correct value for User1 only. From the next user the 'Unique Template AM' column remains blank. Can you please tell me what modification I need to make for it to work correctly.

Once again, thank you for so meticulously explain each step. It is very helpful.

Regards,
techie2013
 
Upvote 0
techie2013,

Please do not quote entire replies from your helper. When quoting follow these guidelines:

1. Quote ONLY if it is needed to add clarity or context for your reply. If so, then
2. Quote ONLY the specific part of the post that is relevant - - not the entire post.

This will keep thread clutter to a minimum and make the discussion easier to follow.

My actual spread sheet has more columns so I had to modify the macro

It is always best to start with your actual raw data. This way a solution can usually be found on the first go.

In order to continue, I will have to have screenshots of your actual dataset, before and after.
 
Upvote 0
I got it. I agree that a clear post will benefit more people as it would be easier to review. Will keep that in mind in the future.

I am including links to the before and after Excel file screen shots of my actual worksheet. I would appreciate it if you can help with modifying the macro as needed.
After
Before

Thanks for your help so far.
Have a nice day!
Techie2013
 
Upvote 0
techie2013,

You are posting two pictures/graphics. This means that if this was a problem where one needed to use your data, anyone trying to help you would have to enter the data manually. That makes no sense.


Can you give us the same type screenshots as in your reply #1?
 
Upvote 0
You could use this UDF, with a formula like
=IF(MATCH(A3, A:A, 0) = ROW(A3),ConcatIf(A:A, A3, C:C,", ",TRUE), "")
Code:
Function ConcatIf(ByVal compareRange As Range, ByVal xCriteria As Variant, Optional ByVal stringsRange As Range, _
                    Optional Delimiter As String, Optional NoDuplicates As Boolean) As String
                    
    Rem the first three argumens of ConcatIf mirror those of SUMIF
    Rem the Delimiter and NoDuplicates arguments are optional (default "" and False)
    Dim i As Long, j As Long
    
    With compareRange.Parent
        Set compareRange = Application.Intersect(compareRange, Range(.UsedRange, .Range("a1")))
    End With
    
    If compareRange Is Nothing Then Exit Function
    If stringsRange Is Nothing Then Set stringsRange = compareRange
    Set stringsRange = compareRange.Offset(stringsRange.Row - compareRange.Row, _
                                            stringsRange.Column - compareRange.Column)
    
    For i = 1 To compareRange.Rows.Count
        For j = 1 To compareRange.Columns.Count
            If (Application.CountIf(compareRange.Cells(i, j), xCriteria) = 1) Then
                If InStr(Delimiter & ConcatIf & Delimiter, Delimiter & CStr(stringsRange.Cells(i, j))) <> 0 Imp Not (NoDuplicates) Then
                    ConcatIf = ConcatIf & Delimiter & CStr(stringsRange.Cells(i, j))
                End If
            End If
        Next j
    Next i
    ConcatIf = Mid(ConcatIf, Len(Delimiter) + 1)
End Function
 
Upvote 0
I understand. I thought the fix would take just some change in column names in the macro you already provided. Of course to test the functionality you do need the data in spread sheet format. Here you go...

Before:
UserID
GroupID
UserName
Topic
SubTopic
FunctionID
TemplateAM
rgr1
NULL
Roger
Performance
Shift from door
TMPAM03
rgr1
NULL
Roger
Pepetation
Repeat steps
TMPAM03
jst1
GroupB
Justin
Collection
Collect Coupons
TMPAM02
jst1
GroupB
Justin
Statistics
Data Analysis
TMPAM04

<TBODY>
</TBODY>
After:
UserID</SPAN>GroupID</SPAN>UserName</SPAN>Topic</SPAN>SubTopic</SPAN>FunctionID</SPAN>TemplateAM</SPAN>Unique Template AM</SPAN>
rgr1</SPAN>NULL</SPAN>Roger</SPAN>Performance</SPAN> Shift from door</SPAN>TMPAM03</SPAN>TMPAM03</SPAN>
rgr1</SPAN>NULL</SPAN>Roger</SPAN>Pepetation</SPAN> Repeat steps</SPAN>TMPAM03</SPAN>
jst1</SPAN>GroupB</SPAN>Justin</SPAN>Collection</SPAN> Collect Coupons</SPAN>TMPAM02</SPAN>TMPAM02,TMPAM04</SPAN>
jst1</SPAN>GroupB</SPAN>Justin</SPAN>Statistics</SPAN> Data Analysis</SPAN>TMPAM04</SPAN>



<TBODY>
</TBODY><COLGROUP><COL><COL><COL><COL><COL><COL><COL><COL><COL></COLGROUP>
 
Upvote 0
Oops! Made a mistake. A whole column is missing in the above examples. Also added column names like A, B, C etc..

Before:</SPAN>
A</SPAN>B</SPAN>C</SPAN>D</SPAN>E</SPAN>F</SPAN>G</SPAN>H</SPAN>
UserID</SPAN>GroupID</SPAN>UserName</SPAN>Topic</SPAN>SubTopic</SPAN>Function</SPAN>FunctionID</SPAN>TemplateAM</SPAN>
rgr1</SPAN>NULL</SPAN>Roger</SPAN>Performance</SPAN> Shift from door</SPAN>ShiftDoor</SPAN>TMPAM03</SPAN>
rgr1</SPAN>NULL</SPAN>Roger</SPAN>Pepetation</SPAN> Repeat steps</SPAN>Repeator</SPAN>TMPAM03</SPAN>
jst1</SPAN>GroupB</SPAN>Justin</SPAN>Collection</SPAN> Collect Coupons</SPAN>Collector</SPAN>TMPAM02</SPAN>
jst1</SPAN>GroupB</SPAN>Justin</SPAN>Statistics</SPAN> Data Analysis</SPAN>Statician</SPAN>TMPAM04</SPAN>
After:</SPAN>
A</SPAN>B</SPAN>C</SPAN>D</SPAN>E</SPAN>F</SPAN>G</SPAN>H</SPAN>I</SPAN>
UserID</SPAN>GroupID</SPAN>UserName</SPAN>Topic</SPAN>SubTopic</SPAN>Function</SPAN>FunctionID</SPAN>TemplateAM</SPAN>Unique Template AM</SPAN>
rgr1</SPAN>NULL</SPAN>Roger</SPAN>Performance</SPAN> Shift from door</SPAN>ShiftDoor</SPAN>TMPAM03</SPAN>TMPAM03</SPAN>
rgr1</SPAN>NULL</SPAN>Roger</SPAN>Pepetation</SPAN> Repeat steps</SPAN>Repeator</SPAN>TMPAM03</SPAN>
jst1</SPAN>GroupB</SPAN>Justin</SPAN>Collection</SPAN> Collect Coupons</SPAN>Collector</SPAN>TMPAM02</SPAN>TMPAM02,TMPAM04</SPAN>
jst1</SPAN>GroupB</SPAN>Justin</SPAN>Statistics</SPAN> Data Analysis</SPAN>Statician</SPAN>TMPAM04</SPAN>

<TBODY>
</TBODY><COLGROUP><COL><COL><COL><COL><COL><COL span=2><COL><COL><COL><COL></COLGROUP>
 
Upvote 0
Hi mikerickson
Thanks for providing a UDF as well. I copied the UDF code into VB editor and that created the 'ContatIf' function in my macro enabled spread sheet. Then I interted the formula you provided in the I column cells. I was expecting the results as shown in my 'After' example provided to hiker95 but I am getting back value in the name column in some cells. wonder what I am doing wrong!


You could use this UDF, with a formula like
=IF(MATCH(A3, A:A, 0) = ROW(A3),ConcatIf(A:A, A3, C:C,", ",TRUE), "")
Code:
Function ConcatIf(ByVal compareRange As Range, ByVal xCriteria As Variant, Optional ByVal stringsRange As Range, _
                    Optional Delimiter As String, Optional NoDuplicates As Boolean) As String
                    
    Rem the first three argumens of ConcatIf mirror those of SUMIF
    Rem the Delimiter and NoDuplicates arguments are optional (default "" and False)
    Dim i As Long, j As Long
    
    With compareRange.Parent
        Set compareRange = Application.Intersect(compareRange, Range(.UsedRange, .Range("a1")))
    End With
    
    If compareRange Is Nothing Then Exit Function
    If stringsRange Is Nothing Then Set stringsRange = compareRange
    Set stringsRange = compareRange.Offset(stringsRange.Row - compareRange.Row, _
                                            stringsRange.Column - compareRange.Column)
    
    For i = 1 To compareRange.Rows.Count
        For j = 1 To compareRange.Columns.Count
            If (Application.CountIf(compareRange.Cells(i, j), xCriteria) = 1) Then
                If InStr(Delimiter & ConcatIf & Delimiter, Delimiter & CStr(stringsRange.Cells(i, j))) <> 0 Imp Not (NoDuplicates) Then
                    ConcatIf = ConcatIf & Delimiter & CStr(stringsRange.Cells(i, j))
                End If
            End If
        Next j
    Next i
    ConcatIf = Mid(ConcatIf, Len(Delimiter) + 1)
End Function
 
Upvote 0

Forum statistics

Threads
1,214,415
Messages
6,119,375
Members
448,888
Latest member
Arle8907

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top