2 abhängige Comboboxen außerhalb Userform

  • Excel

Es gibt 64 Antworten in diesem Thema. Der letzte Beitrag () ist von Patrick.

    Ich hätte einfach die Abfrage im Change-Event auf Einzelzellen erweitert, um die Endlosschleife weg zu kriegen.

    Visual Basic-Quellcode

    1. ​If Target.Count = 1 And Not Intersect(Target, Range("E4:F4")) Is Nothing Then


    Aber mal generell:
    Dein Design ist sehr statisch.
    Wenn morgen jemand auf die Idee kommt, eine blaue Latzhose ins Programm zu nehmen, greift dein Code nicht mehr.
    Das ist ein Faux-Pas.

    Aber ich fürchte, dass deine derzeitigen Kenntnisse nicht reichen, das Projekt so dynamisch zu gestalten, dass bei hinzufügen neuer Artikel sich die Combobox-Inhalte automatisch anpassen und der Code auch automatisch damit klar kommt.
    Jedoch zukunftsorientiert verwendbar ist das Workbook so nicht.

    Aber du könntest wenigstens die Artikel ohne Rechtschreibfehler listen.
    Begriffe wie T-Schirt, Swetshirt, Bluson werfen ein ganz übles Licht auf deine orthographischen Kenntnisse.
    Das solltest du dringend ändern, bevor das an die Öffentlichkeit geht.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Da hast du wohl Recht.

    Ich habe die Datei von jemand anderem übernommen, mir ist auch vollkommen klar das grau, blau usw. nicht groß geschrieben wird.

    In erster Linie geht es hier darum das alles funktioniert.

    Mir ist auch bewusst, das es sehr aufwändig sein wird alles zu berichtigen.

    Aber wie gesagt an erster Stelle steht die Funktion.

    Das lustige ist das diese Tabelle schon gefühlte 100 Jahre benutzt wird und noch keinem aufgefallen ist, das die Rechtschreibung "etwas" missachtet wurde.

    Was aber sehr wohl aufgefallen ist das dieses alte Formular-Dropdown viel zu lang ist... ;)
    Wenn es um meine VBA Kenntnisse geht bin ich denke ich, genauso begabt wie der Verfasser der Datei, in Sachen Rechtschreibung. Im Moment bin ich sehr daran interessiert in die Tiefen des VBA einzudringen.
    Es gibt anscheinend die Möglichkeit alles dynamisch zu gestalten. Ich bin gerne bereit mehr darüber zu erfahren.

    Mein Versuch die ComboBox1 dynamisch zu machen wäre folgender.

    Visual Basic-Quellcode

    1. ComboBox1.RowSource = Range(.Range("B1").End(xlDown), .Range("B999").End(xlUp)).Address

    Oder mit Tabellen arbeiten.

    Aber allein damit ist es nicht getan. Der VBA-Code passt sich ja nicht automatisch an. Das ist dann wahrscheinlich wieder völlig anders.

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

    Mit DynamicNameranges könnte man die CB1 füllen das leuchtet ein. Aber Mal angenommen, ich habe eine UserForm "Kleidungsstücke anlegen" mit einem Textfeld "Art der Kleidung" und einer CB "Konfektionsgröße oder Us-Größe wählen. Dann müsste ja automatisch eine neuer Namensbereich hinzugefügt werden?
    Kommt man da nicht langsam in den Bereich Datenbanken?

    Aber jetzt möchte ich erstmal noch einbauen das die Zellen nach Eingabe bzw. Bestätigung der Eingabe geleert werden.

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

    Patrick schrieb:

    Ahhh jetzt dämmert mir langsam wie der Hase läuft...
    Aus Private Property NumericCells As Range
    wird Dim NumericCells As Range.
    Das Privat Property ist also eine extra Funktion und das Dim baut die Funktion in eine Funktion ein?

    Gruß Patrick


    Property Set-Anweisungen macht man eigentlich nur um Variablen einer Klasse einen Wert zuzuweisen. In diesem Kontext kenne ich das auch nicht bzw. habe ich das noch nie so gesehen. @petaod Mich würde auch interessieren, wie das hier gemeint war.

    Visual Basic-Quellcode

    1. Private Property NumericCells As Range
    2. Set NumericCells = Range("B:B,E4,F5") 'alle Zellen, die auf numerisch abgeprüft werden sollen.
    3. End Property
    So nun für alle, die es gebrauchen können der fertige VBA-Code.

    Nächstes Ziel ist es wie von petaod richtig angemerkt, die ganze Sache Dynamisch zu gestalten.

    Visual Basic-Quellcode

    1. 'mit freundlichster Unterstützung von cry.baby https://www.vb-paradise.de/index.php/User/26665-cry-baby/ und petaod https://www.vb-paradise.de/index.php/User/7056-petaod/
    2. Private Sub ComboBox1_Change()
    3. Select Case ComboBox1
    4. Case "Bundhose grau"
    5. ComboBox2.ListFillRange = "BundhoseG"
    6. ComboBox2.ListIndex = 0
    7. Case "Bundhose Cord"
    8. ComboBox2.ListFillRange = "BundhoseC"
    9. ComboBox2.ListIndex = 0
    10. Case "Latzhose grau"
    11. ComboBox2.ListFillRange = "LatzhoseG"
    12. ComboBox2.ListIndex = 0
    13. Case "Latzhose Cord"
    14. ComboBox2.ListFillRange = "LatzhoseC"
    15. ComboBox2.ListIndex = 0
    16. 'weitere
    17. End Select
    18. End Sub
    19. If Target.Count = 1 And Not Intersect(Target, Range("E4:F4")) Is Nothing Then
    20. Dim FindeGröße As Range
    21. Dim BundhoseCord, Bundhosegrau, Latzhosegrau, LattzhoseCord As Range 'weitere
    22. Set Bundhosegrau = Range("BundhoseG")
    23. Set BundhoseCord = Range("BundhoseC")
    24. Set Latzhosegrau = Range("LatzhoseG")
    25. Set LatzhoseCord = Range("LatzhoseC")
    26. 'weitere
    27. End If
    28. End Sub
    29. Private Function Entnahme(ByVal Kleidungsstück As String, ByVal Größen As Range)
    30. Dim FindeGröße As Range
    31. 'MessageBox bei nichtnumerischer Eingabe bei Entnahme/Einlagerung aufrufen!
    32. On Error GoTo NichtNumerisch
    33. Select Case ComboBox1
    34. Case Kleidungsstück
    35. Set FindeGröße = Größen.Find(ComboBox2.Value)
    36. If Not FindeGröße Is Nothing Then
    37. FindeGröße.Offset(0, 1) = FindeGröße.Offset(0, 1) - Range("E4") + Range("F4")
    38. Range("E4:F4").ClearContents
    39. End If
    40. End Select
    41. Exit Function
    42. NichtNumerisch:
    43. MsgBox "Bitte geben Sie einen gültigen numerischen Wert für die Entnahme/Einlagerung ein!", vbCritical
    44. End Function

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

    cry.baby schrieb:

    wie das hier gemeint war
    Das war ein Typo.
    Ich sollte mir angewöhnen, den Code nicht einfach aus dem Kopf ins Forum zu schreiben, sondern vorher zu testen.

    Eigentlich war es so gemeint:

    Visual Basic-Quellcode

    1. Private Property Get NumericCells As Range
    2. Set NumericCells = Range("B:B,E4,F5") 'alle Zellen, die auf numerisch abgeprüft werden sollen.
    3. End Property
    Worksheets sind Klassenobjekte, weshalb man sie um Properties erweitern kann.
    In dem Fall ist es aber wirklich gleichbedeutend mit

    Visual Basic-Quellcode

    1. Private NumericCells As Range 'auf Klassenebene bzw. Dim innerhalb der Routine
    2. Set NumericCells = Range("B:B,E4,F5") 'alle Zellen, die auf numerisch abgeprüft werden sollen.
    Ich habe mir halt angewöhnt, innerhalb Worksheets mit Properties zu arbeiten, weil man hier halt bei Bedarf zusätzlichen Code unterbringen kann.


    Patrick schrieb:

    Aber jetzt möchte ich erstmal noch einbauen das die Zellen nach Eingabe bzw. Bestätigung der Eingabe geleert werden.
    So wie oben schon beschrieben.

    Visual Basic-Quellcode

    1. If Target.Count = 1 And Not Intersect(Target, Range("E4:F4")) Is Nothing Then
    verhindert, dass der Eintrag bei mehrzelligen Änderungen die Entnahme-Prozedur ausführt.
    Diese Abfrage scheint in deinem jetzigen Code ganz zu fehlen.
    Es ist aber wichtig, das Worksheet_Change Event einzuschränken auf die absolut notwendigen Bereiche, sonst läuft das bei jeder Zelländerung durch.
    Und nachdem du die neuen Bestände geschrieben hast, löschst du die Eingabezellen:

    Visual Basic-Quellcode

    1. Range("E4:E5").ClearContents ' ist eine mehrzellige Modifikation
    hast du ja inzwischen drin.

    Patrick schrieb:

    Nächstes Ziel ist es wie von petaod richtig angemerkt, die ganze Sache Dynamisch zu gestalten.
    was einem kompletten Umbau bedarf.
    Mal sehen, vielleicht habe ich die Tage mal Langeweile.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

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

    Patrick schrieb:

    Aber jetzt möchte ich erstmal noch einbauen das die Zellen nach Eingabe bzw. Bestätigung der Eingabe geleert werden.
    So wie oben schon beschrieben.

    Visual Basic-Quellcode

    1. If Target.Count = 1 And Not Intersect(Target, Range("E4:F4")) Is Nothing Then
    verhindert, dass der Eintrag bei mehrzelligen Änderungen die Entnahme-Prozedur ausführt.
    Diese Abfrage scheint in deinem jetzigen Code ganz zu fehlen.
    Es ist aber wichtig, das Worksheet_Change Event einzuschränken auf die absolut notwendigen Bereiche, sonst läuft das bei jeder Zelländerung durch.
    Und nachdem du die neuen Bestände geschrieben hast, löschst du die Eingabezellen:

    Visual Basic-Quellcode

    1. Range("E4:E5").ClearContents ' ist eine mehrzellige Modifikation
    hast du ja inzwischen drin.[/quote]

    Sorry mein Fehler, habe den Code aus der Falschen Datei kopiert.

    Ist jetzt geändert.
    Nun funktioniert alles.
    Bleibt die Frage der Dynamik,
    sehe ich es richtig, dass ich nur noch einen dynamischen Namen vergeben muss
    und dann die Berechnungen für neu hinzu gefügte Artikel, automatisch erfolgen kann?
    Ohne Änderungen an dem VB-Code vornehmen zu müssen?
    Ungefähr kann ich mir vorstellen wie das funktioniert.
    Namensbereich erweitert sich automatisch. Bedeutet das sich auch die CB1 automatisch mit den neuen Daten Füllt.
    Soweit so gut, funktioniert auch.
    „Klick auf Button“; neuer Artikel wird in Spalten A und B unter dem letzten Eintrag angelegt.
    Der neue Artikel wird auch in der CB1 aufgeführt.
    Nun muss ich aber jedes Mal den VB-Code anpassen um die Einträge der CB2 zu aktualisieren.
    Und die Berechnungen funktionstüchtig zu machen.
    Notwendige Anpassungen:
    Dim BundhoseCord, Bundhosegrau, „NeuerArtikel“ hinzufügen
    Neuen Namensbereich „NeuerA“ manuell erstellen,
    Set Neuerartikel = Range("NeuerA") hinzufügen
    Call Entnahme("Neuer Artikel", Neuer Artikel) hinzufügen
    In dem Sheet Übersicht den neuen Artikel anlegen.

    Wie bekomme ich das jetzt hin? Ich platze bald vor Neugier ;) .


    Gruß Patrick
    So auf Anhieb fällt mir auch nichts ein aber es wäre wohl am einfachsten, wenn Du Dein Arbeitsblatt anders aufbaust. Ganz spontan würde ich sagen, wäre es hier ggf sogar am sinnvollsten mit einer Userform zu arbeiten. Käme sowas in Frage? Das wäre aber schon ein größeres Projekt...
    Userform kommt auch in Frage. Komplettes Umbauen ist auch kein Problem.
    Habe die Angelegenheit mit dem "neuen Artikel anlegen" auch mit einer Userform gelöst. Funktioniert auch super. Klick auf Button "neuen Artikel anlegen" --> Userform öffnet sich --> name in Textfeld eintragen --> Größen per Optionbutton wählen ( US, Konfektion, Schuhe) ---> klick auf jetzt eintragen --> neuer Artikel wird in A:A angelegt und in CB1 gelistet.

    Gruß Patrick
    Das ist schon ein kompletter Umbau der Logik.
    Aber durchaus machbar.
    Ich habe vermutlich diese Woche etwas Luft und schau's mir mal an.

    Ich würde aber eher eine Variante ohne zusätzliche Userform bevorzugen.
    Das macht es nur komplizierter.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Hallo petaod,

    das sieht ja super aus. Vielen Dank für die Mühe.

    Dynamisch ist deine Lösung 100% auch habe ich mich sehr über die von dir angelegten letzten 3 Kleidungsstücke amüsiert.

    Ich frage mich allerdings ob es auch realisierbar ist das ganze etwas Übersichtlicher zu gestalten. man muss ja schon ordentlich scrollen um an das Ende zu gelangen. Natürlich könnte man die Zellen verknüpfen aber das bedeutet gleichzeitig wieder eine Menge Handarbeit nach jedem neu angelegten Artikel.

    Ich finde super das sich die Liste erweitert sobald ein neues Kleidungsstück angelegt wird. Nur passiert das erst dann wenn das erste mal eine Anzahl eingetragen wird. wenn ich als erstes Größe 60 eingebe wird auch in der liste als Erstes Gr 60 angezeigt. danach alle Größen in der Reihenfolge wie eine Anzahl eingegeben wird. Ich habe eine Idee wie ich das lösen kann.

    Sobald ich es fertig habe lade ich es hier wieder hoch. Kannst du dir gerne ansehen und deine Meinung dazu sagen.
    @petaod ich verstehe immer noch nicht ganz was die get/set-Methode der Properties hier für Vorteile hat, gegenüber einer einfachen Variablen-Deklaration. Du schreibst weiter oben, dass man bei Bedarf zusätzlichen Code unterbringen kann. Wie würde das z.B. aussehen? Danke vorab für die Erläuterung!

    Patrick schrieb:

    Natürlich könnte man die Zellen verknüpfen aber das bedeutet gleichzeitig wieder eine Menge Handarbeit nach jedem neu angelegten Artikel.
    Das ist in der Tat eine Herausforderung in Excel, weil eine Tabellenkalkulation dafür originär nicht gemacht ist.
    Du musst dir halt einen Algorithmus der Aufteilung ausdenken.
    Die Zellverknüpfungen lassen sich dann schon automatisieren.

    Patrick schrieb:

    Ich habe eine Idee wie ich das lösen kann.
    Ich habe mir auch überlegt, beim Einfügen den Bereich zu sortieren.
    Bei Nummern funktioniert das ganz gut.
    Bei Reihen wie S,M,L,XL geht's schief.

    cry.baby schrieb:

    was die get/set-Methode der Properties hier für Vorteile hat, gegenüber einer einfachen Variablen-Deklaration. Du schreibst weiter oben, dass man bei Bedarf zusätzlichen Code unterbringen kann. Wie würde das z.B. aussehen?
    Eine Property ist am ehesten mit einer Gruppe von Functions (Get, Let, Set) vergleichbar.
    Ich verwende in vielen Fällen nur den Get-Teil.
    Eine Property verwende ich immer dann, wenn sie Elemente aus dem Objekt (Worksheet) mit (z.B. einen Range) verwendet.
    Functions verwende ich dann, wenn sie für sich allein lauffähig wäre, also alle notwendigen Parameter übergeben bekommt.

    Den Sonderfall, dass die Property nur zur externen Repräsentation einer Variable verwendet wird, kannst du natürlich auch durch eine globale Variable darstellen.

    Ich weiss nicht, ob du meinen obigen Vorschlag angeschaut hast.
    Da ist die Property CurrentSizeCell ein Beispiel für zusätzlichen Code.
    Sie sucht einfach nach der Zelle für die momentan eingestellte Größe und gibt sie zurück.
    Aber wenn diese nicht existiert, wird eine neue angelegt.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

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

    petaod schrieb:


    Sie sucht einfach nach der Zelle für die momentan eingestellte Größe und gibt sie zurück.
    Aber wenn diese nicht existiert, wird eine neue angelegt.


    Wenn ich das richtig verstehe, ist es also möglich, in der CB2 eine Größe einzutippen (die nicht vorhanden ist) und diese wird dann angelegt?
    Vorausgesetzt es ist erlaubt in der CB2 zzu schreiben.
    Gruß Patrick

    Patrick schrieb:

    in der CB2 eine Größe einzutippen (die nicht vorhanden ist)
    Die ComboBox ist so konfiguriert, dass du nichts eingeben kannst, da kannst du nur auswählen.
    Du kannst aber in der Artikeltabelle eine neue Größe eintragen, dann kannst du sie sofort auswählen.
    Wenn du dann Mengen dafür einträgst, wird sie angelegt.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

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