mohrsys
Goto Top

Excel 2003 - 5 Ebenen sortieren

Hallo Freaks,

ich habe ein Problem mit Excel 2003 und hoffe ihr könnt mir helfen?!?!?!?!

Und zwar habe ich eine große Tabelle und möchte diese nach 5 Ebenen sortieren.
Leider kann ich im Menü "sortieren" nur 3 Ebenen sortieren lassen.

Kann ich dieses Fenster "erweitern"???

Vielen vielen Dank für eure Hilfe!!!

Grüße,
Christian

Content-Key: 148824

Url: https://administrator.de/contentid/148824

Printed on: April 18, 2024 at 10:04 o'clock

Member: Biber
Biber Aug 11, 2010 at 20:07:06 (UTC)
Goto Top
Moin Mit-Freak,

bitte beschränke die Verwendung von "???" und "!!!" und "?!?!?!" auf ein normales Dorfdisko-vor-21h-Maß.
Dann kommen mehr Antworten zum eigentlichen Thema.

a) Du kannst nicht mit vertretbarem Aufwand das Menü "Sortieren" erweitern
b) du kannst aber natürlich eine zusätzliche (meinetwegen unsichtbare) Hilfsspalte anlegen, nach der du ganz oder teilsortierst.
Beispiel. Wenn du eigentlich nach Spalten B, E, F, K und L sortieren musst, leg dir doch in Feld W2 (wie Whatever) per Formel
=B2 & E2 & F2 &K2 & L2

...an und kopiere es nach unten.
Und sortier dann nach Spalte W
c) Wenn du eine Excel-Tapete hast, die du nach 5 Spalten sortieren musst....Hey! Du solltest mal langsam eine Datenbank oder ein kleines SQL-Handbuch auf den Wunschzettel setzen. Excel ist -lass dir nichts anderes einreden- ziemlich ZWEI-dimensional ....setzt eine starre Sortierung (oder Umsortierung) voraus.

Wenn es bei dir kein konzeptioneller Fehler ist, der dich zu 5 Sortierspalten zwingt, dann brauchst du die Flexibilität einer Datenbank.
Da kannst du selbst bei den billigsten Varianten mindestens 128 verschiedene sauschnelle Indices auf einer Tabelle haben.

Grüße
Biber
Member: bastla
bastla Aug 11, 2010 at 20:31:56 (UTC)
Goto Top
... und falls sich mittendrin in Deinen 5 Werten auch die eine oder andere Zahl befindet, sei an die Funktion "TEXT()" erinnert - mit der bringst Du die Zahlen dann auch auf eine gleiche Stellenanzahl - etwa:
=B2 & TEXT(E2;"000000,00") & TEXT(F2;"0000") & K2 & L2
bzw wenn auch für eine gleiche Länge der Textinhalte vorgesorgt werden muss, zB
=RECHTS(WIEDERHOLEN(" ";20)&B2;20) & TEXT(E2;"000000,00") & TEXT(F2;"0000") & RECHTS(WIEDERHOLEN(" ";20)&K2;20) & RECHTS(WIEDERHOLEN(" ";20)&L2;20)
wobei hier davon ausgegangen wurde, dass keiner der Textinhalte mehr als 20 Zeichen umfasst (ansonsten eben jeweils beide Werte in der entsprechenden "RECHTS()"-Funktion entsprechend erhöhen) ...

Grüße
bastla
Mitglied: 76109
76109 Aug 13, 2010 at 21:32:02 (UTC)
Goto Top
Mitglied: 76109
76109 Aug 16, 2010 at 20:57:06 (UTC)
Goto Top
Hallo zusammen!

2. Versuchface-smile

Beim vorherigen Codeschnipsel hatte ich leider einen Denkfehler, obwohl bastla in seinem Kommentar deutlichst auf das Problem beim Stringverknüpfen hingewiesen hatface-wink Meine Testdaten waren leider nicht darauf ausgelegt, sodass mir das erst später bewusst wurdeface-smile Bei weiteren Überlegungen, bin ich dann auf eine noch viel einfachere Lösung gestoßen und hoffe, dass es diesesmal fehlerfrei funktioniert?

Der VBA-Code ist der Versuch Biber's Anregungen in einen automatisierten Vorgang umzusetzenface-wink

Die maximale Anzahl der Ebenen ist mir nicht bekannt. Hab nur 6 Ebenen (auf ca 50.000 Zeilen verteilt) getestet.

Vorbereitungen:
Den VB-Editor öffnen Menü>Extras>Makro>Visual Basic Editor
Im Project-Explorer Rechte Maustaste>Einfügen>UserForm eine Leere UserForm erstellen
Im Eigenschaftsfenster UserForm1>(Name) von "UserForm1" nach "FormSort" ändern
Im Project-Explorer FormSort>Rechte Maustaste>Code anzeigen Quelltext UserForm einfügen
Im Project-Explorer Rechte Maustaste>Einfügen>Modul Quelltext Modul einfügen
Anschließend in Menü>Debuggen>Kompilern von VBA-Project] anklicken
Darauf achten, dass in den Codeseiten ganz oben nur einmal "Option Explicit" drinnen steht!

Wenn keine Fehler angezeigt werden, dann VB-Editor wieder schließen. Das Makro kann dann über Excel-Menü>Extras>Makro>Makros>Sortieren gestartet werden, wobei mit dem Auswahlpunkt Optionen eine Tastenkombination angegeben werden kann.

Wegen der Übersichtlichkeit habe ich bewusst auf das auskommentieren verzichtet. Wenn was unklar ist, bitte Fragen!

UserForm(Quelltext in FormSort kopieren):
Option Explicit

Const MaxCellChar = 64
'Konstante anpassen, wenn Zellen mehr als 64 Zeichen enthalten (32, 64, 128)  

Public WithEvents BtnOK As MSForms.CommandButton
Public WithEvents BtnClear As MSForms.CommandButton
Public WithEvents BtnCancel As MSForms.CommandButton

Public WithEvents CBoxColumns As MSForms.ComboBox
Public WithEvents LabelColumns As MSForms.Label

Public WithEvents OptionOrderAZ As MSForms.OptionButton
Public WithEvents OptionOrderZA As MSForms.OptionButton
Public WithEvents OptionHeaderOn As MSForms.OptionButton
Public WithEvents OptionHeaderOff As MSForms.OptionButton

Const adVarChar = 200
Const adFldIsNullable = 32

Dim FormEvents As New Collection

Sub InitUserForm()
    Dim Char As String, i As Integer
        
    If Selection.Count < 2 Then
        MsgBox "Kein Bereich ausgewählt!", vbExclamation, "Fehler":  Exit Sub  
    End If
    
    With FormSort
       .Caption = "Daten sortieren":  .Height = 212:  .Width = 222  
        
        With .Controls
            .Add "Forms.Frame.1", "FrameColumns"  
            .Add "Forms.Frame.1", "FrameOrder"  
            .Add "Forms.Frame.1", "FrameHeader"  
        End With
        
        With .Controls("FrameColumns")  
            .Caption = "Spalten auswählen"  
            .TabIndex = 0
            .Height = 54: .Left = 12: .Top = 12: .Width = 194
            
             Set FormSort.LabelColumns = .Controls.Add("Forms.Label.1", "LabelColumns")  
             Set FormSort.CBoxColumns = .Controls.Add("Forms.ComboBox.1", "CBoxColumns")  
             Set FormSort.BtnClear = .Controls.Add("Forms.CommandButton.1", "BtnClear")  
        End With
        
        With .LabelColumns
            .Height = 16: .Left = 12: .Top = 25: .Width = 168
            .BackColor = &HFFFFFF
            .SpecialEffect = fmSpecialEffectSunken
        End With
             
        With .CBoxColumns
            .TabIndex = 0
            .Height = 15.75: .Left = 12: .Top = 6: .Width = 72
        End With
            
        With .BtnClear
            .Accelerator = "C"  
            .Caption = "Clear"  
            .TabIndex = 1
            .Height = 18: .Left = 119: .Top = 4: .Width = 60
        End With
        
        With .Controls("FrameOrder")  
            .Caption = "Sortieren"  
            .TabIndex = 1
            .Height = 36: .Left = 12: .Top = 72: .Width = 194
             
             Set FormSort.OptionOrderAZ = .Controls.Add("Forms.OptionButton.1", "OptionOrderAZ")  
             Set FormSort.OptionOrderZA = .Controls.Add("Forms.OptionButton.1", "OptionOrderZA")  
        End With
        
        With .OptionOrderAZ
            .Accelerator = "U"  
            .Caption = "Aufsteigend"  
            .Value = True
            .TabIndex = 0
            .Height = 18: .Left = 10: .Top = 6: .Width = 78
        End With
        
        With .OptionOrderZA
            .Accelerator = "B"  
            .Caption = "Absteigend"  
            .TabIndex = 1
            .Height = 18: .Left = 108: .Top = 6: .Width = 78
        End With
        
        With .Controls("FrameHeader")  
            .Caption = "Daten enthalten"  
            .TabIndex = 2
            .Height = 36: .Left = 12: .Top = 114: .Width = 194
            
             Set FormSort.OptionHeaderOn = .Controls.Add("Forms.OptionButton.1", "OptionHeaderOn")  
             Set FormSort.OptionHeaderOff = .Controls.Add("Forms.OptionButton.1", "OptionHeaderOff")  
        End With
             
        With .OptionHeaderOn
            .Accelerator = "E"  
            .Caption = "eine Überschrift"  
            .TabIndex = 0
            .Height = 18: .Left = 10: .Top = 6: .Width = 78
        End With
        
        With .OptionHeaderOff
            .Accelerator = "K"  
            .Caption = "keine Überschrift"  
            .Value = True
            .TabIndex = 1
            .Height = 18: .Left = 108: .Top = 6: .Width = 78
        End With
        
        Set .BtnOK = .Controls.Add("Forms.CommandButton.1", "BtnOK")  
        Set .BtnCancel = .Controls.Add("Forms.CommandButton.1", "BtnCancel")  
        
        With .BtnOK
            .Accelerator = "O"  
            .Caption = "OK"  
            .TabIndex = 3
            .Height = 18: .Left = 36: .Top = 162: .Width = 60
        End With
        
        With .BtnCancel
            .Accelerator = "A"  
            .Caption = "Abbrechen"  
            .TabIndex = 4
            .Height = 18: .Left = 120: .Top = 162: .Width = 60
        End With
        
        FormEvents.Add .BtnOK
        FormEvents.Add .BtnCancel
        FormEvents.Add .BtnClear
        FormEvents.Add .CBoxColumns
    End With
    
    With CBoxColumns
        For i = 0 To UBound(Selection.Value, 2) - 1
             Char = Chr(Asc("@") + Selection.Column + i)  
            
            .AddItem "Spalte " & Char  
            .List(.ListCount - 1, 1) = Char
        Next
       
       .ListIndex = 0
        LabelColumns = " " & .List(0, 1)  
       .SetFocus
        Show
    End With
End Sub

Private Sub CBoxColumns_Change()
    With CBoxColumns
        If .ListIndex < 0 Then
            Exit Sub
        ElseIf LabelColumns = "" Then  
            LabelColumns = " " & .List(.ListIndex, 1)  
        ElseIf InStr(LabelColumns, .List(.ListIndex, 1)) = 0 Then
            LabelColumns = LabelColumns & ";" & .List(.ListIndex, 1)  
        End If
    End With
End Sub

Private Sub BtnClear_Click()
    LabelColumns = ""  
End Sub

Private Sub BtnCancel_Click()
    Unload Me
End Sub

Private Sub BtnOK_Click()
    If LabelColumns <> "" Then Call Sortieren  
    Unload Me
End Sub

Private Sub Sortieren()
    Dim RS As Object, Cols As Variant, SortText As String, SortOrder As String, i As Long, r As Long
    Dim ColCount As Long, FirstCol As Long, LastCol As Long, FirstRow As Long, LastRow As Long
    
    Set RS = CreateObject("ADOR.Recordset")  

    With Selection
        If OptionHeaderOn = True Then FirstRow = .Row + 1 Else FirstRow = .Row
        
        If UBound(.Value, 1) = Rows.Count Then
            LastRow = Cells(Rows.Count, CBoxColumns.List(0, 1)).Rows.End(xlUp).Row
        Else
            LastRow = .Row + UBound(.Value, 1) - 1
        End If
        
        ColCount = UBound(.Value, 2)
        
        FirstCol = .Column:  LastCol = .Column + ColCount - 1
    End With
    
    If OptionOrderAZ = True Then SortOrder = " ASC," Else SortOrder = " DESC,"  
            
    Cols = Split(Trim(LabelColumns), ";")  
    
    For i = 0 To UBound(Cols)
        SortText = SortText & Cols(i) & SortOrder
    Next
    
    SortText = Mid(SortText, 1, Len(SortText) - 1)
    
    With RS
        For i = 0 To ColCount - 1
            .Fields.Append CBoxColumns.List(i, 1), adVarChar, MaxCellChar, adFldIsNullable
        Next
    
       .Open
    
        For r = FirstRow To LastRow
           .AddNew
            For i = 0 To ColCount - 1
               .Fields(i) = Cells(r, FirstCol + i)
            Next
           .Update
        Next
    
       .Sort = SortText:  .Update
       
        Application.ScreenUpdating = False
         
        Range(Cells(FirstRow, FirstCol), Cells(LastRow, LastCol)).ClearContents
        
        For r = FirstRow To LastRow
            For i = 0 To ColCount - 1
                Cells(r, FirstCol + i) = .Fields(i)
            Next
           .MoveNext
        Next
       
       .Close
        
        Application.ScreenUpdating = True
    End With
End Sub

Modul(Quelltext in Modul kopieren):
Option Explicit

Sub Sortieren()
    FormSort.InitUserForm
End Sub

Zum Ablauf:
Ist kein Bereich markiert, wird eine entsprechende Meldung ausgegeben und der Vorgang abgebrochen.

Die Steuerelemente der UserForm werden erst zur Laufzeit des Makros erstellt. Die UserForm beinhaltet dann 3 Frames mit Steuerelementen und 2 Buttons:

Frame1 (Spalten auswählen) beinhaltet:
Eine Combobox, in der die einzelnen Spalten der Sortierreihenfolge nach ausgewählt werden können.
Eine Textanzeige, die die ausgewählten Spalten in Form A;B;C;.... anzeigt
Ein Button (Clear), mit dem die Auswahl bei einer Falscheingabe wieder gelöscht werden kann

Frame2 (Sortieren) beinhaltet:
Zwei Option-Buttons mit der Auswahl Aufsteigend/Absteigend

Frame3 (Daten enthalten) beinhaltet:
Zwei Option-Buttons mit der Auswahl Eine/Keine Überschrift

Buttons:
Zwei Command-Buttons OK/Abbrechen

Gruß Dieter
Member: Biber
Biber Aug 17, 2010 at 06:50:24 (UTC)
Goto Top
Moin didi1954,

du ahnst sicherlich, dass ich deine Beiträge in diesem Forum sehr zu schätzen weiss.
Mit dieser Lösung bringst du mich (in meiner Rolle als Moderator) aber in mehrfacher Hinsicht in eine Zwickmühle.

Erstens ist dieser vor 6 Tagen erstellte und seit 5 Tagen mit mehreren unabhängig voneinander funktionierenden Lösungsansätzen beantwortete Beitrag immer noch ohne Antwort.

Und gehört von daher schon seit dem Wochenende eigentlich in einem anderen meiner Lieblingsbereiche.

Kein Feedback, kein Wert für andere Lösungssucher - du kennst da ja meine Haltung.
Wäre aber schade drum nach deiner Musterlösung. face-wink

Zweitens... so schön diene Strategie "rein handwerklich" auch ist.... wie ich oben angedeutet habe - ich würde schon gerne noch mal draufschauen, wie und warum es überhaupt soweit kommen konnte (rein fachlich).

Ich ziehe ja gern über die Redmonder her - aber ich würde denen niemals Knauserigkeit oder Inkompetenz unterstellen, weil die in Excel (=bestes M$-Tool wo überhaupt gibt) "nur" eine Sortierung nach drei Spalten erlauben.

Wer seine Exceltapeten nach 5 oder 7 oder 122 Spalten sortieren muss, damit aus Daten Informationen werden, der hat vorher schon irgendwas verratzt. Oder benutzt das falsche Tool/sollte lieber eine Datenbank nehmen. Dazu stehe ich nach wie vor.

Anyway - @MohrSys: Ich bitte mal allerfreundlichst um zeitnahes Feedback, ob denn deine Frage hinreichend beantwortet wurde.

Grüße
Biber
Member: MohrSys
MohrSys Aug 17, 2010 at 07:15:58 (UTC)
Goto Top
@Biber:

Ich kenne mich zwar recht gut in Excel aus, aber bei Quelltext und VB-Editor muß ich passen.

Ich sortiere weiterhin nur 3 Ebenen und werde mit ggf. ein neueres Office-Paket zulegen
(bei z.B. 2007 sollte ich selbst (und danz einfach) mehrere Ebenen anlegen können).

Vielen Dank aber für eure Bemühungen!

Christian
Mitglied: 76109
76109 Aug 17, 2010 at 07:30:53 (UTC)
Goto Top
Guten Morgen Biber!

Tja, ich habe auch erst überlegt, ob ich den Code reinsetzen soll, da der TO eigentlich gar keine Antwort verdient. Aber dann habe ich mir gedacht, naja, es gibt ja eventuell noch andere, die es interessieren könnte und da ich aus persönlichem Ehrgeiz den Code erstellt habe, wäre es doch schade drum, ihn in den Mülleimer zu werfenface-smile Ich zumindest, habe keine Verwendung dafür, aber ich mag eben kleine Herausforderungenface-smile

Außerdem kann ich mir vorstellen, das einige Coder die UerForm-Erstellung zur Laufzeit interessieren könnte, sofern sie den Beitrag auch per Google finden.

Ansonsten hast Du natürlich - wie meistens - wieder mal Recht und es lag bestimmt nicht in meiner Absicht, Dir in irgendeiner Weise an die Karre zu fahren und hoffe Du vergibst mir diesesmal auch wiederface-wink

Gruß Dieter