Microsoft Excel

Herbers Excel/VBA-Archiv

Informationen und Beispiele zum Thema CommandButton
BildScreenshot zu CommandButton CommandButton-Seite mit Beispielarbeitsmappe aufrufen
Informationen und Beispiele zum Thema Userform
BildScreenshot zu Userform Userform-Seite mit Beispielarbeitsmappe aufrufen

repetiven Code kürzen?

Betrifft: repetiven Code kürzen? von: Klaus M.
Geschrieben am: 23.09.2020 11:41:22

Hi Leute,

ich habe einen ewig langen repetiven VBA-Code fabriziert, hier ein Ausschnitt bei dem ich alles unwichtige weg gelassen habe:

Private Sub CommandButton_FA1a_Click()
myStat = "FA1a"
wks_Ausgabe.Range("G4").Value = myStat
End Sub

Private Sub CommandButton_FA1b_Click()
myStat = "FA1b"
wks_Ausgabe.Range("G4").Value = myStat
End Sub

Private Sub CommandButton_FA1c_Click()
myStat = "FA1c"
wks_Ausgabe.Range("G4").Value = myStat
End Sub

Private Sub CommandButton_FA1d_Click()
myStat = "FA1d"
wks_Ausgabe.Range("G4").Value = myStat
End Sub
Ich denke ihr seht das Muster - es soll immer der "Name" des geclickten Buttons in das Blatt übernommen werden. In Wahrheit hat der repetive Code 8 Zeilen und es sind fast 100 Buttons.

Natürlich könnte ich den Namen auch aus einer Listbox auslesen und dann weiter verwenden - aus verschiedenen Gründen möchte ich aber, dass der Name per Button ausgewählt wird.

Frage1: kann ich den Namen des geklickten Button irgendwie heraus finden? ActiveControl.Name oder sowas?
Frage2: kann ich das Click-Ereignis von 3 oder 5 oder 100 Buttons abfragen, ohne 100 Button-Private-Subs zu generieren? In Pseudocode stelle ich mir das so vor:
Sub AnyButton_clicked()
myStat = right(ActiveControl.ThatHasFocus.Name, 4)
wks_Ausgabe.Range("G4").Value = myStat
End Sub
Holzweg oder plausibel?

LG,
Klaus M.

Betrifft: AW: repetiven Code kürzen?
von: Daniel
Geschrieben am: 23.09.2020 11:56:20

Hi
Frage 2:
kann man machen.
nennt sich "Klassenprogrammierung" und ist nicht so ganz einfach (obwohl das manche behaupten, aber ich kanns nicht).
ein Beispiel findest du hier https://www.herber.de/forum/archiv/1780to1784/t1782786.htm
es gibt aber auch genügend andere Beispiele und Anleitungen in den Archiven.

als Alternativen zur Listbox gäbe es noch die Auslösung über das Steuerelement "Register".
hier könnte man die Auswahl wie übereinander oder nebeneinander stehende Buttons aussehen lassen und hätte trotzdem nur ein Steuerelement.
ein weitere Workaround um Klassen zu umgehen wäre, die Vielen Buttons als ein Bild darzustellen und über die Klickposition über dem Bild (MouseDown) zu berechnen, welcher Button geklickt wurde.

du kannst den angeklickten Button über ActiveControl als Steuerelement-Objet ermitteln.
das erlaubt es, die 8 Zeilen Code in ein eigenes Makro zu schreiben so dass es ausreicht, in den Klick-Events mit einem Einzeiler dieses Makro aufzurufen.

Gruß Daniel

Betrifft: AW: repetiven Code kürzen?
von: Klaus M.
Geschrieben am: 23.09.2020 12:08:17

Hallo Daniel,

schon besser, vielen Dank! Jetzt sieht es so aus:
Private Sub CommandButton_FA1a_Click()
Call Anmelden(Right(ActiveControl.Name, 4))
End Sub

Private Sub CommandButton_FA1b_Click()
Call Anmelden(Right(ActiveControl.Name, 4))
End Sub

[...]

Sub Anmelden(myStat As String)
wks_Ausgabe.Range("G4").Value = myStat
[... weitere 8 Zeilen Code ...]
End Sub
Ich habe zwar immer noch hunderte von Click-Ereignissen, aber es ist doch schon viel schmaler. Vielleicht mache ich mit Doppelpunkten noch Einzeiler draus:
Private Sub CommandButton_FA1a_Click(): Call Anmelden(Right(ActiveControl.Name, 4)): End Sub

Dann bleibt der relevante Code übersichtlicher - die Ereignisse sind dann halt ein riesenlanger Block, den man beim Lesen leicht überspringen kann.

Klassenmodule *nachdenkliches_Emoji* ... damit sollte ich mich dann wohl mal beschäftigen. Für heute habe ich erstmal ne Lösung, vielen Dank!

LG,
Klaus

Betrifft: AW: repetiven Code kürzen?
von: Daniel
Geschrieben am: 23.09.2020 12:21:48

Hi
ich weiß ja nicht, wie sich die einzelnen Codezeilen unterscheiden bzw nach welcher Regel sich die Buttonnamen ändern, aber wenn ein berechenbares Sytem dahinter steckt, dann kann man ggf. den Code in einem Excelblatt per Formel, die man dann nur nach unten Ziehen muss, erstellen und dann ins Codeblatt übernehmen.
wenn also der Commbandbuttonname über die Zeilennummer berechenbar ist, kannst du so auf einfachem Weg und prozessicher viele Zeilen Code erstellen.

Gruß Daniel

Betrifft: AW: repetiven Code kürzen?
von: Daniel
Geschrieben am: 23.09.2020 13:41:03

noch zwei Varianten bei 100 Buttons:

arbeite mit einem Tabellenblatt als Anwender-Interface.
a) verwende die Zellen selbst als Button über das Selection_Change- oder das BeforeDoubleClick-Event. dort kannst du über TARGET abfragen, welche Zelle geklickt wurde

b) verwende nicht ActiveX- sondern FormularFeld-Buttons.
diesen kann man ein Makro aus dem allgemeinen Modul zuordnen und für alle Buttons das gleiche Makro verwenden. in diesem Makro kann man dann über Application.Caller ermitteln, welcher Button das Makro aufgerufen hat und entsprechend reageieren.

Gruß Daniel

Betrifft: AW: repetiven Code kürzen?
von: Klaus M.
Geschrieben am: 24.09.2020 06:47:17

Ein guter Tipp! Leider sind die Buttons auf einer Userform.

Kurz erklärt: Ich habe einen Grundriss der Produktionsstraße als Hintergrundbild der Userform. Die Buttons liegen kreuz und quer ohne viel System auf diesem - jeweils mit dem Namen der dortigen Station bezeichnet.

LG,
Klaus

Betrifft: Dann rate ich dir auf jeden...
von: Case
Geschrieben am: 24.09.2020 07:24:44

Hallo Klaus, :-)

... Fall zur Klassenprogrammierung! Du brauchst um ein vielfaches weniger Code und es ist egal, ob CommandButton dazukommen oder entfernt werden - es ist keine Codeanpassung nötig. ;-)

Ein gutes Beispiel (mit CommandButton auf einer UserForm) findest du hier: ;-)

Kleine Einführung in Klassen mit Objekten...

Servus
Case

Betrifft: AW: repetiven Code kürzen?
von: Daniel
Geschrieben am: 24.09.2020 07:54:41

Hi
Es spricht nichts dagegen, das ohne Userform in einem Tabellenblatt mit Formularfeldbuttons zu machen (Vorschlag b)
Ist viel einfacher als in der Userform.
Du brauchst keine Klassenprogrammierung lernen, sondern RS reicht, dem Button das Makro über das Kontextmenü zuzuweisen.
Das geht auch in Mehrfachselektion, bzw wird beim Kopieren eines Buttons automatisch übernommen

Außerdem kannst du in einem Tabellenblatt jedes beliebige Grafikelement als Button zu verwenden, was es dir beispielsweise erlauben würde, unterschiedliche Stationstypen über unterschiedliche Grafiken darzustellen (Montagestation Rechteck, Roboter-Station Oval, Qualtätsprüfung Trapez), oder auch Gifs und Jpegs zu verwenden, oder selbst gestaltete Symbole (gruppierte Grafikelemente, z.B bei Stationen mit mehreren Mitarbeitern ein Kreis für jeden Mitarbeiter)

Außerdem hast du so Zusatzfunktionen wie Scrollen, Zoomen, Größe ändern, ausdrucken usw automatisch über das Tabellenblatt vorhanden und müssen nicht zusätzlich programmiert werden.

Gruß Daniel

Betrifft: AW: nimm 1, wenn überhaupt
von: Fennek
Geschrieben am: 23.09.2020 12:39:41

Hallo,

als Unterstützung für Daniel's Argumente: i.d.R. recht 1 Button, der zum Mausklick bewegt wird.

Oft ist es aber besser das Makro mit einem (Doppel-) Klick in eine Zelle zu starten.

Viele Buttons mit individuellem Namen anzulegen "geht gar nicht"

mfg

Betrifft: AW: repetiven Code kürzen?
von: Rolf
Geschrieben am: 23.09.2020 22:02:45

Hallo Klaus

hier mal ein kleines Beispiel mit Klassenprogrammierung.
(...kann ich auch nicht wirklich, aber ich hab mir vor Jahren mal was aus
verschiedenen Beiträgen von hier zusammengebaut und meinen Wünschen angepasst).

https://www.herber.de/bbs/user/140393.xlsm

Gruß Rolf


Beiträge aus dem Excel-Forum zum Thema "repetiven Code kürzen?"