Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1588to1592
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

Insertion-Sort oder Heap-Sort

Insertion-Sort oder Heap-Sort
06.11.2017 11:39:21
Peter(silie)
Hallo Leute,
ich habe eine Maske in die ich mehrere hunderttausend Daten reinlade aus einer Excel-Tabelle.
Jede Spalte kommt in eine eigene Combobox(40 an der Zahl).
Die Daten einer Spalte sind unsortiert, ich verwende einen Quicksort um die Daten
zu sortieren und füge die arrays dann als List-Objekte in meine Comboboxen ein.
Nun kann mit der Maske ein Datensatz erstellt, verändert, oder gelöscht werden.
Die veränderten Daten müssen dann natürlich wieder in der Maske richtig angezeigt werden.
Bis Dato werden alle Daten nach erstellen/verändern/löschen wieder nacheinander sortiert und als Listen eingefügt.
Das ist suboptimal und macht keinen Sinn.
Deshalb möchte ich in meine bestehenden soriterten Listen/Arrays die Daten lediglich updaten und nicht komplett neu laden.
Sollte ich dafür einen Insertion-Sort verwenden oder einen Heap-Sort?

9
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Insertion-Sort oder Heap-Sort
06.11.2017 11:58:04
Daniel
Hi
Wenn die Daten schon sortiert sind, müsste das ganze für einzelne Datensätze so funktionieren:
1. alten Datensatz löschen (RemoveItem)
2. Soll-Position des neuen Datensatzes ermitteln (Worksheetfunction.Match oder Schleife)
3. geänderten Datensatz mit AddItem unter Angabe der unter 2 ermittelten Positionsnummer neu einfügen.
mit .AddItem kann man Daten bei einer List- oder Combobox nicht nur am Datenende, sondern auch mittendrin einfügen, wenn man mit Positionsnummer mit angibt. Die Nachfolgenden Daten rutschen dann um eine Postion nach hinten.
Wenn du die neuen Daten gleich an der richtigen Stelle einfügst, ist ein erneutes Sortieren nicht erforderlich.
Gruß Daniel
Anzeige
AW: Insertion-Sort oder Heap-Sort
06.11.2017 12:03:38
Zwenn
Hallo Peter(silie),
sowohl Insertion-Sort wie auch Heap-Sort sind meiner Erinnerung nach langsamer als Quicksort. Letzterer ist ein "teile und herrsche" Algorithmus und die Sortierung ist fertig, wenn die Daten einmal durchlaufen wurden (einfach ausgedrückt).
Ich würde bei so vielen Daten auch keine komplette Neusortierung vornehmen, wenn Du sequentiell Einträge änderst:
  • Löschen: Hier musst Du gar nix machen, weil sich die Sortierung nicht ändert

  • Einfügen: Suche die richtige Einfügestelle und erstelle den neuen Eintrag genau dort

  • Verändern: Suche die richtige Stelle, trage den geänderten Eintrag dort ein und lösche den alten Eintrag

  • Was Du also brauchst, ist ein Suchalgorithmus, keine neue Sortierung. Da alle Daten sortiert vorliegen sollte eine Suche mit Bordmitteln von der Geschwindigkeit her schnell genug sein.
    Viele Grüße,
    Zwenn
    Anzeige
    AW: Insertion-Sort oder Heap-Sort
    06.11.2017 12:24:25
    mmat
    Hallo Peter,
    wenn es nur darum geht, einen einzelnen Eintrag in eine bereits sortierte Liste in einer Combobox einzufügen, ist ganz klar ein an Insert-Sort angelehntes Verfahren angesagt.
    vg, MM
    AW: Insertion-Sort oder Heap-Sort
    06.11.2017 13:20:39
    Peter(silie)
    Hallo,
    erstmal vielen Dank für eure Hilfe.
    Folgendes habe ich jetzt gemacht:
    - Modul "Update_" erstellt
    - Sub My_Control hinzugefügt
    - Function Item_Exists hinzugefügt
    - Sub Insert_item hinzugefügt
    Modul Update_ Code:
    Option Explicit
    Public Sub My_Control(ByRef Combobox_ As MSForms.ComboBox, ByVal item_ As Variant)
    If Not Item_Exists(Combobox_.list, item_) Then
    Insert_Item Combobox_, item_
    End If
    End Sub
    Private Function Item_Exists(ByRef ListToCheck As Variant, ByVal item_ As Variant) As Boolean
    Dim List_ As Variant
    List_ = ListToCheck
    With Application
    If Not VBA.IsError(.Match(item_, List_, 0)) Then Item_Exists = True
    End With
    End Function
    Private Sub Insert_Item(ByRef Combobox_ As MSForms.ComboBox, item_ As Variant)
    Dim i As Long
    For i = 0 To Combobox_.ListCount
    If Combobox_.list(i, 0) 
    Code in UserForm nach Button Click:
    Update_.My_Control Me.cb_DatensatzRef, Me.tb_BerichtNr.value
    

    Anzeige
    Update
    06.11.2017 13:55:55
    Peter(silie)
    Hallo,
    aufgrund von Fehlern die Aufgetroffen sind durch Datums Werte o.ä. habe ich den Code etwas abgeändert:
    Option Explicit
    Public Sub My_Control(ByRef Combobox_ As MSForms.ComboBox, ByVal item_ As Variant)
    If Combobox_.ListCount > 0 Then
    If Not Item_Exists(Combobox_, item_) Then
    Insert_Item Combobox_, item_
    End If
    End If
    End Sub
    Private Function Item_Exists(ByRef Combobox_ As MSForms.ComboBox, ByVal item_ As String) As  _
    Boolean
    Dim varList() As String: varList = Convert_to_String_Array(Combobox_.list)
    If Not VBA.IsError(Application.Match(item_, varList, 0)) Then Item_Exists = True
    End Function
    Private Sub Insert_Item(ByRef Combobox_ As MSForms.ComboBox, item_ As Variant)
    Dim i As Long, tmp As String
    For i = 0 To Combobox_.ListCount - 1
    tmp = Combobox_.list(i, 0)
    If tmp 

    Anzeige
    AW: Update
    06.11.2017 15:27:30
    mmat
    Hallo Peter,
    ich weiss nicht, ob ich das Problem richtig verstanden habe, aber du willst einen neuen Wert in eine sortierte Liste einfügen (Combo- oder Listbox) und Duplikate vermeiden ?
    Wie wärs damit:
    Private Sub InsertItem(c As msforms.ListBox, s As String, Optional AllowDupes As Boolean = True) _
    Dim x As Long, lc As Long
    lc = c.ListCount
    If lc = 0 Then c.AddItem s: Exit Sub
    x = -1
    Do
    x = x + 1
    If x >= lc Then Exit Do
    Loop Until c.List(x) >= s
    If Not (AllowDupes) And x 
    Bei Datümern wird's schwierig, am einfachsten isses wohl wenn man diese im Format "JJJJ.MM.DD" darstellt...
    Anzeige
    AW: Update
    06.11.2017 16:28:48
    Peter(silie)
    Hallo,
    ja das ist richtig.
    Da die Datenfelder sehr variable vom Inhalt sind und somit auch aus verschiedensten
    Datentypen bestehen(Int, Double, String, Currency, DateTime) habe ich mich jetzt dazu entschieden,
    die List in ein String Array zu konvertieren, mit der fahre ich dann fort und füge Sie anschließend
    als neue List wieder in die Combobox ein.
    Danke für deine Hilfe, dein Vorschlag gefällt mir.
    Hier mal der Code der es bei mir jetzt tut:
    Option Explicit
    Public Sub My_Control(ByRef Combobox_ As MSForms.ComboBox, ByVal item_ As Variant, ByVal  _
    Operation_ As Long)
    Dim varList As Variant
    If Combobox_.ListCount > 0 Then
    If Operation_ = 0 Then
    varList = Convert_to_String_Array(Combobox_.list)
    If Not Item_Exists(varList, item_) Then
    Insert_Item Combobox_, item_
    End If
    ElseIf Operation_ = 1 Then
    varList = Convert_to_String_Array(Combobox_.list)
    If Item_Exists(varList, item_) Then
    Delete_Item varList, item_
    Combobox_.list = varList
    Combobox_.value = Combobox_.list(0, 0)
    End If
    End If
    End If
    End Sub
    Private Function Item_Exists(ByRef array_ As Variant, ByVal item_ As String) As Boolean
    If Not VBA.IsError(Application.Match(item_, array_, 0)) Then Item_Exists = True
    End Function
    Private Sub Insert_Item(ByRef Combobox_ As MSForms.ComboBox, item_ As Variant)
    Dim i As Long, tmp As String
    tmp = Combobox_.list(0, 0)
    While tmp  -1 Then array_(i - 1) = ""
    End Sub
    Private Function IndexOf(ByRef source As Variant, this_ As Variant) As Long
    With Application
    If Not VBA.IsError(.Match(this_, source, 0)) Then
    IndexOf = .Match(this_, source, 0)
    Else
    IndexOf = -1
    End If
    End With
    End Function
    Private Function Convert_to_String_Array(ByRef ListToConvert As Variant) As String()
    Dim i As Long, tmp() As String
    i = UBound(ListToConvert)
    ReDim tmp(i)
    For i = 0 To UBound(ListToConvert)
    tmp(i) = CStr(ListToConvert(i, 0))
    Next i
    Convert_to_String_Array = tmp
    Erase tmp
    End Function
    

    Anzeige
    AW: Update
    06.11.2017 17:02:25
    mmat
    Jetzt stell dir mal vor, der neue Wert muß als letzter hintendrangehängt werden.
    Ich habs zwar nicht getestet, aber ich glaube, damit geht's nicht.
    Private Sub Insert_Item(ByRef Combobox_ As MSForms.ComboBox, item_ As Variant)
    

    Excel-Sort
    06.11.2017 14:11:31
    lupo1
    [A:A] = a
    [A:A].Sort (bzw. der entspr. VBA-Code)
    a = [A:A]

    Links zu Excel-Dialogen

    Beliebteste Forumthreads (12 Monate)

    Anzeige

    Beliebteste Forumthreads (12 Monate)

    Anzeige
    Anzeige
    Anzeige