2012-08-08 58 views
6

Czy ktoś mógłby mi dać kilka wskazówek, jak rozwiązać następujący problem:VBA, usuwanie duplikatów z tablicy

Załóżmy Mam bloku danych w programie Excel 2010, 100 wierszy o 3 kolumnach.

Kolumna C zawiera kilka duplikatów, powiedzieć, że zaczyna się jak 1,1,1, 2,3,4,5 ....., 97,98

Korzystanie z VBA, chciałbym, aby usunąć duplikaty wierszy, zgodnie z kolumną C, więc pozostaję z 1,2,3, ....., 97, 98, tj. tylko 98 wierszy i 3 kolumny.

Wiem, że istnieje przycisk, który mogę kliknąć w Excel 2010, aby to zrobić, ale chcę to zrobić w VBA (ponieważ próbowałem tego i z jakiegoś powodu, wtrąca się reszta mojego kodu i podaje błędnie wyniki).

Ponadto, chciałbym zrobić to w macierzy, a następnie wklej wyniki w arkuszu, zamiast metod, takich jak Application.Worksheetfunction.countif (.....

Więc coś takiego:

.
Dim myarray() as Variant 
myarray=cells(1,1).Currentregion.value 

Dim a as Long 

For a=1 to Ubound(myarray,1) 

    'something here to 

Next a 

Odpowiedz

5

I answered a similar question Oto kod użyłem:

Dim dict As Object 
Dim rowCount As Long 
Dim strVal As String 

Set dict = CreateObject("Scripting.Dictionary") 

rowCount = Sheet1.Range("A1").CurrentRegion.Rows.Count 

'you can change the loop condition to iterate through the array rows instead 
Do While rowCount > 1 
    strVal = Sheet1.Cells(rowCount, 1).Value2 

    If dict.exists(strVal) Then 
    Sheet1.Rows(rowCount).EntireRow.Delete 
    Else 
    'if doing this with an array, then add code in the Else block 
    ' to assign values from this row to the array of unique values 
    dict.Add strVal, 0 
    End If 

    rowCount = rowCount - 1 
Loop 

Set dict = Nothing 

Jeśli chcesz używać tablicy, następnie pętli elementów z tego samego warunkowe (if/else) st ateny. Jeśli pozycja nie istnieje w słowniku, możesz dodać ją do słownika i dodać wartości wierszy do innej tablicy.

Szczerze mówiąc, myślę, że najbardziej skutecznym sposobem jest dostosowanie kodu można dostać od rejestrator makr. Można wykonać powyższą funkcję w jednym wierszu:

Sheet1.UsedRange.RemoveDuplicates Columns:=3, Header:=xlYes 
+2

To powoduje usunięcie rzeczywistych wierszy z arkusza, natomiast pytanie dotyczyło usunięcia duplikatów w VBA.Plus każde usunięcie wiersza powinno zawsze następować od dołu do góry, aby uniknąć pomijania wierszy. – brettdj

+0

@brettdj Oba bity kodu będą działać, aby usunąć duplikaty. Pytający chciał to zrobić w VBA, najlepiej z tablicami (w takim przypadku może on łatwo modyfikować pętlę, aby iterować przez wiersze tablicy zamiast zakresu, a następnie dodawać tylko unikalne elementy do oddzielnej tablicy). Jeśli spojrzysz na kod, zobaczysz, że usunięcie wiersza przechodzi od dołu do góry (wartość 'rowCount' zmniejsza się). :) – Zairja

+0

Cóż, pytanie jest zatytułowane * VBA, usuń duplikaty z tablicy *. Dobrze trafiłeś, że twój kod idzie w dół do sposobu, w jaki używasz '.Count', chociaż w tym przypadku pytający może potrzebować określić, czy pierwsze wystąpienie powinno być przechowywane na górze czy na dole. – brettdj

0

Słowniki mieć max 255 przedmiotów, więc jeśli masz więcej wartości trzeba użyć Collection. Niestety obiekt Collection nie ma metody .Contains (a) lub .Exists (a), ale ta funkcja ładnie (podróbka) ładnie, używając numerów błędów:

KOREKTA: Słowniki nie mają takich limit (dzięki Zairja). Być może używałem Integer do iteracji przez mój słownik. W każdym przypadku, funkcja ta pozwala sprawdzić kolekcje dla istnienia elementu, więc będę go tu zostawić, jeśli jest to przydatne każdemu:

CollContainsItem(col As Collection, val As Variant) As Boolean 

Dim itm As Variant 
On Error Resume Next 

    itm = col.Item(val) 
    CollContainsItem = Not (Err.Number = 5 Or Err.Number = 9) 

On Error GoTo 0 

End Function 

Więc jeśli potrzebujemy kolekcji, można prawdopodobnie wystarczy zastąpić

dict.Exists(strVal) 

z

CollContainsItem(coll, strVal) 

i zastąpić

Set dict = CreateObject("Scripting.Dictionary") 

z

Set coll = CreateObject("Scripting.Collection") 

i wykorzystać resztę kodu Zairja użytkownika. (Tak naprawdę nie próbowałem, ale powinno być blisko)

+2

W rzeczywistości obiekt 'Dictionary' nie jest ograniczony do 255 elementów. To tylko maksymalna liczba elementów wyświetlana przez debuggera. Uważam, że jest to ograniczone tylko przez pamięć (używam Excel 2010, ale w wersji 2003 mogłem mieć słowniki z kilkoma setkami tysięcy elementów). Dodatkowo, upewnij się, że jeśli używasz jakiejś zmiennej inkrementującej, upewnij się, że jest to 'Long', a nie' Integer' (który zatrzymałby się na 256). – Zairja

+0

Och, czy liczba całkowita Excela wynosi tylko 256? Może to był mój problem przez cały czas! –

3
Function eliminateDuplicate(poArr As Variant) As Variant 
Dim poArrNoDup() 

    dupArrIndex = -1 
For i = LBound(poArr) To UBound(poArr) 
     dupBool = False 

     For j = LBound(poArr) To i 
      If poArr(i) = poArr(j) And Not i = j Then 
       dupBool = True 
      End If 
     Next j 

     If dupBool = False Then 
      dupArrIndex = dupArrIndex + 1 
      ReDim Preserve poArrNoDup(dupArrIndex) 
      poArrNoDup(dupArrIndex) = poArr(i) 
     End If 
Next i 

eliminateDuplicate = poArrNoDup 
End Function 
+0

Proszę nie edytować innych odpowiedzi użytkowników SO, jak to było w [tej wersji] (http://stackoverflow.com/revisions/19693896/2), jeśli jest problem z kodem, komentarzem i niech wiedzą. – Lankymart

+0

Musisz ustawić dupBool na false dla każdej pętli i – 99moorem

Powiązane problemy