Sortierung einer Spalte innerhalb einer Tabelle ohne andere Spalten mit zu sortieren

  • Excel

Es gibt 76 Antworten in diesem Thema. Der letzte Beitrag () ist von cry.baby.

    Update: Aktualisierter Code siehe unten!

    Kopier am besten das ganze Modul nochmal neu rein. Habe es getestet und es sollte funktionieren:

    Visual Basic-Quellcode

    1. Option Explicit
    2. Sub Einfaerben()
    3. Const Blau = 15773696 'RGB(0, 176, 240)
    4. Const Lila = 10498160 'RGB(121, 48, 160)
    5. Const Gelb = 65535 'RGB(255, 255, 0)
    6. Const Grün = 5287936 'RGB(0,176,80)
    7. Const Rot = 255 'RGB(255,0,0)
    8. Const Orange = 52479 'RGB(255,204,0)
    9. Dim AnzahlGV0598_blau, AnzahlGV0587_lila, AnzahlGV0588_gelb, AnzahlGV0598_grün, AnzahlGV0587_rot, AnzahlGV0588_orange As Integer
    10. Dim GezähltGV0598, GezähltGV0587, GezähltGV0588 As Integer
    11. Dim Finden, RangeFinden, r As Range
    12. 'Hilfsspalte D mit Farbnummern erstellen
    13. With Sheets("Tabelle2")
    14. For Each r In Intersect(.UsedRange, .Range("B:B"))
    15. r.Offset(0, 2) = r.Interior.Color
    16. Next r
    17. 'Anschließend die Stückzahl zur jeweiligen GV dynamisch ermitteln
    18. Set RangeFinden = .Range("D2", .Range("D2").End(xlDown))
    19. AnzahlGV0598_blau = AnzahlFarben(RangeFinden, Blau)
    20. AnzahlGV0587_lila = AnzahlFarben(RangeFinden, Lila)
    21. AnzahlGV0588_gelb = AnzahlFarben(RangeFinden, Gelb)
    22. AnzahlGV0598_grün = AnzahlFarben(RangeFinden, Grün)
    23. AnzahlGV0587_rot = AnzahlFarben(RangeFinden, Rot)
    24. AnzahlGV0588_orange = AnzahlFarben(RangeFinden, Orange)
    25. End With
    26. With Sheets("Tabelle1")
    27. 'Für GV0598_blau
    28. GezähltGV0598 = 0
    29. For Each r In Intersect(.UsedRange, .Range("B:B"))
    30. If r = "GV0598" And GezähltGV0598 < AnzahlGV0598_blau Then
    31. GezähltGV0598 = GezähltGV0598 + r.Count
    32. r.Offset(0, -1).Interior.Color = Blau
    33. End If
    34. Next r
    35. 'Für GV0587_lila
    36. GezähltGV0587 = 0
    37. For Each r In Intersect(.UsedRange, .Range("B:B"))
    38. If r = "GV0587" And GezähltGV0587 < AnzahlGV0587_lila Then
    39. GezähltGV0587 = GezähltGV0587 + r.Count
    40. r.Offset(0, -1).Interior.Color = Lila
    41. End If
    42. Next r
    43. 'Für GV0588_gelb
    44. GezähltGV0588 = 0
    45. For Each r In Intersect(.UsedRange, .Range("B:B"))
    46. If r = "GV0588" And GezähltGV0588 < AnzahlGV0588_gelb Then
    47. GezähltGV0588 = GezähltGV0588 + r.Count
    48. r.Offset(0, -1).Interior.Color = Gelb
    49. End If
    50. Next r
    51. 'Für GV0598_grün
    52. GezähltGV0598 = 0
    53. For Each r In Intersect(.UsedRange, .Range("B:B"))
    54. If r = "GV0598" Then
    55. GezähltGV0598 = GezähltGV0598 + r.Count
    56. If r = "GV0598" And GezähltGV0598 > AnzahlGV0598_blau And GezähltGV0598 <= AnzahlGV0598_blau + AnzahlGV0598_grün Then
    57. r.Offset(0, -1).Interior.Color = Grün
    58. End If
    59. End If
    60. Next r
    61. 'Für GV0587_rot
    62. GezähltGV0587 = 0
    63. For Each r In Intersect(.UsedRange, .Range("B:B"))
    64. If r = "GV0587" Then
    65. GezähltGV0587 = GezähltGV0587 + r.Count
    66. If r = "GV0587" And GezähltGV0587 > AnzahlGV0587_lila And GezähltGV0587 <= AnzahlGV0587_lila + AnzahlGV0587_rot Then
    67. r.Offset(0, -1).Interior.Color = Rot
    68. End If
    69. End If
    70. Next r
    71. 'Für GV0588_orange
    72. GezähltGV0588 = 0
    73. For Each r In Intersect(.UsedRange, .Range("B:B"))
    74. If r = "GV0588" Then
    75. GezähltGV0588 = GezähltGV0588 + r.Count
    76. If r = "GV0588" And GezähltGV0588 > AnzahlGV0588_gelb And GezähltGV0588 <= AnzahlGV0588_gelb + AnzahlGV0588_orange Then
    77. r.Offset(0, -1).Interior.Color = Orange
    78. End If
    79. End If
    80. Next r
    81. End With
    82. End Sub
    83. Function AnzahlFarben(ByVal SuchRange As Range, Farbenname As String) As Integer
    84. Dim Rng As Range
    85. Set Rng = SuchRange.Find(Farbenname)
    86. If Not Rng Is Nothing Then AnzahlFarben = Val(Rng.Offset(0, -2).Value)
    87. End Function

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „cry.baby“ ()

    Wo weist er den Fehler genau aus? Hier?

    Visual Basic-Quellcode

    1. 'Hilfsspalte D mit Farbnummern erstellen
    2. With Sheets("Tabelle2")
    3. For Each r In Intersect(.UsedRange, .Range("B:B"))
    4. r.Offset(0, 2) = r.Interior.Color
    5. Next r
    6. End With


    Dann probier es mal so:

    Visual Basic-Quellcode

    1. 'Hilfsspalte D mit Farbnummern erstellen
    2. Sheets("Tabelle2").activate
    3. For Each r In Intersect(Tabelle2.UsedRange, Tabelle2.Range("B:B"))
    4. r.Offset(0, 2) = r.Interior.Color
    5. Next r
    Leider immer noch nicht.
    Habe mal meinen Code rein kopiert.
    Die rot markierte Zeile ist die wo er den fehler ausgibt.
    Die grünen sind die alternativen Zeilen als Textzeile markiert.
    Habe immer beides mal ausprobiert. Aber immer der selbe Fehler in der gleichen Zeile.

    Visual Basic-Quellcode

    1. Option Explicit
    2. Private Sub CommandButton1_Click()
    3. Const Blau = 15773696 'RGB(0, 176, 240)
    4. Const Lila = 10498160 'RGB(121, 48, 160)
    5. Const Gelb = 65535 'RGB(255, 255, 0)
    6. Const Grün = 5287936 'RGB(0,176,80)
    7. Const Rot = 255 'RGB(255,0,0)
    8. Const Orange = 52479 'RGB(255,204,0)
    9. Dim AnzahlGV0598_blau, AnzahlGV0587_lila, AnzahlGV0588_gelb, AnzahlGV0598_grün, AnzahlGV0587_rot, AnzahlGV0588_orange As Integer
    10. Dim GezähltGV0598, GezähltGV0587, GezähltGV0588 As Integer
    11. Dim RangeStckZahl As Range
    12. Dim r As Range
    13. Dim Finden As Variant
    14. Dim RangeFinden As Range
    15. 'Hilfsspalte D mit Farbnummern erstellen
    16. 'With Sheets("Tabelle2")
    17. Sheets("Tabelle2").Activate
    18. 'For Each r In Intersect(.UsedRange, .Range("B:B"))
    19. For Each r In Intersect(Tabelle2.UsedRange, Tabelle2.Range("B:B"))
    20. r.Offset(0, 2) = r.Interior.Color
    21. Next r
    22. 'End With
    23. 'Anschließend die Stückzahl zur jeweiligen GV dynamisch ermitteln
    24. Sheets("Tabelle2").Activate
    25. Set RangeFinden = Range("D2", Range("D2").End(xlDown))
    26. Finden = RangeFinden.Find(Blau).Offset(0, -2) ' <<--- FEHLER HIER
    27. AnzahlGV0598_blau = Finden
    28. Finden = RangeFinden.Find(Lila).Offset(0, -2)
    29. AnzahlGV0587_lila = Finden
    30. Finden = RangeFinden.Find(Gelb).Offset(0, -2)
    31. AnzahlGV0588_gelb = Finden
    32. Finden = RangeFinden.Find(Grün).Offset(0, -2)
    33. AnzahlGV0598_grün = Finden
    34. Finden = RangeFinden.Find(Rot).Offset(0, -2)
    35. AnzahlGV0587_rot = Finden
    36. Finden = RangeFinden.Find(Orange).Offset(0, -2)
    37. AnzahlGV0588_orange = Finden
    38. 'With Sheets("Tabelle1")
    39. Sheets("Tabelle1").Activate
    40. 'Für GV0598_blau
    41. GezähltGV0598 = 0
    42. 'For Each r In Intersect(.UsedRange, .Range("B:B"))
    43. For Each r In Intersect(Tabelle1.UsedRange, Tabelle1.Range("B:B"))
    44. If r = "GV0598" And GezähltGV0598 < AnzahlGV0598_blau Then
    45. GezähltGV0598 = GezähltGV0598 + r.Count
    46. r.Offset(0, -1).Interior.Color = Blau
    47. End If
    48. Next r
    49. 'Für GV0587_lila
    50. GezähltGV0587 = 0
    51. For Each r In Intersect(Tabelle1.UsedRange, Tabelle1.Range("B:B"))
    52. If r = "GV0587" And GezähltGV0587 < AnzahlGV0587_lila Then
    53. GezähltGV0587 = GezähltGV0587 + r.Count
    54. r.Offset(0, -1).Interior.Color = Lila
    55. End If
    56. Next r
    57. 'Für GV0588_gelb
    58. GezähltGV0588 = 0
    59. For Each r In Intersect(Tabelle1.UsedRange, Tabelle1.Range("B:B"))
    60. If r = "GV0588" And GezähltGV0588 < AnzahlGV0588_gelb Then
    61. GezähltGV0588 = GezähltGV0588 + r.Count
    62. r.Offset(0, -1).Interior.Color = Gelb
    63. End If
    64. Next r
    65. 'Für GV0598_grün
    66. GezähltGV0598 = 0
    67. For Each r In Intersect(Tabelle1.UsedRange, Tabelle1.Range("B:B"))
    68. If r = "GV0598" Then
    69. GezähltGV0598 = GezähltGV0598 + r.Count
    70. If r = "GV0598" And GezähltGV0598 > AnzahlGV0598_blau And GezähltGV0598 <= AnzahlGV0598_blau + AnzahlGV0598_grün Then
    71. r.Offset(0, -1).Interior.Color = Grün
    72. End If
    73. End If
    74. Next r
    75. 'Für GV0587_rot
    76. GezähltGV0587 = 0
    77. For Each r In Intersect(Tabelle1.UsedRange, Tabelle1.Range("B:B"))
    78. If r = "GV0587" Then
    79. GezähltGV0587 = GezähltGV0587 + r.Count
    80. If r = "GV0587" And GezähltGV0587 > AnzahlGV0587_lila And GezähltGV0587 <= AnzahlGV0587_lila + AnzahlGV0587_rot Then
    81. r.Offset(0, -1).Interior.Color = Rot
    82. End If
    83. End If
    84. Next r
    85. 'Für GV0588_orange
    86. GezähltGV0588 = 0
    87. For Each r In Intersect(Tabelle1.UsedRange, Tabelle1.Range("B:B"))
    88. If r = "GV0588" Then
    89. GezähltGV0588 = GezähltGV0588 + r.Count
    90. If r = "GV0588" And GezähltGV0588 > AnzahlGV0588_gelb And GezähltGV0588 <= AnzahlGV0588_gelb + AnzahlGV0588_orange Then
    91. r.Offset(0, -1).Interior.Color = Orange
    92. End If
    93. End If
    94. Next r
    95. 'End With
    96. End Sub


    Code-Tags eingefügt. ~Thunderbolt

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Thunderbolt“ ()

    Parawolli schrieb:

    Finden = RangeFinden.Find(Blau).Offset(0, -2)

    Range.Find gibt ein Range-Objekt zurück und muss deshalb entsprechend zugewiesen werden:

    Visual Basic-Quellcode

    1. Set Finden = RangeFinden.Find(Blau) 'wenn nichts gefunden wird, wird hier ein Null-Objekt zurückgegeben (Nothing)
    2. If Not Finden Is Nothing Then FindenBlau = Finden.Offset(0, -2).Value

    Es ist schade, dass VBA kein Option Strict On kennt.
    Du kannst es dir trotzdem weitgehend erleichtern, wenn du nie Variant verwendest, sondern die Variablen mit dem richtigen Datentyp deklarierst.
    Dim RangeFinden As Range

    Die Tatsache, dass der Code bei erfolgreicher Suche läuft, liegt an der Tatsache, dass bei der Zuweisung
    Finden = RangeFinden.Find(Blau).Offset(0, -2)
    Nicht das Range-Objekt RangeFinden.Find(Blau).Offset(0, -2), sondern dessen Default-Property Value zugewisen wird.
    Also streng genommen: Finden = RangeFinden.Find(Blau).Offset(0, -2).Value
    Wenn aber halt RangeFinden.Find(Blau) Nothing ist, crasht das Ganze, weil Nothing nun mal keine Property Offset hat.
    Deswegen bei Range.Find immer überprüfen, ob was gefunden wurde.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „petaod“ ()

    Hallo petaod,
    Ich habe mal Deinen Code (Siehe unten) eingegeben.
    Die beiden roten Zeilen werden abwechselnd als Fehler ausgegeben.
    Wahrscheinlich habe ich aber auch nicht ganz verstanden was ich jetzt machen musste und habe es falsch eingegeben.
    Beim ersten mal hat er das FindenBlau als Fehler ausgegeben, weil es wahrscheinlich nicht deklariert war. Nachden ich es als Variable bzw. Range angelegt hatte, hat er mir die Zeile dadrüber als Fehler angegeben.

    'Dim FindenBlau As Variant
    Dim FindenBlau As Range

    Sheets("Tabelle2").Activate

    Set Finden = RangeFinden.Find(Blau) 'wenn nichts gefunden wird, wird hier ein Null-Objekt zurückgegeben (Nothing)
    If Not Finden Is Nothing Then FindenBlau = Finden.Offset(0, -2).Value


    Set RangeFinden = Range("D2", Range("D2").End(xlDown))

    Finden = RangeFinden.Find(Blau).Offset(0, -2).Value
    AnzahlGV0598_blau = Finden

    *Rot in blau geändert, siehe Regeln bzgl. Moderatorenfarbe*

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Marcus Gräfe“ ()

    Du musst sowohl 'Finden' als auch 'RangeFinden' als Range deklarieren. Da 'Finden' jetzt kein Variant mehr ist, sondern eine Range und somit eine Objekt_Variable, musst Du Finden ein 'Set' vorsetzen. Zudem muss 'RangeFinden' vor der Methode .Find bestimmt werden. In Code sieht das dann so aus:

    Visual Basic-Quellcode

    1. Dim Finden, RangeFinden As Range
    2. 'Anschließend die Stückzahl zur jeweiligen GV dynamisch ermitteln
    3. Sheets("Tabelle2").Activate
    4. Set RangeFinden = Range("D2", Range("D2").End(xlDown))
    5. Set Finden = RangeFinden.Find(Blau).Offset(0, -2)
    6. If Not Finden Is Nothing Then
    7. AnzahlGV0598_blau = Finden
    8. End If


    @Petaod: Danke für die Lehreinheit! Hab wieder was dazugelernt!

    cry.baby schrieb:

    Set Finden = RangeFinden.Find(Blau).Offset(0, -2)
    Führt auch zu einem Crash, wenn Blau nicht gefunden wird.
    Dann ist RangeFinden.Find(Blau)=Nothing.
    Und Nothing.Offset(0, -2) gibt es nicht.
    Deshalb erst suchen und, nur wenn gefunden, die nachfolgenden Schritte durchführen.

    Deshalb

    Visual Basic-Quellcode

    1. Set Finden = RangeFinden.Find(Blau)
    2. If Not Finden Is Nothing Then AnzahlGV0598_blau = Finden.Offset(0, -2).Value
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    X/ Dann würde ich ein 'On Error Resume Next' und 'On Error Goto 0' einbauen. Müsste in dem Fall ausreichen, oder? Bzw. gleich richtig:

    Visual Basic-Quellcode

    1. Set Finden = RangeFinden.Find(Blau) '.Offset(0, -2)
    2. If Not Finden Is Nothing Then
    3. AnzahlGV0598_blau = Finden.Offset(0, 2).value
    4. End If


    Vollzitat entfernt. ~Thunderbolt


    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „Thunderbolt“ ()

    cry.baby schrieb:

    Dann würde ich ein 'On Error Resume Next' und 'On Error Goto 0' einbauen
    Erwartete Fehler mit On Error abzufangen ist kein besonders guter Stil.
    Im übrigen würde ich so etwas nur in einer überschaubaren Funktion durchführen.
    On Error Goto 0 hebt alle EventHandler auf, die sich ggf. noch in der Routine befinden.

    Wenn dann so:

    Visual Basic-Quellcode

    1. Function NumberOfColors(ByVal SearchRange As Range, Colorname As String) As Integer
    2. On Error Goto Done
    3. NumberOfColors = SearchRange.Find(ColorName).Offset(0, -2)
    4. Done:
    5. End Function


    Und im Code dann einfach für jede Farbe entsprechend.

    Visual Basic-Quellcode

    1. GV0598_blau = NumberOfColors(RangeFinden, Blau)


    Ich würde dennoch für die Funktion die saubere Variante wählen

    Visual Basic-Quellcode

    1. Function NumberOfColors(ByVal SearchRange As Range, Colorname As String) As Long
    2. Dim Rng As Range
    3. Set Rng = SearchRange.Find(ColorName)
    4. If Not Rng Is Nothing Then NumberOfColors = Val(Rng.Offset(0, -2).Value)
    5. End Function

    Ist nicht länger, aber erfordert keine unnötige zeitintensive Fehlerbehandlung.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Hi Wolfgang,

    ich habe den Code weiter oben (zweites Posting) entsprechend den Hinweisen von petaod aktualisiert. Du kannst ihn kopieren/einfügen, dann sollte es jetzt gehen.

    Die Funktion von petaod habe ich auch nocheingebaut (nur mit deutschen Namen um der Linie treu zu bleiben) -> wenn Du neben den angegeben Farben weitere einfügen möchtest ist die Anpassung einfacher und macht den Code auch schlanker!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „cry.baby“ ()

    Hi cry.baby & petaod
    Vielen Dank, das Ihr beide Euch Zeit für mich genommen habt. Es funktioniert jetzt.

    Ich hatte allerdings etwas vergessen zu erwähnen.
    In der originalen Tabelle1 sind in Spalte C mal SN: Nr. vorhanden und mal keine vorhanden. (Siehe Anhang)
    Ich möchte das er in Spalte A nur die farblich markiert, wo keine SN: Nr. in Spalte C neben der entsprechenden GV steht. Wenn eine SN: Nr. drin steht, soll er die Zelle unberührt lassen (farblos) und einfach mit dem Zählen zur nächsten GV springen und in der entsprechenden Farbe markieren.
    Denn überall wo eine SN: Nr. vorhanden ist soll in Spalte A grau markiert werden. Alles andere in den Farben zur Tabelle2.

    Das grau markieren habe ich bereits mit einer einfachen IF Abfrage hin bekommen. Allerdings schaffe ich es nicht zu programmieren, das er immer einen Schritt weiter mit den Farben springen soll.

    Habe folgendes für die GV0598 und fabe blau ausprobiert.
    Also eigentlich nur z als Range deklariert
    Die rote Zeile hinzugefügt und in der IF Bedingung den roten Teil als weitere Bedingung hinzugefügt.
    Funktioniert aber nicht so leicht wie ich dachte.

    Visual Basic-Quellcode

    1. With Sheets("Tabelle1")
    2. GezähltGV0598 = 0
    3. Dim z As Range
    4. For Each r In Intersect(Tabelle1.UsedRange, Tabelle1.Range("B:B"))
    5. For Each z In Intersect(Tabelle1.UsedRange, Tabelle1.Range("C:C")) ' <<---
    6. ' vvvvvvvvvv
    7. If r = "GV0598" And z = "" And GezähltGV0598 < AnzahlGV0598_blau Then
    8. GezähltGV0598 = GezähltGV0598 + r.Count
    9. r.Offset(0, -1).Interior.Color = Blau
    10. End If
    11. Next z
    12. Next r
    13. End With
    14. End Sub


    Code-Tags eingefügt. Die Farbe "Rot" ist der Moderation vorbehalten. ~Thunderbolt
    Dateien
    • Test.xlsx

      (11,74 kB, 38 mal heruntergeladen, zuletzt: )

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Thunderbolt“ ()

    cry.baby schrieb:

    Hast Du vllt noch was vergessen uns zu sagen? Hm? Also irgend ne Spalte nicht erwähnt oder so? <img src="https://www.vb-paradise.de/wcf/images/smilies/biggrin.png" alt=":D" />

    <span style="color: #FF0000"><b>Vollzitat entfernt.</b> ~Thunderbolt</span>


    Glaube nicht oder lass mal überlegen ?(

    Habe das fast fertige Programm mal als Text-Datei angehangen. Funktioniert super.
    Ist aber etwas lang geworden mit 2752 Zeilen....
    Habe auch direkt die Farben die verwendet werden dürfen fest vorgegeben, damit nicht ausversehen eine fremde Farbe genommen werden kann, die dann nicht erkannt wird.
    Habe noch nicht alle GV Nr. integriert. Denke werden am Ende ca. 3000 Zeilen sein.
    Ohne Deinen Code hätte ich das aber nicht geschafft.
    Habe aber trotzdem sehr viel dabei gelernt.
    Ich muss noch irgendwie versuchen, das die Farbwahl individuell sein darf und nicht fest vorgegeben ist.

    Ab und zu kann es vorkammen das ich pro GV Nr. 3 Farben vergeben muss, weil ich 3 Aufträge glaichzeitig geplant habe. Werde mal versuchen Deinen Code daraufhin zu erweitern.
    Lg Wolfgang
    Dateien
    • Planungsliste.txt

      (93,67 kB, 153 mal heruntergeladen, zuletzt: )

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Parawolli“ ()