[VBA & EXCEL 2010] Variable Userform aufrufen

Lasersword

Cadet 4th Year
Registriert
Jan. 2008
Beiträge
123
Hallo zusammen,

stehe gerade irgendwie auf dem Schlauch.
Ggf. finde ich auch nicht die richtige Syntax für die Google-Suche.

Mein Anliegen ist relativ simple

Folgender Code funktioniert einwandfrei:

Code:
Dim form As Object 
Set form = UserForm3 
form.Show 
End Sub

Wenn aber die Userform, welche ich aufrufen möchte z. B. in Range("A1") steht
bekomme ich den Bezug nicht hin.

Hintergrund:
Ich habe eine recht große Eingabeprozedur und es kann sein, dass der User einige Informationen
nicht sofort eingeben kann.
Also wollte ich ein Zwischenspeichern ermöglichen und einfach mit

Code:
Range("A1").value = me.name

die aktuelle Userform (1 - 25) wegschreiben.

Wie bekomme ich es jetzt hin, dass ich genau diese wieder aufrufen kann?

Vielen Dank im Voraus.

VG,
Lasersword
 
Ich denke du musst noch angeben von welchem Sheet die Range gelesen werden soll?
 
Das Auslesen ist das Problem nicht.

Wenn ich aber

Code:
Dim form As Object 
Set form = Range("A1").value (oder auch Sheets(1).Range("A1").value) 
form.Show 
End Sub

schreiben würde, bekomme ich eine Typenunverträglichkeit.

Eigentlich müsst ich im nur beispielhaft sagen

Code:
Dim form As Object 
Dim Maske as String

Maske = Range("A1").value

Set form = CreateObject(Maske)
form.Show 
End Sub
 
diablobase, du hast meinen Tag gerettet.

Vielen Dank. War genau dass, was ich gesucht habe.

Falls jemand Interesse hat, der Code in Kurzform lautet:

Code:
Dim Eingabe As String
Eingabe = Range("A1").Value
VBA.UserForms.Add(Eingabe).Show Modal

VG,
Lasersword
 
Hallo zusammen,

wie schon gesagt, der Code funktioniert.

Jetzt habe ich allerdings noch ein kleines Problem :freak:

Ich möchte die gespeicherten Daten beim Aufruf in die Userform zurück laden.

Dies haben mich auch mit

Code:
Private Sub UserForm_activate()

If ThisWorkbook.Sheets("Aufbau").Range("N1").Value = "UserForm3" Or _
ThisWorkbook.Sheets("Aufbau").Range("N1").Value = "UserForm4" Or _
ThisWorkbook.Sheets("Aufbau").Range("N1").Value = "UserForm5" Or _
ThisWorkbook.Sheets("Aufbau").Range("N1").Value = "UserForm6" Or _
ThisWorkbook.Sheets("Aufbau").Range("N1").Value = "UserForm7" Or _
ThisWorkbook.Sheets("Aufbau").Range("N1").Value = "UserForm8" Or _
ThisWorkbook.Sheets("Aufbau").Range("N1").Value = "UserForm9" Or _
ThisWorkbook.Sheets("Aufbau").Range("N1").Value = "UserForm10" Or _
ThisWorkbook.Sheets("Aufbau").Range("N1").Value = "UserForm11" Or _
ThisWorkbook.Sheets("Aufbau").Range("N1").Value = "UserForm12" Or _
ThisWorkbook.Sheets("Aufbau").Range("N1").Value = "UserForm13" Then
Me.cboDL.Value = ThisWorkbook.Sheets("Aufbau").Range("M41").Value
Me.txtDatumZuteilung.Value = ThisWorkbook.Sheets("Aufbau").Range("M43").Value
Me.txtDL1.Value = ThisWorkbook.Sheets("Aufbau").Range("M46").Value
Me.OptionButton3.Value = ThisWorkbook.Sheets("Aufbau").Range("M48").Value
Me.OptionButton4.Value = ThisWorkbook.Sheets("Aufbau").Range("M49").Value
Me.txtVC1.Value = ThisWorkbook.Sheets("Aufbau").Range("M51").Value
Me.txtUstID1.Value = ThisWorkbook.Sheets("Aufbau").Range("M55").Value
Me.txtUmsatzDL1.Value = ThisWorkbook.Sheets("Aufbau").Range("M57").Value
Me.txtKostenDL1.Value = ThisWorkbook.Sheets("Aufbau").Range("M59").Value
Me.txtQuote1.Value = ThisWorkbook.Sheets("Aufbau").Range("M62").Value
Me.OptionButton1.Value = ThisWorkbook.Sheets("Aufbau").Range("M64").Value
Me.OptionButton2.Value = ThisWorkbook.Sheets("Aufbau").Range("M65").Value
End If

End Sub

umsetzen können.

Problem dabei: Ich habe Comboboxen verbaut.
Wenn hier jetzt der Wert der Zelle zurück geschrieben wird (z. B.: "2"),
übernimmt er das auch.
Dropdown funktioniert nicht, weil die Combobox nicht mit ".addItem" befüllt wird.

OK, auch kein Problem, der Wert steht ja drin und könnte zur Not überschrieben werden.
Wenn ich aber auf "Weiter" klicke, scheitert es an der Plausibilitätsprüfung, da die ComboBox
angeblich nicht gefüllt ist.

Da ich beim Öffnen des Workbooks eh ein Makro aufrufe, welches u. a. die Comboboxen befüllt,
hab ich mir gedacht, mache ich das jetzt auch, bevor die Userform, welche in Spalte N1 steht geöffnet wird.

Funktioniert nicht.
Ok, dann ein Button hinterlegen, welcher die Userformen neu befüllt (Call "Makro").
Auch das funktioniert nicht.

Habt ihr einen Rat für mich?
Bin gerade etwas überfragt.

VG,
Lasersword
 
Hinein ins Blaue: nicht Activate sondern Initialize.

Wo parkst du die alten Werte? Hast du im Codeblock fürs Schließen eine Sequenz die in einem unauffälligen Blattteil die Daten parken (wir verzichte auf den Overkill das ein Datei auszuschreiben)?

Persönlich kapiere ich nicht inwiefern man ComboBoxen und DropDowan vorbelegen sollte. Es erscheint mir nach einem logischen Designfehler. Ich rufe eine UF auf um ein Ziel anzusteuern das sich dann aus einem Vorrat befülle. Was hilft mir da ein Default, der kann sichtbar im Blatt liegen.

CN8
 
Guten Morgen,

Initialize habe ich auch versucht. Funktioniert auch nicht.

Es handelt sich hierbei um eine Art "Antragsformular",
in dem Fragen beantwortet werden müssen.

Die Drop-Down-Felder bekommen dann halt die möglichen Antworten hinterlegt,
um eine spätere Auswertung vornehmen zu können (soll ja nicht jeder seine eigene Antwort formulieren).

Jetzt kommt es aber vor, dass der Kollege bei einer Frage nicht mehr weiterkommt, weil er Rücksprache
halten muss (Thema ist etwas komplexer).
Und hier wollte ich ein Zwischenspeichern ermöglichen.

Die Daten werden ein einem Tabellenblatt weggeschrieben und daraus wieder geladen.
(z. B.: Userform2.textbox1.value = Range("A25").value)

In der ComboBox wird allerdings der Wert eingetragen, die DropDown-Werte bleiben aber leer.
Um alle notwendigen Elemente zu laden (Captions und Werte) habe ich auch ein Makro geschrieben.
Dies funktioniert auch. Nur nicht, wenn ich Zwischengespeichert habe und die Userform aufrufe.
Also ein vorangestelltes "Call Daten_laden" funktioniert nicht.

Ich habe jetzt als Notlösung mit einer If-Abfrage gearbeitet.

Das ganze sieht jetzt so aus:

Code:
Private Sub Workbook_open()

'Sprache festlegen
If ThisWorkbook.Sheets("Aufbau").Range("P1").Value = "Deutsch" Then
Call Deutsch
Else
Call English
End If

'Userform anzeigen

If ThisWorkbook.Sheets("Aufbau").Range("N1").Value = "" Or _
ThisWorkbook.Sheets("Aufbau").Range("N1").Value = "UserForm1" Then
UserForm1.ScrollTop = 0
UserForm1.Show
ElseIf ThisWorkbook.Sheets("Aufbau").Range("N1").Value = "UserForm2" Then
UserForm2.Show
ElseIf ThisWorkbook.Sheets("Aufbau").Range("N1").Value = "UserForm3" Then
UserForm3.Show
ElseIf ThisWorkbook.Sheets("Aufbau").Range("N1").Value = "UserForm4" Then
UserForm4.Show
ElseIf ThisWorkbook.Sheets("Aufbau").Range("N1").Value = "UserForm5" Then
UserForm5.Show
ElseIf ThisWorkbook.Sheets("Aufbau").Range("N1").Value = "UserForm6" Then
UserForm6.Show
ElseIf ThisWorkbook.Sheets("Aufbau").Range("N1").Value = "UserForm7" Then
UserForm7.Show
ElseIf ThisWorkbook.Sheets("Aufbau").Range("N1").Value = "UserForm8" Then
UserForm8.Show
ElseIf ThisWorkbook.Sheets("Aufbau").Range("N1").Value = "UserForm9" Then
UserForm9.Show
ElseIf ThisWorkbook.Sheets("Aufbau").Range("N1").Value = "UserForm10" Then
UserForm10.Show
ElseIf ThisWorkbook.Sheets("Aufbau").Range("N1").Value = "UserForm11" Then
UserForm11.Show
ElseIf ThisWorkbook.Sheets("Aufbau").Range("N1").Value = "UserForm12" Then
UserForm12.Show
ElseIf ThisWorkbook.Sheets("Aufbau").Range("N1").Value = "UserForm13" Then
UserForm13.Show
End If
    
End Sub

Hab nur gedacht, man könnte es schicker lösen.

VG,
Lasersword
 
Was bedeutet "funktioniert nicht"? Gibt es eine Fehlermeldung oder ähnliches?
Warum fragst du im UserForm_Activate() die Namen der Userforms ab? Du weißt doch in welcher UserForm du dich befindest?
Warum rufst du in deiner aktuellen Notlösung wieder jede UserForm einzeln auf statt die Lösung zu benutzen die ich dir bei deinem ersten Problem gepostet habe?

Grundsätzlich funktioniert ein ComboBox.AddItem("irgendwas") immer, sollte am besten aber im UserForm_Initialize() gemacht werden.
Ich habe dein Szenario gerade getestet und es funktioniert problemlos.
 
Mit "VBA.UserForms.Add(Eingabe).Show Modal" habe ich doch auch gearbeitet.

War auch alles soweit in Ordnung.

Beim Zwischenspeichern schreiben ich die aktuelle Userform in Eine Spalte (N1) weg.

Bevor die UserForm (in meinem Beispiel UserForm3) aufgerufen wird, würde ich gerne
mein Makro laufen lassen, was die Label-Bezeichnungen und Combobox inhalte festlegt und
dann erst die Werte aus den einzelnen Zellen zurück läd.
Und genau dieser Befehl wird nicht ausgeführt.
Hab auch einen Button eingebaut (nach dem Motto "Bitte erstmal aktualiseren").
Aber der dort hinterlegt Call-Befehlt wird einfach nicht ausgeführt.
Ich weiß auch nicht warum.

Und ja, ich versuche in Excel etwas abzulegen, wozu man eigentlich eine Datenbank braucht.
Ist nicht so einfach zu erklären.

Warum ich vorher abfrage, welche Userform gestartet werden soll ist relativ einfach.

Wenn Userform3 gestartet wird, kann es sein, dass der User wieder zurück auf UF2 oder UF1 springt.
Für UF4 hätte ich keine Daten. Springe ich jetzt von UF3 in UF4, würde der Befehl die Auswirkung haben, Daten zu laden,
die nicht existieren. Und dann laufe ich auf einen Fehler.

Vielleicht denke ich auch einfach zu kompliziert.

Aber wie gesagt, mit Initialize hatte ich das gleiche Problem.

VG,
Lasersword
 
Hast du eventuell die Fehlermeldung deaktiviert? (Application.DisplayAlerts)
Versuche deinen Code mal mit dem Debugger durch zu gehen ob die Befehle ausgeführt werden.
Wie gesagt sollte das ComboBox.AddItem() jederzeit funktionieren, egal ob im Initialize, Activate oder einem Button.

Dein Code im Activate() dürfte eigentlich nie einen Fehler werfen, du lädst die Daten ja aus deinem Excelblatt, wenn du keine Daten für die jeweilige Form hast wird einfach "" übernommen, was ja korrekt sein sollte.

Wäre es möglich eine abgespeckte Version deiner Datei nur mit dem Code zu den UserForms hochzuladen? Dann könnte man besser verstehen wo das Problem liegt.
Meinetwegen kannst du sie mir auch per PN schicken, dann kann ich die nächsten Tage mal genauer drüberschauen.
 
Soviele If..Else Anweisungen mit vollem Code finde ich irgendwie anstrengend zu lesen und zu bearbeiten.

Hier mal optimiert mit With und Select Case Statements

Code:
Private Sub Workbook_open()
    With ThisWorkbook.Sheets("Aufbau")
        'Sprache festlegen
        If .Range("P1").Value = "Deutsch" Then
            Call Deutsch
        Else
            Call English
        End If
         
        'Userform anzeigen
        Select Case .Range("N1").Value
            Case "", "UserForm1"
                UserForm1.ScrollTop = 0
                UserForm1.Show
            Case "UserForm2"
                UserForm2.Show
            Case "UserForm3"
                UserForm2.Show
            Case "UserForm4"
                UserForm4.Show
            Case "UserForm5"
                UserForm5.Show
            Case "UserForm6"
                UserForm6.Show
            Case "UserForm7"
                UserForm7.Show
            Case "UserForm8"
                UserForm8.Show
            Case "UserForm9"
                UserForm9.Show
            Case "UserForm10"
                UserForm10.Show
            Case "UserForm11"
                UserForm11.Show
            Case "UserForm12"
                UserForm12.Show
            Case "UserForm13"
                UserForm13.Show
        End Select
    End With
End Sub

Zu deinen anderen Problemen wäre eine Beispieldatei ganz nett.
So kann ich dir leider nicht weiterhelfen.
 
Zuletzt bearbeitet:
OK, hab mal einen Test gemacht.

War heute leider etwas eingebunden.

Hab mal eine kleine Testdatei gemacht.
Vielleicht versteht ihr mich jetzt besser.

Anhang anzeigen Test.zip

Vielen Dank für eure Unterstützung.

VG,
Lasersword
 
Also fürs füllen der ComboBox mit Werten aus einem Range einfach:

Code:
Private Sub UserForm_Initialize()
    Me.cbotest.List = ThisWorkbook.Worksheets("Aufbau").Range("N2:N6").Value
End Sub

Was war sonst noch offen?
Wird mir irgendwie hier in den ganzen Beiträgen nicht wirklich klar. Sorry.
 
Entferne mal "UserForm1" in der Spalte N1.

Dann Starte die Datei.
Du wirst sehen, dass die ComboBox gefüllt ist.

Wenn der Wert aber beibehalten bleibt, wird die ComboBox nicht gefüllt.
Die Frage ist: Warum?
 
Das einfachste und sinnvollste ist es den Code in die Form zu verschieben und im UserForm_Initialize() aufzurufen.
Alles andere finde ich auch höchst unsauber und unübersichtlich.
Code:
Sub English()
    Dim ws As Worksheet
    
    Set ws = ThisWorkbook.Sheets("Aufbau")
    ws.Range("P1").Value = "English"
    
    Me.Label1.Caption = ws.Range("H2").Value
    Me.Label2.Caption = ws.Range("H3").Value
    Me.Label3.Caption = ws.Range("H4").Value
    
    Call Me.cbotest.Clear
    With Me.cbotest
        .AddItem ws.Range("H5").Value
        .AddItem ws.Range("I5").Value
        .AddItem ws.Range("J5").Value
        .AddItem ws.Range("K5").Value
        .AddItem ws.Range("L5").Value
    End With
End Sub

Sub Deutsch()
    Dim ws As Worksheet
    
    Set ws = ThisWorkbook.Sheets("Aufbau")
    ws.Range("P1").Value = "Deutsch"
    
    Me.Label1.Caption = ws.Range("C2").Value
    Me.Label2.Caption = ws.Range("C3").Value
    Me.Label3.Caption = ws.Range("C4").Value
    
    Call Me.cbotest.Clear
    With Me.cbotest
        .AddItem ws.Range("C5").Value
        .AddItem ws.Range("D5").Value
        .AddItem ws.Range("E5").Value
        .AddItem ws.Range("F5").Value
        .AddItem ws.Range("G5").Value
    End With
End Sub

Private Sub UserForm_Initialize()
    If ThisWorkbook.Sheets("Aufbau").Range("P1").Value = "Deutsch" Then
        Call Deutsch
    Else
        Call English
    End If
End Sub
Deine Frage warum das passiert kann ich dir mit dem vollständigen Code jetzt auch ganz einfach beantworten:
Wenn Zelle "N1" leer ist öffnest du die vorher implizit erstellte Instanz des Objektes "UserForm1" mit:
Code:
UserForm1.Show
Wenn die Zelle "N1" befüllt ist erstellst du anhand des Namens (also eines Strings) eine neue Instanz des Objekts "UserForm1", also ohne den Änderungen die du vorher gemacht hast.
Code:
VBA.UserForms.Add(Eingabe).Show Modal
Zugegebenermaßen ist das in VBA leider nicht immer ganz transparent, daher sollte Code der Forms befüllt/ändert am besten immer in der Form selbst aufgerufen wurden (Initialize oder Activate).

Ich hoffe das ist so verständlich.
 
Danke für die Info.

Zugegebenermaßen ist das ganz Konstrukt etwas unübersichtlich.

Mein Problem bestand ja eigentlich darin, dass ich

1. Die Elemente der Userformen befüllen muss (deutsch und englisch)
2. Vorhandene Comboboxen mit ".AddItem" befüllen muss (jeweils deutsch und englisch)
3. Ein Zwischenspeichern ermöglicht werden soll, wo die Daten in die Tabelle übertragen werden
beim Wiederaufnehmen zurück geladen werden.

Und wie ich Gestern im Meeting erfahren habe, wurden Entscheidungen getroffen,
die dafür sorgen, dass ich alles nochmal umbauen darf :grr:

Wenn ich dich also richtig verstanden habe, würde in der Userform1 die Combobox gefüllt werden,
aber dadurch, dass ich einen neue Instanz der Userform1 starte, läuft der Befehl ins Leere?

Vielen Dank für eure Unterstützung.

VG,
Lasersword
 
Also, zu Deiner hauptsächlichen Frage, warum bleibt die Drop-Down box leer. Momentan versuchst Du in deinen Subs Deutsch und Englisch die box zu befüllen. Leider bleibt das Object UserForm1 nicht im Speicher erhalten und wenn Du dann UserForm1.Show nach Beendigung dieser beiden Subs aufrufst, ist die Dropdown-Box leer, da hier ein neues Object im Speicher erzeugt wird.

Wenn Du jetzt dein Program soweit abänderst, dass in den Subs Deutsch und English jeweils am Ende ein UserForm1.Show auftaucht, funktioniert es :-)

Was den Rest angeht, verstehe ich nocht nicht so ganz was Du erreichen willst. Vielleicht hab ich auch nicht genau gelesen :-) In welcher Situation kommt Sub Userform_aufrufen() zum tragen?
 
Zurück
Oben