dubbele waarden verwijderen (remove duplicates)

Status
Niet open voor verdere reacties.

pasan

Terugkerende gebruiker
Lid geworden
6 nov 2010
Berichten
1.110
hallo
ik heb in office 2010 een macro gemaakt om dubbele waarden te verwijderen
dit was heel simpel te maken met het knopje dubbele waarden verwijderen in het lint
zie code

maar het probleem is dat dit gebruikt moet worden met excel 2000 en daar werkt het niet
Iemand een suggestie of een oplossing?

Code:
Sub archiefinventaris_Knop1_Klikken()
'
' archiefinventaris_Knop1_Klikken Macro
' dubbele waarden weghalen archief inventaris

Application.ScreenUpdating = False
    Columns("C:N").Select
    Sheets("archiefinventaris").Unprotect Password:=Sheets("archiefdagrapportage").Range("i2")
    ActiveSheet.Range("$C:$O").RemoveDuplicates Columns:=Array(1, 2, 3, 4, 5, 6, 7, 8, 9, _
        10, 11, 12), Header:=xlNo
    Range("C1").Select
    Sheets("archiefinventaris").Protect Password:=Sheets("archiefdagrapportage").Range("i2")
Application.ScreenUpdating = True
End Sub

groet

Pasan:thumb:
 
Hoi Pasan,

Ik heb ff snel een soortgelijke functie in elkaar geflanst die hopelijk wel in excel 2000 werkt.

De functie is alleen geschikt voor bereiken waarbij je alle kolommen met elkaar wilt vergelijken, het duurt me te lang om een optie om specifieke kolommen met elkaar te vergelijken in te bouwen, wellicht heeft iemand anders daar wel tijd voor.

Om het goed te laten werken is het aan te raden om deze code in een nieuwe module te plakken.

twee opmerkingen:
1. De gegevens in de broncellen worden gesorteerd, om het ontdubbelen makkelijker te maken
2. Er wordt een nieuw blad aangemaakt met de ontdubbelde gegevens, zodat je zelf kan bepalen of je je oude gegevens kan overschrijven of niet.

Code:
Option Explicit
Private mvarSource As Variant
Private mlngNew As Long
Private mlngDeleted As Long

Private Enum dupHeaders
    dpYEs = 1
    dpNo = 2
End Enum

Sub archiefinventaris_Knop1_Klikken()
'Versie 2

    Application.ScreenUpdating = False
    Sheets("archiefinventaris").Unprotect Password:=Sheets("archiefdagrapportage").Range("i2")
    
    RemoveDuplicates Source:=Range("C1:O" & ActiveSheet.UsedRange.Rows.Count), _
                     Columns:=Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), _
                     Header:=dpNo
    
    Range("C1").Select
    Sheets("archiefinventaris").Protect Password:=Sheets("archiefdagrapportage").Range("i2")
    
    Application.ScreenUpdating = True
End Sub

Private Sub RemoveDuplicates(ByVal Source As Range, _
                             ByRef Columns As Variant, _
                             ByVal Header As dupHeaders)
'Source is een range variabele
'Columns doet niets momenteel
'header is een constante van enum dupheaders(zie bovenin module)
Dim mVarNew As Variant
        
    If Source.Cells.Count = 1 Then
        MsgBox "deze bewerking kan niet worden uitgevoerd op één enkele cel", _
                vbInformation
        Exit Sub
    ElseIf Source.Areas.Count <> 1 Then
            MsgBox "Selecteer een bereik en niet gehele kolommen!", _
            vbInformation
        Exit Sub
    ElseIf Source.Rows.Count > 50000 Then
        MsgBox "Selecteer een bereik en niet gehele kolommen!", _
                vbInformation
        Exit Sub
    End If
        
    Application.ScreenUpdating = False
    XLSort Source, Header
    Application.ScreenUpdating = True
    
    mVarNew = StripDuplicates(Source, Header)
    
    Sheets.Add
    
    ActiveSheet.Range("A1").Resize(UBound(mVarNew, 2), UBound(mVarNew, 1)) = _
        XL_Transpose(mVarNew)
    
    MsgBox "Er zijn " & mlngDeleted & " rijen verwijderd, en er blijven " & _
            mlngNew & " Unieke waarden over.", vbInformation


End Sub

Private Function StripDuplicates(ByVal rngDuplicates As Range, _
                                 ByVal Header As dupHeaders) As Variant
Dim avarDuplicates As Variant
Dim avarClean As Variant
Dim i As Long
Dim j As Long
Dim strRow As String
Dim strCompare As String

    mlngDeleted = 0
    mlngNew = 0

    avarDuplicates = rngDuplicates.Value
    ReDim avarClean(1 To UBound(avarDuplicates, 2), 1)

    For i = LBound(avarDuplicates) + (Header Mod 2) To UBound(avarDuplicates)
        
        strRow = Join(WorksheetFunction.Index(avarDuplicates, i, 0), "")

        If StrComp(strCompare, strRow, vbBinaryCompare) = 0 Then
            'skip this row
            mlngDeleted = mlngDeleted + 1
        
        Else
            'new unique row, add it.
            mlngNew = mlngNew + 1
            ReDim Preserve avarClean(1 To UBound(avarDuplicates, 2), 1 To mlngNew)
            
            For j = 1 To UBound(avarDuplicates, 2)
                avarClean(j, mlngNew) = avarDuplicates(i, j)
            Next
        
        End If
        
        strCompare = strRow

    Next
    
    StripDuplicates = avarClean

End Function

Private Sub XLSort(ByVal RangeToSort As Range, _
                    ByVal Headers As dupHeaders)
'Supports more than 3 columns
    Dim i As Long
    Dim lngLast As Long

    With RangeToSort
    
        For i = .Columns.Count To 1 Step -2
    
            If i >= 3 Then
                .Sort Key1:=.Cells(1, i - 2), Order1:=xlAscending, _
                      Key2:=.Cells(1, i - 1), Order2:=xlAscending, _
                      Key3:=.Cells(1, i), Order3:=xlAscending, _
                      Header:=Headers
                        
            ElseIf .Columns.Count = 2 Then
                .Sort Key1:=.Cells(1, 1), Order1:=xlAscending, _
                      Key2:=.Cells(1, 2), Order2:=xlAscending, _
                      Header:=Headers
                    
            ElseIf .Columns.Count = 1 Then
                .Sort Key1:=.Cells(1, 1), Order1:=xlAscending, _
                      Header:=Headers
                    
            Else
                .Sort Key1:=.Cells(1, 1), Order1:=xlAscending, _
                      Key2:=.Cells(1, 2), Order2:=xlAscending, _
                      Key3:=.Cells(1, 3), Order3:=xlAscending, _
                      Header:=Headers
            End If
    
        Next
    
    End With

End Sub

Private Function XL_Transpose(ByVal avarMatrix As Variant) As Variant
Dim avarResult As Variant
Dim i As Long
Dim j As Long

    If IsArray(avarMatrix) Then
        ReDim avarResult(1 To UBound(avarMatrix, 2), 1 To UBound(avarMatrix, 1))
    
        For i = LBound(avarMatrix, 2) To UBound(avarMatrix, 2)
            For j = LBound(avarMatrix, 1) To UBound(avarMatrix, 1)
                avarResult(i, j) = avarMatrix(j, i)
            Next
        Next
        XL_Transpose = avarResult
    Else
        XL_Transpose = avarMatrix
    End If
        
End Function
 
Mark Xl bedankt voor je reactie op mijn vraag maar de werking is helaas niet dat wat ik zocht ik zal een voorbeeld bestandje plaatsen met uitleg
ik snap je bedoeling wel maar de mensen die hier mee moeten werken denk ik niet.
voorbeeld bestand volgt
 
Met onderstaande code kopieer ik van blad Inventaris naar archiefinventaris deze werkt ook in office 2000.
De code in mn start vraag daarmee haalde ik de dubbele waarden weg dit werkt niet in office 2000.
Maar mischien benader ik mn doel verkeerd is het mischien mogelijk om bij het kopieeren al meteen te kijken of bepaalde waarden al bestaan?

Code:
Sub Copy_With_AutoFilter2()
'Note: This macro use the function LastRow
'Important: The DestSh must exist
Application.ScreenUpdating = False
    Dim My_Range As Range
    Dim DestSh As Worksheet
    Dim calcmode As Long
    Dim ViewMode As Long
    Dim FilterCriteria As String
    Dim CCount As Long
    Dim rng As Range

    'Set filter range on ActiveSheet: A1 is the top left cell of your filter range
    'and the header of the first column, D is the last column in the filter range.
    'You can also add the sheet name to the code like this :
    'Worksheets("Sheet1").Range("A1:D" & LastRow(Worksheets("Sheet1")))
    'No need that the sheet is active then when you run the macro when you use this.
    Sheets("Inventaris").Unprotect Password:=Sheets("archiefdagrapportage").Range("i2")
    Set My_Range = Range("C2:O" & Lastrow(ActiveSheet))
    My_Range.Parent.Select

    'Set the destination worksheet
    'Note: the sheet "blad?" must exist in your workbook
    Set DestSh = Sheets("archiefinventaris")
    Application.ScreenUpdating = False
    Sheets("archiefinventaris").Visible = True
    Sheets("archiefinventaris").Unprotect Password:=Sheets("archiefdagrapportage").Range("i2")
    If ActiveWorkbook.ProtectStructure = True Or _
       My_Range.Parent.ProtectContents = True Then
        MsgBox "Sorry, het blad is beveiligd met een wachtwoord", _
               vbOKOnly, "Copy to new worksheet"
        Exit Sub
    End If

    'Change ScreenUpdating, Calculation, EnableEvents, ....
    With Application
        calcmode = .Calculation
        
        .ScreenUpdating = False
        .EnableEvents = False
    End With
    ViewMode = ActiveWindow.View
    ActiveWindow.View = xlNormalView
    ActiveSheet.DisplayPageBreaks = False

    'Firstly, remove the AutoFilter
    My_Range.Parent.AutoFilterMode = False

    'Filter and set the filter field and the filter criteria :
    'This example filter on the first column in the range (change the field if needed)
    'In this case the range starts in A so Field 1 is column A, 2 = column B, ......
    'Use "<>Netherlands" as criteria if you want the opposite
    My_Range.AutoFilter Field:=4, Criteria1:="<>"

    'If you want to filter on a cell value you can use this, use "<>" for the opposite
    'This example uses the activecell value
    'My_Range.AutoFilter Field:=1, Criteria1:="=" & ActiveCell.Value

    'This will use the cell value from A2 as criteria
    'My_Range.AutoFilter Field:=1, Criteria1:="=" & Range("A2").Value

    ''If you want to filter on a Inputbox value use this
    'FilterCriteria = InputBox("What text do you want to filter on?", _
     '                          "Enter the filter item.")
    'My_Range.AutoFilter Field:=1, Criteria1:="=" & FilterCriteria


    'Check if there are not more then 8192 areas(limit of areas that Excel can copy)
    CCount = 0
    On Error Resume Next
    CCount = My_Range.Columns(1).SpecialCells(xlCellTypeVisible).Areas(1).Cells.Count
    On Error GoTo 0
    If CCount = 0 Then
        MsgBox "There are more than 8192 areas:" _
             & vbNewLine & "het geselecteerd gebied is te groot." _
             & vbNewLine & "Tip: handmatig toevoegen.", _
               vbOKOnly, "Copy to worksheet"
    Else
  
        'Copy the visible data and use PasteSpecial to paste to the Destsh
        With My_Range.Parent.AutoFilter.Range
            On Error Resume Next
           
            ' Set rng to the visible cells in My_Range without the header row
            Set rng = .Offset(1, 0).Resize(.Rows.Count - 1, .Columns.Count) _
                      .SpecialCells(xlCellTypeVisible)
            On Error GoTo 0
            If Not rng Is Nothing Then
                'Copy and paste the cells into DestSh below the existing data
                rng.Copy
                With DestSh.Range("C" & Lastrow(DestSh) + 1)
                    ' Paste:=8 will copy the columnwidth in Excel 2000 and higher
                    ' Remove this line if you use Excel 97
                    .PasteSpecial Paste:=8
                    .PasteSpecial xlPasteValues
                    .PasteSpecial xlPasteFormats
                    Application.CutCopyMode = False
                End With
                'Delete the rows in the My_Range.Parent worksheet
                'rng.EntireRow.Delete
            End If
        End With
    End If

    'Close AutoFilter
    My_Range.Parent.AutoFilterMode = False

    'Restore ScreenUpdating, Calculation, EnableEvents, ....
    ActiveWindow.View = ViewMode
    Application.GoTo DestSh.Range("A1")
    With Application
        .ScreenUpdating = True
        .EnableEvents = True
        .Calculation = calcmode
    End With
    Sheets("archiefinventaris").Protect Password:=Sheets("archiefdagrapportage").Range("i2")
    Sheets("archiefinventaris").Visible = False
    Application.ScreenUpdating = True
   Sheets("Inventaris").Visible = True
Sheets("Inventaris").Protect Password:=Sheets("archiefdagrapportage").Range("i2")
End Sub


Function Lastrow(sh As Worksheet)
    On Error Resume Next
    Lastrow = sh.Cells.Find(What:="*", _
                            After:=sh.Range("A1"), _
                            LookAt:=xlPart, _
                            LookIn:=xlValues, _
                            SearchOrder:=xlByRows, _
                            SearchDirection:=xlPrevious, _
                            MatchCase:=False).Row
    On Error GoTo 0
End Function

groet

Pasan:thumb:
 
Laatst bewerkt:
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan