ABOUT Visual Basic Programmieren Programmierung Download Downloads Tips & Tricks Tipps & Tricks Know-How Praxis VB VBA Visual Basic for Applications VBS VBScript Scripting Windows ActiveX COM OLE API ComputerPC Microsoft Office Microsoft Office 97 Office 2000 Access Word Winword Excel Outlook Addins ASP Active Server Pages COMAddIns ActiveX-Controls OCX UserControl UserDocument Komponenten DLL EXE
Diese Seite wurde zuletzt aktualisiert am 25.07.2001

Diese Seite wurde zuletzt aktualisiert am 25.07.2001
Aktuell im ABOUT Visual Basic-MagazinGrundlagenwissen und TechnologienKnow How, Tipps und Tricks rund um Visual BasicActiveX-Komponenten, Controls, Klassen und mehr...AddIns für die Visual Basic-IDE und die VBA-IDEVBA-Programmierung in MS-Office und anderen AnwendungenScripting-Praxis für den Windows Scripting Host und das Scripting-ControlTools, Komponenten und Dienstleistungen des MarktesRessourcen für Programmierer (Bücher, Job-Börse)Dies&Das...

Themen und Stichwörter im ABOUT Visual Basic-Magazin
Code, Beispiele, Komponenten, Tools im Überblick, Shareware, Freeware
Ihre Service-Seite, Termine, Job-Börse
Melden Sie sich an, um in den vollen Genuss des ABOUT Visual Basic-Magazins zu kommen!
Informationen zum ABOUT Visual Basic-Magazin, Kontakt und Impressum

Zurück...

Doubletten eliminieren

Zurück...


Anzeige

(-hg) mailto:hg_uniqueitemslbcb@aboutvb.de

Sie möchten doppelte Elemente aus einer ListBox oder aus einer ComboBox entfernen? Bei einer sortierten ListBox (alles weitere gilt auch gleichermaßen für eine ComboBox) ist das relativ einfach. Sie durchlaufen alle Elemente und entfernen diejenigen Elemente, die gleich dem vorhergehenden sind:

Dim l As Long
Dim nListCount As Long
Dim nLastItem As String
Dim nThisItem As String

With ListBox
  nListCount = .ListCount
  Do
    nThisItem = .List(l)
    If nThisItem = nLastItem Then
      .RemoveItem l
      nListCount = nListCount - 1
    Else
      nLastItem = nThisItem
      l = l + 1
    End If
  Loop Until l = nListCount
End With

Bei einer unsortierten ListBox geht es nicht so einfach. Theoretisch müssten Sie nämlich jedes Element mit jedem vergleichen. Sie können zwar trickreich schon verglichene Elemente aus darauf folgenden Vergleichen ausnehmen, aber trotzdem dauert das um so länger, je mehr Elemente die ListBox enthält.

Es müsste also eine Möglichkeit geben, sich jedes bereits geprüfte Element zu merken und nur noch zu prüfen, ob sich ein nachfolgendes Element bereits unter den geprüften Elementen befindet. An sich ist das auch kein Problem - die bereits geprüften Elemente werden in einem Array abgelegt. Jedes nachfolgende Element wird nun nur noch mit den in diesem Array vorhandenen Elementen verglichen. Aber auch hier steigt der Aufwand mit zunehmender Anzahl der Elemente. So ganz überzeugend ist dieses Verfahren also auch noch nicht.

Eine Variante wäre, in diesem Array nicht mehr die geprüften Elemente abzulegen, sondern nur noch jeweils einen eindeutigen Schlüssel, der sich über ein Element errechnen lässt, etwa einen Hashcode in einer Hash-Tabelle. Zwar muss dieser Schlüssel für jedes nachfolgende Element neu berechnet werden, damit er mit den bereits abgelegten Schlüsseln verglichen werden kann, aber das dürfte unterm Strich wahrscheinlich schneller sein, als String-Vergleiche.

Nach diesem Prinzip arbeitet das Verfahren, das ich Ihnen als Lösung vorstelle. Es verwendet eine Collection, die intern bereits eine Hash-Tabelle (oder ein ähnlich schnelles Prinzip) zur Verwaltung der als String übergebenen Schlüssel verwendet. Sie brauchen also in diese Collection nur ein "Nichts" (Empty) einzufügen und dabei den Element-String selbst als Schlüssel angeben. Die Prüfung, ob ein nachfolgendes Element bereits in der Collection enthalten ist, könnte nach dem Versuch-Irrtum-Prinzip geschehen: Sie versuchen, ein neues "Nichts" unter dem Element als Schlüssel einzufügen. Schlägt der Versuch fehl, ist das Element bereits in der Liste vorhanden und kann somit entfernt werden.

Dim nItems As Collection
Dim l As Long
Dim nListCount As Long

With ListBox
  nListCount = .ListCount
  Set nItems = New Collection
  On Error Resume Next
  Do
    nItems.Add Empty, .List(l)
    If Err.Number Then
      .RemoveItem l
      nListCount = nListCount - 1
      Err.Clear
    Else
      l = l + 1
    End If
  Loop Until l = nListCount
  End If
End With

Aber auch dies lässt sich noch optimieren. Mit dem Ansatz des Versuches, den gleichen Schlüssel beim Einfügen mehrfach zu verwenden, habe ich Sie nämlich aufs Glatteis geführt. Für das Einfügen, auch wenn es fehlschlägt, braucht Visual Basic nämlich relativ viel Zeit. Fast doppelt so schnell ist der Versuch, ein Collection-Element zu einem gegebenen Schlüssel auszulesen, und nur beim Fehlschlagen dieses Versuchs ein Element mit dem sich nun als noch unbekannt herausstellenden Schlüssel in die Collection einzufügen. Packen wir dieses Verfahren gleich in eine praktische Hilfsfunktion:

Public Sub UniqueItemsLB(ListBox As ListBox)
  Dim nItems As Collection
  Dim l As Long
  Dim nListCount As Long
  Dim nThisItem As String
  Dim nVar As Variant
  
  With ListBox
    nListCount = .ListCount
    Set nItems = New Collection
    On Error Resume Next
    Do
      nThisItem = .List(l)
      nVar = nItems(nThisItem)
      If Err.Number Then
        nItems.Add Empty, nThisItem
        l = l + 1
      Else
        .RemoveItem l
        nListCount = nListCount - 1
        Err.Clear
      End If
    Loop Until l = nListCount
  End With
End Sub

Bei einer unsortierten ListBox ist dieses Verfahren um ein Mehrfaches schneller, als die ursprünglich angedachte Lösung, jedes Element mit jedem zu vergleichen. Und bei einer sortierten ListBox ist es immerhin noch weit mehr als doppelt so schnell, wie unser bereits zu Anfang vorgestelltes und bereits sehr effizient erscheinendes Verfahren. Genau genommen ist es diesem letzten Verfahren nun völlig egal, ob es sich um eine sortierte oder um eine unsortierte ListBox handelt - es ist also noch nicht einmal eine optimierende Unterscheidung in dieser Hinsicht notwendig.


Modul modUniqueItemsLBCB (modUniqueItemsLBCB.bas - ca. 1,6 KB)


Artikel
Zum Download-Bereich dieses Artikel
Mail an den Autor dieses Artikels

KnowHow
Zur KnowHow-Übersicht

KnowHow-Themen
Themen - Allgemeines
Themen - Entwicklungsumgebung (VB-IDE)
Themen - Forms
Themen - Steuerelemente (Controls)
Themen - Grafik
Themen - Dateien
Themen - UserControls
Themen - Einsteiger-Tipps
Themen - Wussten Sie...?

Übersicht nach Titeln in alphabetischer Reihenfolge
Übersicht nach Erscheinungsdatum

Schnellsuche




Zum Seitenanfang

Copyright © 1999 - 2017 Harald M. Genauck, ip-pro gmbh  /  Impressum

Zum Seitenanfang

Zurück...

Zurück...

Download Internet Explorer