Klassenmodul

Informationen und Beispiele zu den hier genannten Dialog-Elementen:
UserForm Calendar TextBox MsgBox
Bild

Betrifft: Klassenmodul
von: PQuest:-)
Geschrieben am: 17.10.2015 15:09:23

Hallo,
ich habe keine Ahnung von Klassenmodulen, habe aber den Verdacht, dass ich sie für mein Problem nutzen könnte.
In einem Userform befinden sich 16 txtBoxen. Neben jeder txtBox befindet sich ein kleiner Kalenderbutton, mit dem ich ein Kalenderblatt aufrufe um das Datum auszuwählen, was in die txtBox geschrieben werden soll.
Hier mal der Codeblock für eine txtBox inkl. des Kalenderbuttons:

Private Sub txtDCV_AfterUpdate()
    txtDCV = Format(txtDCV, "dd.mm.yyyy")
End Sub
Private Sub txtDCV_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    If Not IsDate(txtDCV) Then
        MsgBox prompt:="Geben Sie ein gültiges Datum ein."
        txtDCV = ""
        Cancel = True
    End If
End Sub
Private Sub txtDCV_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
    Call SF_DatePick.DatePickinCtl(Me.txtDCV)
End Sub
Private Sub btnCalendar_Click()
    Call SF_DatePick.DatePickinCtl(Me.txtDCV)
End Sub

Das kann ich jetzt natürlich 16 mal wiederholen und anpassen. Geht es einfacher? bzw. kann, und wenn ja wie, das mit einem Klassenmodul gelöst werden?
Gruß,
PQuest:-)

Bild

Betrifft: AW: Klassenmodul
von: Nepumuk
Geschrieben am: 17.10.2015 16:35:02
Hallo,
um ein Klassenmodul zu nutzen musst du für jede TextBox eine Instanz der Klasse erzeugen. Das macht man normalerweise in einer Schleife. Wenn aber jede TextBox einen eigenen Namen hat ist eine normale Schleife mehr schlecht wie recht möglich. Wenn aber jede TextBox ausnahmslos das selbe Verhalten zeigen soll dann geht's indem du per For Each alle Controls abklapperst. Also, wie sieht es aus?
Ich benenne Controls in UserForms grundsätzlich nicht um, denn ich als Programmierer weiß für was Textbox16 steht und für den normalen Anwender spielt es überhaupt keine Rolle welchen Namen das Ding hat.
Gruß
Nepumuk

Bild

Betrifft: Nachtrag
von: Nepumuk
Geschrieben am: 17.10.2015 16:46:20
Mir ist gerade noch was eingefallen,
das Exit-Event steht in Klassenmodulen nicht zur Verfügung. Ich würde auch keine Just In Time Prüfung machen sondern den Benutzer erst alle Eingaben tätigen lassen und erst beim Klick auf Übernehmen prüfen. Hat auch den Vorteil dass ich nicht alles richtig ausfüllen muss um dann auf Abbrechen klicken zu können.
Gruß
Nepumuk

Bild

Betrifft: AW: Nachtrag
von: PQuest:-)
Geschrieben am: 17.10.2015 17:21:39
Hallo Nepumuk,
ja, du als Programmierer weisst das :-). Ich als Ab-und-zu-mal-"Programmierer" bin aber froh, wenn ich den sprichwörtlichen Strohhalm in Form eines Namens habe, nach dem ich greifen kann, um mich in meinem Code zurecht zu finden.
Ich würde das Ganze gerne elegant programmieren, aber dazu fehlt leider die Zeit und vor allem das Wissen.
Nur mal ein Beispiel:

Private Sub cmdSave_Click()
'Übertragen der Daten in Tabelle
Dim lngLastRow As Long
Dim bytLastCol As Byte
Dim ws As Worksheet
Dim vntCtrl As Variant
Dim x As Byte, i As Integer, col As Byte
Set ws = Worksheets("ListOfPatients")
lngLastRow = ws.Cells(Rows.Count, 1).End(xlUp).Row
bytLastCol = ws.Cells(8, Columns.Count).End(xlToLeft).Column
'vntCtrl = Array("cbPatID", "txtPatName", "optAG1", "txtSV", "txtIDV", "txtTV1", "txtTV2", " _
txtTV3", "txtTV4", "txtTV5", "txtDCV", "txtSCV14", _
'                "txtSCV28", "txtSCV42", "txtSCV56", "txtFUS1", "txtFUS3", "txtFUS7", "txtFUS10" _
)
    If lngLastRow = 8 And Cells(8, 1) = "" Then x = 0 Else x = 1
    
    With ws
        .Cells(lngLastRow + x, 1) = cbPatID
        .Cells(lngLastRow + x, 2) = txtPatName
        .Cells(lngLastRow + x, 3) = "Agegroup?"
        .Cells(lngLastRow + x, 4) = txtSV
        .Cells(lngLastRow + x, 5) = txtIDV
        .Cells(lngLastRow + x, 6) = txtTV1
        .Cells(lngLastRow + x, 7) = txtTV2
        .Cells(lngLastRow + x, 8) = txtTV3
        .Cells(lngLastRow + x, 9) = txtTV4
        .Cells(lngLastRow + x, 10) = txtTV5
        .Cells(lngLastRow + x, 11) = txtDCV
        .Cells(lngLastRow + x, 12) = txtSCV14
        .Cells(lngLastRow + x, 13) = txtSCV28
        .Cells(lngLastRow + x, 14) = txtSCV42
        .Cells(lngLastRow + x, 15) = txtSCV56
        .Cells(lngLastRow + x, 16) = txtFUS1
        .Cells(lngLastRow + x, 17) = txtFUS3
        .Cells(lngLastRow + x, 18) = txtFUS7
        .Cells(lngLastRow + x, 19) = txtFUS10
    End With
.
.
.
End Sub
Für den Spaghetti-Code habe ich 5 Minuten gebraucht. Mein Versuch das ganze elegant über ein Array zu lösen, um es auf ein paar wenige Zeilen einzudampfen, hat mich 2 Stunden gekostet und kein Ergebnis gebracht.
Ich denke das verdeutlicht mein Dilemma ;-) Ich verstehe die Logik, aber es hapert an den Kenntnissen der Programmiervokabeln.
Also im Moment doch lieber die unschöne Holzhammerprogrammierung.
Sorry, musste mich mal ausweinen :-)
Gruß,
PQuest:-)

Bild

Betrifft: Kein Exit-Event in Klassenmodul
von: Nepumuk
Geschrieben am: 17.10.2015 18:29:33
Hallo,
ich seh schon, mit einer einfachen Schleife geht das nicht. Dann müsste man ein Array mit den Namen benutzen. Trotzdem nochmal, in einem Klassenmodul kannst du das Exit-Event nicht benutzen. Sprich du müsstest dein Konzept nochmal überdenken.
Gruß
Nepumuk

Bild

Betrifft: AW: Kein Exit-Event in Klassenmodul
von: Luschi
Geschrieben am: 17.10.2015 18:43:22
Hallo,
zeige doch mal ein kleines Beispiel mit dem Formular, dann wird Dir schon geholfen werden.
Ich bin davon abgekommen, das Beispiel auch noch selber zu erstellen.
Gruß von Luschi
aus klein-Paris

Bild

Betrifft: AW: Kein Exit-Event in Klassenmodul
von: PQuest:-)
Geschrieben am: 17.10.2015 19:05:45
Hallo Luschi,
ein kleines Beispiel gibt es nicht...nur das ganze Paket :-)
https://www.herber.de/bbs/user/100846.xlsm
In der angefügten Datei findet sich im Sheet ListOfPatients die Schaltfläche New Patient. Diese öffnet das ufShedule. Bisher ist mein Bestreben nur bei Dose Confirmation Visit umgesetzt. Hier wird durch klick auf das Symbol oder Doppelklick in das Textfeld der Datepicker geöffnet. Dieses Verhalten möchte ich auf alle Felder übertragen, die das kleine Kalender Image besitzen.
Schaut einfach mal rein ;-)
Gruß,
PQuest:-)

Bild

Betrifft: AW: Kein Exit-Event in Klassenmodul
von: PQuest:-)
Geschrieben am: 18.10.2015 11:59:17
Hallo,
also ich würde jetzt mein Konzept überdenken...dazu benötige ich aber einen Denkanstoss. Leider habe ich mich selbst mittlerweile so verwirrt, dass ich am Besten noch einmal neu anfange.
Meine erste Änderung war die, meine Textboxen, mit denen später das gleiche passieren soll, umzubenennen.
Sie heissen jetzt wieder Textbox1 bis Textbox16. Das Kalendersymbol neben der jeweiligen Textbox trägt nun den Namen ImageX. X ist hier die korrespondierende Zahl zur zugehörigen Textbox, also Image1 bis Image16.
Nun möchte ich folgendes erreichen:
1. In den Textboxen soll nur die Eingabe eines Datums erlaubt sein. Die schreibweisen 1-1-1900 und 1/1/1900 sind erlaubt, sollen aber in 01.01.1900 umgewandelt werden.
2. Doppelklick in die Textbox soll den Datepicker aufrufen und das ausgewählte Datum in die Textbox schreiben.
3. Klick auf das Kalendersymbol soll das gleiche bewirken wie Punkt 2.
Sorry für die Frageliste, aber wie schon gesagt, ich habe einen Cut gemacht und brauche jetzt etwas Starthilfe. Hier noch mal das (fast) leere Gerüst meiner Bemühungen...
https://www.herber.de/bbs/user/100851.xlsm
Kommentare sind im SourceCode eingefügt.
Wäre wirklich toll, wenn mich jemand auf das richtige Gleis setzen könnte.
Nahezu verzweifelter Gruß,
PQuest:-)

Bild

Betrifft: AW: Kein Exit-Event in Klassenmodul
von: Nepumuk
Geschrieben am: 18.10.2015 16:43:17
Hallo,
müssen immer alle Datumsboxen ausgefüllt werden?
Gruß
Nepumuk

Bild

Betrifft: AW: Kein Exit-Event in Klassenmodul
von: PQuest:-)
Geschrieben am: 18.10.2015 16:53:55
Hallo Nepumuk,
Erst mal zu deiner Frage: JA.
Es stellt sich im späteren Verlauf der Benutzung aber noch komplizierter dar.
Textbox1 bis Textbox8 werde manuell bzw. über den Datepicker gefüllt.
Textbox 9 bis Textbox 16 werden nach "Füllung" von Textbox8 berechnet, sollen aber bei Bedarf auch manuell bzw. über Datepicker befüllt werden.
Im Weiteren sind noch einige Bedingungen zur Berechnung der Daten in Textbox9 bis Textbox16 geknüpft, die zu erläutern aber ewig langen Text benötigen würden, darum verzichte ich mal darauf. Ausserdem ist das ganze nicht ganz unkritisch, was die "Veröffentlichung" angeht. Tiefergehende Fragen kann ich gerne per Mail beantworten.
Gruß,
PQuest:-)

Bild

Betrifft: AW: Kein Exit-Event in Klassenmodul
von: Nepumuk
Geschrieben am: 18.10.2015 19:31:09
Hallo,
ich hab mal ein bisschen was gemacht wie ich es lösen würde.
https://www.herber.de/bbs/user/100858.xlsm
Gruß
Nepumuk

Bild

Betrifft: AW: Kein Exit-Event in Klassenmodul
von: PQuest:-)
Geschrieben am: 18.10.2015 20:02:39
Hallo Nepumuk,
leider kann ich die Datei nicht vollumfänglich nutzen, weil ich nicht im Besitz deiner Smartcard bin...sagt mir zumindest Excel. :-)
Gruß,
PQuest:-)

Bild

Betrifft: AW: Kein Exit-Event in Klassenmodul
von: Nepumuk
Geschrieben am: 18.10.2015 20:08:34
Hallo,
du musst nur unter Extras - Digitale Signatur das Zertifikat entfernen.
Gruß
Nepumuk

Bild

Betrifft: AW: Kein Exit-Event in Klassenmodul
von: PQuest:-)
Geschrieben am: 18.10.2015 20:52:01
Hallo Nepumuk,
SUPER!
Da wäre ich alleine nie hintergekommen. Die 7 Siegel der Klassen :-)
Noch ein paar kurze Fragen:
Wenn ich jetzt noch etwas für die Textboxen ergänzen möchte...z.B. ob das berechnete Datum (TextBox9 bis TextBox16) ein Samstag ist, füge ich das in die Klasse ein, richtig?
Warum rufst du Anweisungen wie Unload me mit einem Call auf?
Ich habe eine Ergänzung für das Formular hinzugefügt:

Private Sub TextBox8_AfterUpdate()
    
    TextBox9.Value = CDate(TextBox8.Value) + 14 - 2
    TextBox10.Value = CDate(TextBox8.Value) + 28 - 2
    TextBox11.Value = CDate(TextBox8.Value) + 42 - 2
    TextBox12.Value = CDate(TextBox8.Value) + 56 - 2
End Sub
Leider ist es wohl das falsche Ereignis - zumindest wenn ich das Datum per Datepicker eingebe, dann passiert nichts und ich muss nochmal in die Zelle, eine Zahl ändern und dann werden die Werte wie gewünscht in die anderen Textboxen eingetragen wenn ich EWnter betätige. Kannst du mir sagen, woran das liegt?
Nochmal vielen Dank,
PQuest:-)

Bild

Betrifft: AW: Kein Exit-Event in Klassenmodul
von: Nepumuk
Geschrieben am: 18.10.2015 21:23:25
Hallo,
der Code muss in das Modul des UserForms, denn auch das AfterUpdate-Event steht dir in der Klasse nicht zur Verfügung. Das hat wie beim Exit-Event folgenden Grund:
Diese Events werden durch das aktivieren eines anderen Controls ausgelöst. In der Klasse existiert aber nur die TextBox.
Gruß
Nepumuk

Bild

Betrifft: AW: Kein Exit-Event in Klassenmodul
von: PQuest:-)
Geschrieben am: 18.10.2015 22:09:51
Hallo Nepumuk,
der Code steht im Modul des Userforms :-(
Gruß,
PQuest:-)

Bild

Betrifft: AW: Kein Exit-Event in Klassenmodul
von: Nepumuk
Geschrieben am: 18.10.2015 22:44:16
Hallo,
bei mir funktioniert es so:

Private Sub TextBox8_Change()
    If IsDate(TextBox8.Text) Then
        TextBox9.Value = CStr(CDate(TextBox8.Value) + 14 - 2)
        TextBox10.Value = CStr(CDate(TextBox8.Value) + 28 - 2)
        TextBox11.Value = CStr(CDate(TextBox8.Value) + 42 - 2)
        TextBox12.Value = CStr(CDate(TextBox8.Value) + 56 - 2)
    End If
End Sub

Gruß
Nepumuk

Bild

Betrifft: AW: Kein Exit-Event in Klassenmodul
von: PQuest:-)
Geschrieben am: 19.10.2015 05:05:15
Hallo,
ich dachte mir schon, dass ich das falsche Ereignis gewählte habe. Danke für die Bestätigung :-)
Hat es einen Grund, warum du aus dem Date wieder einen String machst?
Gruß,
PQuest:-)

Bild

Betrifft: AW: Kein Exit-Event in Klassenmodul
von: Luschi
Geschrieben am: 19.10.2015 06:32:29
Hallo PQuest,
Du darfst ja 3 mal raten, welche Art von Datentyp in einer Textbox hinterlegt werden können.
Gruß von Luschi
aus klein-Paris

Bild

Betrifft: AW: Kein Exit-Event in Klassenmodul
von: PQuest:-)
Geschrieben am: 19.10.2015 18:54:07
Hallo Luschi,
das ist schon klar, aber wenn ich den CSTR nicht drumpacke klappt es auch...Sind es genau diese Unsauberkeiten, die später zu Problemen führen (können)?
Gruß

Bild

Betrifft: AW: Kein Exit-Event in Klassenmodul
von: Luschi
Geschrieben am: 21.10.2015 10:37:26
Hallo PQuest,
auf Deinen Einwurf habe ich regelrecht gewartet; sicher funktioniert es auch ohne.
Aber man sollte auch nach gewisser Zeit noch den Vba-Code lesen können, ohne jedesmal
nachdenken zu müssen, welche Compiler-internen Abläufe passieren, wenn man sich nur
auf die Standards der Programmiersprache verläßt.
Beispiel:
Dim v
v = ActiveSheet.Range("A4")
Das hier die Property (Eigenschaft) 'Value' gemeint ist, kann man mit einiger Erfahrung
noch evaluieren.
Aber in großen Projekten kann diese Art der Programmierung schon ein Problem werden.
Gruß von Luschi
aus klein-Paris


Bild

Betrifft: AW: Kein Exit-Event in Klassenmodul
von: PQuest:-)
Geschrieben am: 22.10.2015 17:49:34
Zitat: Aber in großen Projekten kann diese Art der Programmierung schon ein Problem werden.
Genau das hatte ich vermutet, aber aufgrund meiner mangelnden Routine und Erfahrung muss ich so etwas immer mal wieder erfragen ;-)
Ich danke allen Beteiligten für ihre Beiträge.
Gruß,
PQuest:-)

 Bild

Beiträge aus den Excel-Beispielen zum Thema "Klassenmodul"