Listing Distinct Items From A Range
This page describes code that you can use to get a list of the
distinct elements in an range.
Most every application written for Excel makes use of list in one way or another, and
Excel provides a number of functions (VLOOKUP, HLOOKUP,
and the D data functions. However, there is no formula function that allows
you to get a list of the distinct elements. That is, a list with all duplicates removed. Excel's
Advanced Filter can do this, but it has two significant shortcomings: First, the list of distinct
values must be placed on the same worksheet as the original data. Second, the list created by
Advanced Filter is static. If you add new elements to the list, the filter list of distinct values
is no updated. You have to apply the filter manually.
The code on this page describes a VBA procedure called GetDistinct that returns
an array containing the distinct values from a range. The function declaration is:
Public Function GetDistinct(RR As Range) As Variant()
where RR is the range from which the distinct values are to be extracted. There result in an array of Variants.
This will return the values the values oriented as a single row spanning several columns. To get the result oriented
as a column, one column spanning several rows, use the TRANPOSE function to transpose the
array: =TRANSPOSE(GetDistict(A1:A10)).
This is an array formula, so you must first select the range cell cells into which the distinct values are
to be written, enter the formula, and press CTRL SHIFT ENTER rather than just
ENTER when you first enter the formula and whenever you edit it later. If you
do this properly, Excel will display the formula in the formula bar enclosed in curly braces { }.
The code can optionally resize the array to the size of the range from which it was called. Normally, if you enter
an array function into more cells than the size of the returned array, Excel files the empty cell with
#N/A errors. As written, the code will automatically resize itself so that it
fills the entire range with data, so no #N/A errors will appear. The values of the array
that lie outside the distinct elements are filled with empty strings so they will appear blank. See
the nodes in the comments of the code marked with '<<<<< OPTIONAL for details about this
part of the code.
The code for the GetDistinct procedure is shown below:
Option Explicit
Option Compare Text
Public Function GetDistinct(RR As Range) As Variant()
Dim Arr() As Variant
Dim R As Range
Dim N As Long
Dim Ndx As Long
Dim ArraySize As Long
' If the range RR is completely empty, get out.
If Application.WorksheetFunction.CountA(RR) = 0 Then
ReDim Arr(1 To Application.Caller.Cells.Count)
For N = 1 To Application.Caller.Cells.Count
Arr(N) = vbNullString
Next N
GetDistinct = Arr
Exit Function
End If
ArraySize = Application.Evaluate("=SUM(1/IF(" & RR.Address & "="""",1,(COUNTIF(" & _
RR.Address & "," & RR.Address & "))))-COUNTBLANK(" & RR.Address & ")")
ReDim Arr(1 To ArraySize)
For Each R In Application.Intersect(RR.Worksheet.UsedRange, RR).Cells
If R.Text <> vbNullString Then
On Error Resume Next
Err.Clear
N = 0
N = Application.WorksheetFunction.Match(R.Value, Arr, 0)
If Err.Number <> 0 Then
Ndx = Ndx + 1
Arr(Ndx) = R.Value
End If
End If
Next R
If Application.Caller.Cells.Count > Ndx Then
ReDim Preserve Arr(1 To Application.Caller.Cells.Count)
For N = Ndx + 1 To Application.Caller.Cells.Count
Arr(N) = vbNullString
Next N
Else
ReDim Preserve Arr(1 To Ndx)
End If
GetDistinct = Arr
End Function
|
This page last updated: 9-August-2010. |