From: Dan Thompson on
I have recently found a function on the interent that will remove duplicate
values within any array. It works just fine for a single dimensional array
but I would like to edit and change the code to work for Multi-Dimensional
array to support a minimum of 2 dimentional arrays. I only need it to find
any duplicate values within the first dimension of the array and than remove
any values corisponding to the same element number that the duplicate value
was found in the 1st dimention of the array and remove them from the 2nd and
3rd dimention of the array as well.

For example:
MyArray(1,2)
----------------------
| 0 | 0 | Hello |
| 1 | 0 | XX |
| 0 | 1 | Bye |
| 1 | 1 | YY |
| 0 | 2 | Hello |
| 1 | 2 | ZZ |
----------------------
So how it should work on the above sample array is that it would find look
for duplicate value in 1st dimention and find the value in 0,2 is a duplicate
of 0,0 and it will remove the 0,2 value and than since it found a duplicate
value in 0,2 and removed it, It would also than remove any value in same
corrisponding element row from the other dimentions i the case of the sample
above it would also not only remove 0,2 but it would remove 1,2 as well even
though 1,2 is not a duplicate
value.

Here is my currently working function based on just single dimetional arrays

Public Function RemoveDuplicates(ByRef SourceArray As Variant)
Dim Values As Collection
Dim Value As Variant
Dim Index1 As Long
Dim Index2 As Long

Set Values = New Collection
Index2 = LBound(SourceArray)
On Error Resume Next
For Index1 = LBound(SourceArray) To UBound(SourceArray)
Value = Empty
Value = Values(VarType(SourceArray(Index1)) & "|" & SourceArray(Index1))
If IsEmpty(Value) And Not Len(SourceArray(Index1)) = 0 Then
Values.Add SourceArray(Index1), VarType(SourceArray(Index1)) & "|"
& SourceArray(Index1)
SourceArray(Index2) = SourceArray(Index1)
Index2 = Index2 + 1
End If
Next Index1
On Error GoTo 0
If Index2 = 1 Then
SourceArray = Empty
Else
ReDim Preserve SourceArray(LBound(SourceArray) To Index2 - 1)
End If

End Function

I hope someone can help me find a solution.

Thanks,
Dan Thompson
From: Dave Peterson on
So with this data, you'd end up with 2 rows:

----------------------
| 0 | 0 | Hello |
| 1 | 0 | XX |
----------------------

If that's correct, then this worked ok for me. I don't think it would scale for
more than 2 dimensions, though.

All I did was let each entry in the collection hold that row (an array).

Option Explicit
Sub testme()

'| 0 | 0 | Hello |
'| 1 | 0 | XX |
'| 0 | 1 | Bye |
'| 1 | 1 | YY |
'| 0 | 2 | Hello |
'| 1 | 2 | ZZ |

Dim myArr(0 To 5, 0 To 2) As Variant
Dim myArrCols(0 To 2) As Variant
Dim cCtr As Long
Dim rCtr As Long

Dim myColl As Collection
Dim ColCtr As Long

Dim myNewArr As Variant

'just creating the test array
myArrCols(0) = Array(0, 1, 0, 1, 0, 1)
myArrCols(1) = Array(0, 0, 1, 1, 2, 2)
myArrCols(2) = Array("hello", "xx", "bye", "yy", "hello", "zz")

For cCtr = LBound(myArrCols) To UBound(myArrCols)
For rCtr = LBound(myArrCols(cCtr)) To UBound(myArrCols(cCtr))
myArr(rCtr, cCtr) = myArrCols(cCtr)(rCtr)
Next rCtr
Next cCtr


'now the real work
Set myColl = New Collection

On Error Resume Next
For rCtr = LBound(myArr, 1) To UBound(myArr, 1)
myColl.Add Application.Index(myArr, rCtr + 1, 0), CStr(myArr(rCtr, 0))
Next rCtr
On Error GoTo 0

If myColl.Count = 0 Then
MsgBox "no data!"
Else
ReDim myNewArr(LBound(myArr, 1) _
To LBound(myArr, 1) + myColl.Count - 1, _
LBound(myArr, 2) To UBound(myArr, 2))

iCtr = 1
For rCtr = LBound(myNewArr, 1) To UBound(myNewArr, 1)
'this didn't work
'myNewArr(rCtr) = myColl.Item(iCtr)
'so I had to loop
ColCtr = 1
For cCtr = LBound(myNewArr, 2) To UBound(myNewArr, 2)
myNewArr(rCtr, cCtr) = myColl.Item(iCtr)(ColCtr)
ColCtr = ColCtr + 1
Next cCtr
iCtr = iCtr + 1
Next rCtr
End If

'and to prove that it worked ok
For rCtr = LBound(myNewArr, 1) To UBound(myNewArr, 1)
For cCtr = LBound(myNewArr, 2) To UBound(myNewArr, 2)
Debug.Print rCtr & "." & cCtr & ":" & myNewArr(rCtr, cCtr)
Next cCtr
Next rCtr

End Sub


Dan Thompson wrote:
>
> I have recently found a function on the interent that will remove duplicate
> values within any array. It works just fine for a single dimensional array
> but I would like to edit and change the code to work for Multi-Dimensional
> array to support a minimum of 2 dimentional arrays. I only need it to find
> any duplicate values within the first dimension of the array and than remove
> any values corisponding to the same element number that the duplicate value
> was found in the 1st dimention of the array and remove them from the 2nd and
> 3rd dimention of the array as well.
>
> For example:
> MyArray(1,2)
> ----------------------
> | 0 | 0 | Hello |
> | 1 | 0 | XX |
> | 0 | 1 | Bye |
> | 1 | 1 | YY |
> | 0 | 2 | Hello |
> | 1 | 2 | ZZ |
> ----------------------
> So how it should work on the above sample array is that it would find look
> for duplicate value in 1st dimention and find the value in 0,2 is a duplicate
> of 0,0 and it will remove the 0,2 value and than since it found a duplicate
> value in 0,2 and removed it, It would also than remove any value in same
> corrisponding element row from the other dimentions i the case of the sample
> above it would also not only remove 0,2 but it would remove 1,2 as well even
> though 1,2 is not a duplicate
> value.
>
> Here is my currently working function based on just single dimetional arrays
>
> Public Function RemoveDuplicates(ByRef SourceArray As Variant)
> Dim Values As Collection
> Dim Value As Variant
> Dim Index1 As Long
> Dim Index2 As Long
>
> Set Values = New Collection
> Index2 = LBound(SourceArray)
> On Error Resume Next
> For Index1 = LBound(SourceArray) To UBound(SourceArray)
> Value = Empty
> Value = Values(VarType(SourceArray(Index1)) & "|" & SourceArray(Index1))
> If IsEmpty(Value) And Not Len(SourceArray(Index1)) = 0 Then
> Values.Add SourceArray(Index1), VarType(SourceArray(Index1)) & "|"
> & SourceArray(Index1)
> SourceArray(Index2) = SourceArray(Index1)
> Index2 = Index2 + 1
> End If
> Next Index1
> On Error GoTo 0
> If Index2 = 1 Then
> SourceArray = Empty
> Else
> ReDim Preserve SourceArray(LBound(SourceArray) To Index2 - 1)
> End If
>
> End Function
>
> I hope someone can help me find a solution.
>
> Thanks,
> Dan Thompson

--

Dave Peterson