VBA Comboboxnamen mit Zählvariable

Hallo,

Ich habe ungefähr 50 Comboboxen in Excel untereinander in einer Spalte stehen. Diese sollen eigentlich alle das Gleiche ausführen. Ich möchte aber nicht im Visual Basic 50 mal denselben Code eingeben. Ist es irgendwie möglich hinter dem Namen der Box eine Zählvariable so zu platzieren, dass man mit einer Schleife die einzelnen Comboboxen ansprechen kann???

z.B.: For i=1 to 50
If ComboBox"i" = " irgendwas" Then
Worksheets(„TABELLE1“).Cells(i, 1)= „irgendwas“
Next i

Danke im voraus

Karo

Ja das geht.
Du kannst ein Feld erstellen in dem sich alle Comboboxen befinden. Funktioniert dann genau wie ein Array und du sprichst diese wie folgt an:
ComboBox(index).Text = „Text“

mfg Andreas

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hallo Andreas,

Ja das geht.
Du kannst ein Feld erstellen in dem sich alle Comboboxen
befinden. Funktioniert dann genau wie ein Array und du
sprichst diese wie folgt an:
ComboBox(index).Text = „Text“

hast Du einen Beispielcode? Weiter unten wurde eine ähnliche Frage gestellt, ich habe das mal probiert und nicht geschafft. Mit VB6 kein Problem, aber in VBA haben die Steuerelemente scheinbar die Eigenschaft ‚Index‘ nicht. Mit VBA kenne ich mich nicht so gut aus, möchte das aber besser lernen.

Gruß, Rainer

Danke für die schnelle Antwort.
Könntest du das ein bisschen genauer beschreiben - vielleicht mit ein paar Zeilen Code?

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Ich habe ungefähr 50 Comboboxen in Excel untereinander in
einer Spalte stehen. Diese sollen eigentlich alle das Gleiche
ausführen. Ich möchte aber nicht im Visual Basic 50 mal
denselben Code eingeben. Ist es irgendwie möglich hinter dem
Namen der Box eine Zählvariable so zu platzieren, dass man mit
einer Schleife die einzelnen Comboboxen ansprechen kann???

Hi Karo, Rainer,

sicher kann man besser referenzieren aber erstmal so:

Option Explicit

Sub tt()
Dim n As Integer
With ActiveSheet.Shapes
 For n = 1 To .Count
 If .Item(n).Name Like "ComboBox\*" Then MsgBox .Item(n).Name
 Next n
End With
End Sub


Können die Comboboxen auch aus "Formular" sein? dann langt dir ein 
Code für alle Comboboxen die nun Dropdowns heißen.
mit Rechtsklick auf die Dropdowns kannste denen makro zuweisen, 
ListFillRange und LinkedCell (heißt dort anders) usw. festlegen.

Generell würde ich bei so vielen Objekten das Erzeugen, positionieren, makro zuweisen, benennen usw per Makro machen.

Sub alle()
MsgBox Application.Caller
End Sub

Gruß
Reinhard

Hallo Reinhard,

Option Explicit

Sub tt()
Dim n As Integer
With ActiveSheet.Shapes
For n = 1 To .Count
If .Item(n).Name Like „ComboBox*“ Then MsgBox
.Item(n).Name
Next n
End With
End Sub

sorry, nicht verstanden. Also … ich habe eine Userform und drei Comboboxen darauf. Mit VB6 könnte ich …

Option Explicit

Private Sub Combo1\_Click(Index As Integer)
 Me.Print Combo1(i).Text
End Sub

Private Sub Command1\_Click()
 Dim i As Integer
 For i = Combo1.LBound To Combo1.UBound
 Combo1(i).Text = Str(i)
 Next
End Sub

… in der Schleife alle Comboboxen bearbeiten.

Es gibt auch nur ein Klickereignis für alle drei Boxen gemeinsam.
Ich habe nicht verstanden, wie das mit VBA geht.

Hast Du einen funktionierenden Quellcode, der das Selbe macht, wie meiner in VB6 für VBA, den ich in die Userform einfüge, den ich laufen lassen kann und dann am Ablauf sehen, wie das funktioniert? Dann verstehe ich das eventuell auch. :smile:

Gruß, Rainer

Hallo Rainer

sorry, nicht verstanden. Also … ich habe eine Userform und
drei Comboboxen darauf. Mit VB6 könnte ich …

Option Explicit

Private Sub Combo1_Click(Index As Integer)
Me.Print Combo1(i).Text
End Sub

Private Sub Command1_Click()
Dim i As Integer
For i = Combo1.LBound To Combo1.UBound
Combo1(i).Text = Str(i)
Next
End Sub

… in der Schleife alle Comboboxen bearbeiten.

Private Sub CommandButton1\_Click()
 Dim i As Byte
 For i = 1 To 3
 MsgBox UserForm1("Combo" & i).Value
 Next
End Sub

Es gibt auch nur ein Klickereignis für alle drei Boxen
gemeinsam.
Ich habe nicht verstanden, wie das mit VBA geht.
Hast Du einen funktionierenden Quellcode, der das Selbe macht,
wie meiner in VB6 für VBA, den ich in die Userform einfüge,
den ich laufen lassen kann und dann am Ablauf sehen, wie das
funktioniert? Dann verstehe ich das eventuell auch. :smile:

Das geht auch in VBA, allerdings mit Klassenmodulen, das können nur
wenige, ich nicht :smile:
Das es geht weiß ich aber, denn ich hatte mal Code mit einem
Klassenmodul der den Klick auf einen von 56 CommandButtons auswerten
konnte, leider ist der Code im Festplattenhimmel:frowning:

Ein Hinweis, in Excel sind die Dokumentmodule „Tabelle1“, „Tabelle2“,
usw. Klassenmodule. Diese Klassenmodule haben die Ereignisse „Change“,
„SelectionChange“ usw.
Somit brauchst du ein Klassenmodul clsComboBox, dennen du dann
beliebige Ereignisse „beibringen“ kannst wie z.B. „Click“, " Chnage"
usw.
Ist zwar von Sinn und Zweck überhaupt nicht zu vergleichen aber vom
Reindenken und Code erstellen sind Klassenmdule wie rekursive Makros.
Sehr kurzer Code aber sehr lange Entwicklungszeit bei mir

Nachfolgend mal was zu Klassenmodulen für Steuerelemente.
Gruß
Reinhard

Autor: Peter Haserodt --- Aus Excel VBA - Gruppe: Klassen

Steuerelement Ereignisse - Eine nette Sache

Bevor ich lange um den heißen Brei rede, gleich das erste Beispiel:
Erstellen Sie ein Klassenmodul clsCommandButton und eine UserForm mit einem CommandButton.
Plazieren Sie diesen links oben und geben Sie der UF eine bisserl Platz.
Starten Sie dann die UF und klicken Sie ein wenig.



' \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
' Modul: clsCommandButton Typ = Klassenmodul
' \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

Option Explicit
Public WithEvents DerCmd As MSForms.CommandButton

Private Sub DerCmd\_Click()
 DerCmd.ControlTipText = "Geklickt"
 DerCmd.BackColor = vbGreen
 DerCmd.Font.Bold = Not DerCmd.Font.Bold
End Sub

Private Sub DerCmd\_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
 MsgBox "Double"
End Sub




' \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
' Modul: UserForm1 Typ = Userform
' \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

Option Explicit
Dim oCommand1 As clsCommandButton
Dim oCommand2 As clsCommandButton

Private Sub CommandButton1\_Click()
 MsgBox "Hallo"
End Sub

Private Sub UserForm\_Initialize()
 Dim oComTemp As MSForms.CommandButton
 Set oCommand1 = New clsCommandButton
 Set oCommand2 = New clsCommandButton
 Set oCommand1.DerCmd = CommandButton1
 Set oComTemp = Me.Controls.Add("Forms.CommandButton.1", "cmd" & "Test", True)
 With oComTemp
 .Left = 100
 .Top = 100
 .Height = 25
 .Width = 100
 .Caption = "Klick Mich"
 End With
 Set oCommand2.DerCmd = oComTemp
 Set oComTemp = Nothing
End Sub

Private Sub UserForm\_Terminate()
 Set oCommand1 = Nothing
 Set oCommand2 = Nothing
End Sub


Code Analyse Klassenmodul

Der Schlüsselsatz ist hier:

Public WithEvents DerCmd As MSForms.CommandButton

Das sieht ungeheuer kompliziert aus aber ist es gar nicht.
WithEvents ist einfach ein Schlüsselwort (genauso wie Dim oder Sub oder sonstwas) und man könnte es übersetzen:
Mach mit den Ereignissen was

DerCmd ist einfach ein Name den ich vergebe. Das könne auch Timbuktu sein aber dann wäre mein Code schwerer lesbar.

MSForms.CommandButton ist einfach der Typ des Controls welches ich abgreife, in unserem Fall ein CommandButton
Und davor steht, dass er zu MSForms gehört, ist einfach ein Rezept.

Dann kommen zwei Ereignisse, die ich abfangen will, nämlich das Klickereignis und das Doppelklickereignis.
(Ich weiß, Doppelklick gibt keinen Sinn bei einem cmd aber ist ja nur zur Demo)


Danach lege ich Ereignisse fest, auf die ich reagieren will.

Dies funktioniert in der Art:
Mein oben definierter Name in WithEvents und danach Underscore und Ereignis.
Aber woher soll man wissen was dort hinkommt?
Nun ganz einfach:
Man nimmt sich einfach ein Steuerelement in einer Userform und kopiert das Ereignis welches man haben will.
(Alles hinter dem Namen, inkl. Underscore)
Dann schreibt man seinen eigenen Namen und fügt noch ein, so einfach. Inklusiv der Argumente.

Vorab aber schon der Wehmutstropfen:
Es werden nur wenige Ereignisse von Steuerelementen unterstützt. Später noch mehr dazu.

Code Analyse Userform

Ich habe zwei Variablen für zwei Instanzen der Klasse:
oCommand1 und oCommand2.
Diese Sette ich in meiner Initialize auf new.
Eine kleine Zwischenbemerkung hier:

Tatsächlich könnte ich mir in Initialize das Set .. = new ... sparen, wenn ich im Deklarationsteil schreiben würde:
Dim .. as new clsCommandbutton.
Dies würde hier problemlos funzen. Aber dem ist nicht immer so. Deswegen habe ich mir weitgehend diese Reihenfolge angewöhnt. Aber die Info sollen Sie haben.



Jetzt wird es aber wirklich interessant:

Unser Ausdruck WithEvents DerCmd ... steht uns nun hier zur Verfügung, um der Klasse den CommandButton zu übergeben.

Betrachten wir es für den CommandButton1:
Set oCommand1.DerCmd = CommandButton1

Mit dieser Zeile sage ich der Instanz der Klasse, dass sie sich auf den CommandButton1 bezieht.
Es ist eigentlich immer wieder das Gleiche:
Dim oBlatt as Worksheet Set oBlatt=ActiveSheet
Hier ist es nur ein klein wenig anderer Konstrukt aber vom Prinzip her ...

Im weiteren Verlauf der Initialize erzeugen wir einen CommandButton zu Laufzeit und Setten ihn auf unsere zweite Instanz der Klasse.
Vom Prinzip her die gleiche Vorgehensweise.

Sinn und ...

Gibt es denn einen Sinn, ein Ereignis eines Steuerelementes abzufangen, welches mir sowieso in meiner UF zur Verfügung steht ( wie bei CommandButton1) ?

Nicht wirklich aber dies diente nur der Demonstration, dass es auch bei zur Entwurfszeit kreierten Steuerelementen funktioniert.

Sinn gibt das Ganze erst wirklich bei dynamisch erstellent Steuerelementen, wie aufgezeigt.
Denn dort habe ich die Ereignisse ja nicht zur Entwurfszeit zur Verfügung!

Aber aber aber ....

Bevor Sie nun wild dynamisch Steuerlemente kreieren und mit Klassen traktieren wollen:

Es werden nur wenige Ereignisse unterstützt. Zumeist Klickereignisse.
Sie müssen selbst austesten, welches Steuerelement was unterstützt.
Es gibt eine Seite, die sich mit diesen Limitationen beschäftigt, die auch sehr zu empfehlen ist:

http://www.xlam.ch/xlimits/index.htm

Zum Abschluss ein kleines Beispiel für dynamische Controls, was ich mal vor längerer Zeit für ein Forum aus Spaß geschrieben hatte.

Sie benötigen eine leere Userform (darf ruhig etwas größer sein) und das Klassenmodul clsButton:



' \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
' Modul: UserForm1 Typ = Userform
' \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

'Code by Peter Haserodt 2002
Option Explicit
Dim aCommands(100) As New clsButton

Private Sub UserForm\_Initialize()
 Dim i As Integer, obTemp As MSForms.CommandButton
 For i = 1 To 100
 Set obTemp = Me.Controls.Add("Forms.CommandButton.1", "cmd" & 1, True)
 obTemp.Width = 25
 obTemp.Height = 25
 obTemp.Left = ((i - 1) Mod 10) \* 30
 obTemp.Top = (((i - 1) - ((i - 1) Mod 10)) / 10) \* 30
 obTemp.Caption = "" & i
 obTemp.ControlTipText = "" & i
 Set aCommands(i).DieCmds = obTemp
 Next i
End Sub



' \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
' Modul: clsButton Typ = Klassenmodul
' \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

'Code by Peter Haserodt 2002
Option Explicit
Public WithEvents DieCmds As MSForms.CommandButton

Private Sub DieCmds\_Click()
 DieCmds.ControlTipText = "Geklickt"
 DieCmds.BackColor = vbGreen
 DieCmds.Font.Bold = True
End Sub

Tut mir leid, dass ist ein typischer Fall von Angabe nicht richtig durchgelesen/verstanden. Ich bin auch von VB6 ausgegangen.
Tut mir Leid.

mfg Andreas

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hallo Reinhard,

Danke! Nun habe ich ja reichlich etwas zum Arbeiten! :smile:

Ich bin gespannt, ob ich da durchsehe und eine Klasse schreiben kann, die mir die Indizierung von Steuerelementen erlaubt.

Gruß, Rainer

Danke! Nun habe ich ja reichlich etwas zum Arbeiten! :smile:
Ich bin gespannt, ob ich da durchsehe und eine Klasse
schreiben kann, die mir die Indizierung von Steuerelementen
erlaubt.

Hallo Rainer,
immer her mit Lösungscode :smile:
Nachfolgend Code den ich in der personl.xls habe. Er sorgt dafür dass jede datei, egal ob alt oder neu einen Verweis auf MS Forms 2.0 gesetzt bekommt und da irgend ein Geist (k.A. warum das geschieht,nervte halt, aber dank dem Code Thema erledigt, muss sowieso die Festplatte mal formatieren da verwurmt) das Berechnen manchmal auf manuell stellt das Berechnen immer auf Automatisch gestellt wird.
Vielleicht kannst du die Struktur ja brauchen.

In ein Klassenmodul dass den Namen clsApplication haben muss:

Option Explicit
Private WithEvents mobjApplication As Application

Public Property Set prpApplication(objApplication As Application)
 Set mobjApplication = objApplication
End Property

Private Sub mobjApplication\_NewWorkbook(ByVal Wb As Workbook)
 Call prcAddReverence(Wb)
End Sub

Private Sub mobjApplication\_WorkbookOpen(ByVal Wb As Workbook)
 Call prcAddReverence(Wb)
End Sub

In Modul1

Option Explicit

Private Const FM20\_GUID = "{0D452EE1-E08F-101A-852E-02608C4D0BB4}"

Public Sub prcAddReverence(objWorkbook As Workbook)
 Dim intIndex As Integer
 Dim blnFound As Boolean
 On Error GoTo err\_exit
 With objWorkbook.VBProject.References
 For intIndex = 1 To .Count
 If .Item(intIndex).GUID = FM20\_GUID Then
 If .Item(intIndex).IsBroken Then
 .Remove .Item(intIndex)
 Else
 blnFound = True
 End If
 End If
 Next
 If Not blnFound Then \_
 .AddFromGuid GUID:=FM20\_GUID, Major:=2, Minor:=0
 End With
 objWorkbook.Application.Calculation = xlCalculationAutomatic
 Exit Sub
err\_exit:
 MsgBox "Fehler " & CStr(Err.Number) & vbLf & \_
 vbLf & Err.Description, vbCritical, "Fehler"
End Sub

In Diese Arbeitsmappe

Option Explicit
Private objApplication As clsApplication
Private Sub Workbook\_Open()
 'Application.Caption = "Reinhard"
 Set objApplication = New clsApplication
 Set objApplication.prpApplication = Application
End Sub

Gruß
Reinhard

Hallo Reinhard,

immer her mit Lösungscode :smile:

*gg* gaaaaanz langsam … :smile: Nun lasse ich es erst mal Wochenende werden, dann schreibe ich eine Klasse (wie hast Du mir ja verraten :smile:) und schreibe dann in den Aufruf noch ‚With Events‘. In der Klasse muß ich dann die passende Stelle für ein ‚Raise event ()‘ finden … Na ja, es ist ja ein ‚vier Tage Wochenende‘. :smile:

Danke für den Code, der hilft sehr.

Gruß, Rainer

Hallo Andreas,

Ich bin auch von VB6 ausgegangen.

schade. Ich dachte Du hättest die Lösung. Weiter unten ist mir das ja auch passiert, stell Dir meine Überraschung vor, als der Button in VBA plötzlich keine Index-Eigenschaft hatte … :smile:

Dann müssen wir eben weiter suchen. Das packen wir aber noch!

Gruß, Rainer

Na ja, es ist ja ein ‚vier
Tage Wochenende‘. :smile:

In Deutschland schon, aber ich muss normal arbeiten gehen
*g*