{"id":55000310,"date":"2016-02-01T00:00:00","date_gmt":"2020-01-24T15:59:32","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=310"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Klassenmodule_und_benutzerdefinierte_Typen","status":"publish","type":"post","link":"https:\/\/access-basics.de\/index.php\/Klassenmodule_und_benutzerdefinierte_Typen.html","title":{"rendered":"Klassenmodule und benutzerdefinierte Typen"},"content":{"rendered":"<p class='introduction'>Die allermeisten Prozeduren und Funktionen des VBA-Projekts Ihrer Datenbank werden Sie in ganz normalen Modulen unterbringen. Dabei wird leicht &uuml;bersehen, dass es sich etwa bei Formularen um eine andere Art Module handelt, n&auml;mlich um Klassenmodule. Diese k&ouml;nnen Sie aber auch selbst anlegen. Erfahren Sie hier, wie Sie dabei vorgehen. Wir leiten das Thema zun&auml;chst jedoch mit den benutzerdefinierten Typen ein, welche Klassenmodule verst&auml;ndlicher machen.<\/p>\n<h2>Beispieldatenbank<\/h2>\n<p>Die Beispiele dieses Artikels finden Sie in der Datenbank <b>1601_Klassenmodule.accdb<\/b><\/p>\n<h2>Benutzerdefinierte Typen<\/h2>\n<p>Ein benutzerdefinierter Typ ist nichts weiter, als eine zusammengefasste Struktur von Variablen.<\/p>\n<p>Interessanterweise findet man Beispiele daf&uuml;r im VBA-Objektkatalog weder in der Access-Bibliothek, noch unter den VBA- oder Office-Bibliotheken. Also stellen wir gleich eine eigene Kreation vor:<\/p>\n<pre><span style=\"color:blue;\">Public <\/span>Type TAdresse\r\n     ID<span style=\"color:blue;\"> As Long<\/span>\r\n     Nachname<span style=\"color:blue;\"> As String<\/span>\r\n     Vorname<span style=\"color:blue;\"> As String<\/span>\r\n     Strasse<span style=\"color:blue;\"> As String<\/span>\r\n     PLZ<span style=\"color:blue;\"> As String<\/span>\r\n     Ort<span style=\"color:blue;\"> As String<\/span>\r\nEnd Type<\/pre>\n<p>Der reservierte Begriff <b>Type<\/b> definiert, dass unter dem folgenden Namen <b>TAdresse<\/b> eine Variablenstruktur folgt. Solche Typen k&ouml;nnen im G&uuml;ltigkeitsbereich auch mit <b>Private<\/b> gekennzeichnet sein, was sie nur f&uuml;r das Modul zugreifbar macht, in dem sich die Deklaration befindet. <b>Public<\/b> bedeutet hier, dass nun das gesamte VBA-Projekt den Typen kennt und auch aus anderen Modulen heraus verwendet werden kann.<\/p>\n<p>Die einzelnen Variablen des Typs werden in den folgenden Zeilen durch Namen und Variablentypen definiert. Jeglicher Datentyp ist hier m&ouml;glich &#8211; etwa auch <b>As Object<\/b>. <\/p>\n<p>Wozu ist das gut Kann man die Elemente der Struktur nicht auch als einzelne Variablen deklarieren Es gibt sicher viele F&auml;lle, f&uuml;r die die Antwort hier Ja lautet. Doch schauen wir uns an, welche Vorteile der benutzerdefinierte Typ bietet. Denn er verh&auml;lt sich genau so, wie jeder andere Datentyp. Also kann er einer Variablen zugeordnet werden:<\/p>\n<pre><span style=\"color:blue;\">Dim <\/span>A<span style=\"color:blue;\"> As <\/span>TAdresse<\/pre>\n<p>Der Zugriff auf die Elemente des Typs geschieht &uuml;ber Punkt und Namen:<\/p>\n<pre>A.Nachname = \"Minhorst\"\r\nA.Vorname = \"Andr&eacute;\"\r\nA.Ort = \"Duisburg\"\r\n<span style=\"color:blue;\">Debug.Print<\/span> A.Nachname<\/pre>\n<p>Der Code l&auml;sst sich noch &uuml;ber die <b>With<\/b>-Anweisung vereinfachen:<\/p>\n<pre><span style=\"color:blue;\">With<\/span> A\r\n     .Nachname = \"Minhorst\"\r\n     .Vorname = \"Andr&eacute;\"\r\n     .Ort = \"Duisburg\"\r\n     <span style=\"color:blue;\">Debug.Print<\/span> .Nachname\r\nEnd <span style=\"color:blue;\">With<\/span><\/pre>\n<p>Das w&auml;re schon einmal Vorteil Nummer eins. Nach Eingabe von <b>A<\/b> und Punkt stellt das <b>IntelliSense<\/b> von VBA gleich alle Elemente des Typs in der Auswahlliste vor. Und das &uuml;brigens auch innerhalb des <b>With<\/b>-Blocks, wo allein die Punkt-Eingabe f&uuml;r das Ausl&ouml;sen von <b>IntelliSense<\/b> ausreicht.<\/p>\n<p>Besonders n&uuml;tzlich sind benutzerdefinierte Typen jedoch dann, wenn Sie in Arrays Verwendung finden:<\/p>\n<pre><span style=\"color:blue;\">Dim <\/span>Adressen()<span style=\"color:blue;\"> As <\/span>TAdresse\r\nReDim Adressen(99)\r\nAdressen(0).Nachname = \"Minhorst\"\r\nAdressen(0).Vorname = \"Andr&eacute;\"\r\nAdressen(1).Nachname = \"Trowitzsch\"\r\nAdressen(1).Vorname = \"Sascha\"\r\n...<\/pre>\n<p>Das Array <b>Adressen<\/b> ist vom Typ <b>TAdresse<\/b>. Es wird im ersten Schritt auf Hundert Elemente dimensioniert. Danach folgt die Zuweisung der Werte einerseits &uuml;ber die Indizes des Arrays, andererseits &uuml;ber den Namen der Elemente. Wollte man das &uuml;ber separate Variablen erreichen, so ben&ouml;tigte man f&uuml;r jedes Element des Typs ein eigenes gesondertes Array. Das machte die Angelegenheit deutlich un&uuml;berschaubarer, als es das Handling mit einem Array des benutzerdefinierten Typs erlaubt.<\/p>\n<p>Die Sache l&auml;sst sich noch weiterspinnen. Durch den Fakt, dass ein Typelement Variablen beliebigen Datentyps aufweisen darf, kommt f&uuml;r dieses selbst ein benutzerdefinierter Typ infrage:<\/p>\n<pre><span style=\"color:blue;\">Public <\/span>Type TAdressen\r\n     Items()<span style=\"color:blue;\"> As <\/span>TAdresse\r\nEnd Type<\/pre>\n<p>Zwar enth&auml;lt der Typ nur ein Element, welches jedoch als Array des benutzerdefinierten <b>TAdresse<\/b> ausgelegt ist. Damit ist nur eine Variable vom Typ <b>TAdressen<\/b> imstande mehrere Adressen zu speichern:<\/p>\n<pre><span style=\"color:blue;\">Dim <\/span>A<span style=\"color:blue;\"> As <\/span>TAdressen\r\nReDim A.Items(99)\r\n<span style=\"color:blue;\">With<\/span> A\r\n     .Items(0).Nachname = \"Minhorst\"\r\n     .Items(0).Vorname = \"Andr&eacute;\"\r\n     .Items(1).Nachname = \"Trowitzsch\"\r\n     .Items(1).Vorname = \"Sascha\"\r\n    ...\r\nEnd <span style=\"color:blue;\">With<\/span>\r\n<span style=\"color:blue;\">Debug.Print<\/span> A.Items(1).Vorname<\/pre>\n<p>Auch hier f&uuml;hrt der benutzerdefinierte Typ zu strukturierterer Programmierung. Treiben wir es noch einen Schritt weiter. Es l&auml;gen etwa Adressen f&uuml;r verschiedene Anwendungsbereiche vor, seien es Kundenadressen, Ansprechpartner, Beh&ouml;rden, Firmen.<\/p>\n<p>Dann k&ouml;nnten alle Adressen zusammen wiederum in einen neuen Typ &uuml;berf&uuml;hrt werden:<\/p>\n<pre><span style=\"color:blue;\">Public <\/span>Enum eAddressType\r\n     eAddressUnspecific = 0 \r\n     eAddressCustomer = 1\r\n     eAddressPartner = 2\r\n     eAddressCompany = 3\r\nEnd Enum\r\n<span style=\"color:blue;\">Public <\/span>Type TAdressenGesamt\r\n     AddressType<span style=\"color:blue;\"> As <\/span>sAddressType\r\n     AddressBlock<span style=\"color:blue;\"> As <\/span>TAdressen\r\nEnd Type<\/pre>\n<p>Die Zuordnung der Werte wird nun zwar etwas l&auml;nglich, ist aber dennoch gut zu &uuml;berblicken:<\/p>\n<pre><span style=\"color:blue;\">Dim <\/span>A()<span style=\"color:blue;\"> As <\/span>TAdressenGesamt\r\nReDim A(3)\r\nA(1).AddressType = eAddressCustomer\r\nRedim A(1).AdressBlock.Items(9)\r\n<span style=\"color:blue;\">With<\/span> A(1).AdressBlock\r\n    .Items(0).Nachname = \"Minhorst\"\r\n    .Items(0).Vorname = \"Minhorst\"\r\n    .Items(1).Nachname = \"Trowitzsch\"\r\n    .Items(1).Vorname = \"Sascha\"\r\n     ...\r\nEnd <span style=\"color:blue;\">With<\/span>\r\nA(2).AddressType = eAddressUnspecific\r\nRedim A(2).AdressBlock.Items(9)\r\n<span style=\"color:blue;\">With<\/span> A(2).AdressBlock\r\n    .Items(0).Nachname = \"H&auml;berle\"\r\n    .Items(0).Vorname = \"Adam\"\r\n    .Items(1).Nachname = \"Gutschmidt\"\r\n    .Items(1).Vorname = \"Andrea\"\r\n     ...\r\nEnd <span style=\"color:blue;\">With<\/span>\r\n...<\/pre>\n<p>Immerhin haben wir nun mehrere Adressbl&ouml;cke unterschiedlichen Umfangs und Typs in einer Variablen vereint! Das einzig hinderlich ist die Notwendigkeit, die <b>Items<\/b>-Arrays jeweils neu zu dimensionieren. Das lie&szlig;e sich mit einer festen Anzahl von Elementen umgehen:<\/p>\n<pre><span style=\"color:blue;\">Public <\/span>Type TAdressen\r\n     Items(99)<span style=\"color:blue;\"> As <\/span>TAdresse\r\nEnd Type<\/pre>\n<p>Damit l&auml;ge die Maximalzahl von Adressen f&uuml;r einen Block bei Hundert. Probleme gibt stellen sich also ein, wenn doch mehr ben&ouml;tigt w&uuml;rden. Und bei kleinerer Anzahl w&uuml;rde au&szlig;erdem Speicherplatz vergeudet. Dieses Beispiel sollte eigentlich nur eines demonstrieren, n&auml;mlich wie sich benutzerdefinierte Typen im Interesse von Strukturierung verschachteln lassen. Das Ganze geht in Richtung Objektorientierter Programmierung, mit der wir es sp&auml;ter bei den Klassenmodulen noch mehr zu tun bekommen.<\/p>\n<h2>Tabellendaten in benutzerdefinierten Typen<\/h2>\n<p>Damit es nicht bei trockener Theorie bleibt, folgt ein Beispiel, das in der einen oder anderen Datenbank durchaus vertreten sein kann. Es geht hier darum, die Datens&auml;tze einer Tabelle oder Abfrage in VBA-Strukturen zu &uuml;berf&uuml;hren.<\/p>\n<p>Listing 1 zeigt das Grundger&uuml;st mit der Prozedur <b>TestUDT<\/b>. Nebenbei erw&auml;hnt ist <b>UDT<\/b> das K&uuml;rzel f&uuml;r einen benutzerdefinierten Typ (<b>User Defined Type<\/b>). Eine Datensatzgruppe <b>rs<\/b> wird auf alle Datens&auml;tze der Tabelle <b>tblAdressen<\/b> ge&ouml;ffnet. In einer <b>Do-Loop<\/b>-Schleife werden sie alle durchlaufen und die einzelnen Feldinhalte den Elementen der Variablen <b>T<\/b> des Typs <b>TAdresse<\/b> verabreicht. Da mache Felder der Datens&auml;tze leer sind und <b>Leer<\/b> nicht in einem String gespeichert werden kann &#8211; Strasse ist etwa vom Typ <b>String<\/b> &#8211; m&uuml;ssen die Werte noch einer Vorbehandlung mit der Funktion <b>Nz<\/b> unterzogen werden, die aus Nullwerten ordnungsgem&auml;&szlig;e Strings der L&auml;nge 0 macht.<\/p>\n<pre><span style=\"color:blue;\">Sub <\/span>TestUDT()\r\n     <span style=\"color:blue;\">Dim <\/span>rs<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n     <span style=\"color:blue;\">Dim <\/span>T<span style=\"color:blue;\"> As <\/span>TAdresse\r\n     \r\n     <span style=\"color:blue;\">Set<\/span> rs = CurrentDb.OpenRecordset(\"SELECT * FROM tblAdressen\", dbOpenDynaset)\r\n     <span style=\"color:blue;\">Do While<\/span> <span style=\"color:blue;\">Not<\/span> rs.EOF\r\n         <span style=\"color:blue;\">With<\/span> T\r\n             .ID = rs!ID.Value\r\n             .Nachname = Nz(rs!Nachname.Value)\r\n             .Vorname = Nz(rs!Vorname.Value)\r\n             .Strasse = Nz(rs!Strasse.Value)\r\n             .PLZ = Nz(rs!PLZ.Value)\r\n             .Ort = Nz(rs!Ort.Value)\r\n         End <span style=\"color:blue;\">With<\/span>\r\n         rs.Move<span style=\"color:blue;\">Next<\/span>\r\n     <span style=\"color:blue;\">Loop<\/span>\r\n     rs.Close\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p class='imagetext'>Listing 1: Hier werden die Daten der Tabelle tblAdressen hintereinander in einer Variablen T des benutzerdefinierten Typs TAdressen abgespeichert<\/p>\n<p>Viel Sinn macht das Beispiel nicht. Schlie&szlig;lich landen alle Daten in der einen Variablen <b>T<\/b> und &uuml;berschreiben sich damit bei jedem Schleifendurchlauf. In Listing 2 ist die Routine aufgebohrt und um den Typ <b>TAdressen<\/b> erweitert, welcher, wie bereits weiter oben dargestellt, mehrere Adressen aufnehmen kann. Die <b>Items<\/b> des Typs <b>T<\/b>, also die einzelnen Adressen, m&uuml;ssen zun&auml;chst auf die Zahl der Datens&auml;tze des Recordsets dimensioniert werden. Sie erhalten diese &uuml;ber die Methode <b>RecordCount<\/b>, nachdem Sie den Daten-Cursor &uuml;ber <b>MoveLast<\/b> einmal auf das Ende der Datens&auml;tze einstellen. Da das Array <b>Items<\/b> nullbasiert ist, muss die Obergrenze auf <b>RecordCount &#8211; 1<\/b> festgelegt werden. In der folgenden <b>Do-Loop<\/b>-Schleife wird auf eine Adresse nun &uuml;ber den Array-Index <b>i<\/b> Bezug genommen, wobei <b>T.Items(i)<\/b> als Spezifikation des <b>With<\/b>-Blocks dient. Die Z&auml;hlervariable <b>i<\/b> wird nach erfolgtem <b>MoveNext<\/b> innerhalb der Schleife erh&ouml;ht. Im Endergebnis haben Sie damit alle Datens&auml;tze der Tabelle in der einen Variablen <b>T<\/b>.<\/p>\n<pre><span style=\"color:blue;\">Sub <\/span>TestUDTArray()\r\n     <span style=\"color:blue;\">Dim <\/span>rs<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n     <span style=\"color:blue;\">Dim <\/span>T<span style=\"color:blue;\"> As <\/span>TAdressen\r\n     <span style=\"color:blue;\">Dim <\/span>i<span style=\"color:blue;\"> As Long<\/span>\r\n     \r\n     <span style=\"color:blue;\">Set<\/span> rs = CurrentDb.OpenRecordset(\"SELECT * FROM tblAdressen\", dbOpenDynaset)\r\n     rs.MoveLast: rs.MoveFirst\r\n     ReDim T.Items(rs.RecordCount - 1)\r\n     <span style=\"color:blue;\">Do While<\/span> <span style=\"color:blue;\">Not<\/span> rs.EOF\r\n         <span style=\"color:blue;\">With<\/span> T.Items(i)\r\n             .ID = i\r\n             .Nachname = Nz(rs!Nachname.Value)\r\n             .Vorname = Nz(rs!Vorname.Value)\r\n             .Strasse = Nz(rs!Strasse.Value)\r\n             .PLZ = Nz(rs!PLZ.Value)\r\n             .Ort = Nz(rs!Ort.Value)\r\n         End <span style=\"color:blue;\">With<\/span>\r\n         rs.MoveNext: i = i + 1\r\n     <span style=\"color:blue;\">Loop<\/span>\r\n     rs.Close\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p class='imagetext'>Listing 2: Hier kommt der benutzerdefinierte Typ TAdressen zum Tragen<\/p>\n<p>Was damit dann anstellen, ist ein anderes Thema. Beispiel w&auml;re etwa das Abspeichern in eine Textdatei. Tats&auml;chlich lassen sich Variablen eines benutzerdefinierten Typs &uuml;ber nur eine einzige Zeile exportieren. Sie k&ouml;nnten die Routine von Listing 2 am Ende mit diesen Zeilen erweitern:<\/p>\n<pre><span style=\"color:blue;\">Dim <\/span>F<span style=\"color:blue;\"> As Integer<\/span>\r\nF = FreeFile\r\nOpen \"c:\\daten\\tabelle.txt\" For Binary<span style=\"color:blue;\"> As <\/span>F\r\nPut F,, T\r\nClose F<\/pre>\n<p>Mit der dergestalt exportierten Textdatei kann allerdings kein anderes Programm etwas anfangen. Sie l&auml;sst sich aber analog in einem VBA-Programm einlesen, das den Typ <b>TAdressen<\/b> kennt; sinngem&auml;&szlig;:<\/p>\n<pre><span style=\"color:blue;\">Dim <\/span>T<span style=\"color:blue;\"> As <\/span>TAdressen\r\nGet F,, T<\/pre>\n<h2>Klassenmodule<\/h2>\n<p>Recht grundlos fristen Klassenmodule unter VBA ein Nischendasein. Entweder wird der Umgang mit ihnen immer wieder als kompliziert dargestellt, oder aber der Nutzen in Frage gestellt. Schlie&szlig;lich l&auml;sst sich mit den normalen Modulen dasselbe bewerkstelligen Dem ist aber nicht so. Grund genug, sich einmal deren Grundlagen zu widmen.<\/p>\n<p>Rein mechanisch f&uuml;gen Sie Ihrer Datenbank ein Klassenmodul hinzu, indem Sie den gleichnamigen Button im <b>Ribbon<\/b> unter der Registerseite <b>Erstellen<\/b> anklicken, oder, alternativ, im <b>Projekt-Explorer <\/b>der VBA-Umgebung und das Kontextmen&uuml; <b>Einf&uuml;gen | Klassenmodul<\/b> bet&auml;tigen. Bei Speichern vergeben Sie dem Modul einen Namen. Es hat sich eingeb&uuml;rgert, hier ein abweichendes Pr&auml;fix zu verwenden. Versieht man normale Module meist mit dem Pr&auml;fix <b>mod<\/b> oder <b>mdl<\/b>, so kommt hier eher ein <b>cls<\/b> oder schlicht <b>C<\/b> zum Einsatz. Ist das Thema des Klassenmoduls die Verwaltung von Adressen, so verwenden Sie etwa <b>clsAdressen<\/b>.<\/p>\n<p>Vom programmtechnischen Standpunkt aus unterscheidet sich ein Klassenmodul nicht von normalen Modulen. Es existiert lediglich eine kleine Erweiterung, das Event, auf welches wir noch zu sprechen kommen. Der Unterschied besteht vielmehr darin, dass ein Klassenmodul eben eine Klasse zur Verf&uuml;gung stellt, w&auml;hrend normale Module eine Sammlung von allgemein verwendbaren Funktionen verzeichnet. Die Methoden der Klasse k&ouml;nnen aber nicht direkt aufgerufen werden. Eine Klasse ist n&auml;mlich lediglich der Bauplan f&uuml;r ein <b>Objekt<\/b>! Ein <b>Objekt<\/b> stellt eine <b>Instanz<\/b> einer Klasse dar, welche erst per <b>New<\/b>-Anweisung erzeugt werden muss, um an die Funktionen der Klasse zu kommen:<\/p>\n<pre><span style=\"color:blue;\">Dim <\/span>C<span style=\"color:blue;\"> As <\/span>clsAdressen\r\n<span style=\"color:blue;\">Set<\/span> C = <span style=\"color:blue;\">New<\/span> clsAdressen<\/pre>\n<p>oder einfach<\/p>\n<pre><span style=\"color:blue;\">Dim <\/span>C<span style=\"color:blue;\"> As <\/span><span style=\"color:blue;\">New<\/span> clsAdressen<\/pre>\n<p>&uuml;ber <b>C<\/b> gelangen Sie dann an die Methoden der Klasse. &auml;hnlich, wie beim benutzerdefinierten Typ, zeigt <b>IntelliSense<\/b> die Methoden der Klasse, wenn Sie einen Punkt hinter die Variable setzen. Enthielte die Adressenklasse eine Prozedur <b>FindeNachnamen<\/b>, so riefen Sie jene auf diese Weise auf:<\/p>\n<pre>C.FindeNachname<\/pre>\n<p>Der Umstand, dass Klassenmodule erst auf dem Umweg &uuml;ber deren Instanziierung ansprechbar werden, macht sie wahrscheinlich unbeliebt, ist doch der Aufwand h&ouml;her, als bei normalen Modulfunktionen.<\/p>\n<p>Es gibt an anderer Stelle ersch&ouml;pfende Darlegungen &uuml;ber Klassen, Objekte, Instanziierung und objektorientierte Programmierung. Da viele der Charakteristiken von Objektstrukturen unter VBA jedoch nicht implementiert sind, lassen wir es f&uuml;r den Anfang bei einigen grundlegenden Erl&auml;uterungen.<\/p>\n<p>Ein Schlagwort bei Klassen ist <b>Kapselung<\/b>. Dadurch, dass eine Klasse erst dezidiert &uuml;ber eine Variable instanziiert werden muss, kapselt sich deren Funktionalit&auml;t und schottet den Zugriff im Vergleich zu normalen Modulen ab. Die Methoden sind nur Teil des Objekts und damit nicht generell verf&uuml;gbar.<\/p>\n<p>Deshalb eignet sich eine Klasse und deren Objekt auch f&uuml;r die Aufnahme von Daten. Nicht zuf&auml;llig hatten wir es eingangs mit benutzerdefinierten Objekten zu tun. <b>UDT<\/b>-Variablen sind h&auml;ufig &ouml;ffentlich ansprechbar und damit unsicherer, als ein Objekt.<\/p>\n<h2>Container-Klassen<\/h2>\n<div class=\"rcp_restricted\"><p><span style=\"color: #ff0000;\">M&ouml;chten Sie weiterlesen? Dann l&ouml;sen Sie Ihr Ticket!<\/span><br \/>\n<span style=\"color: #ff0000;\">Hier geht es zur Bestellung des Jahresabonnements des Magazins <strong>Access &#091;basics&#093;<\/strong>:<\/span><br \/>\n<span style=\"color: #ff0000;\"><a style=\"color: #ff0000;\" href=\"https:\/\/shop.minhorst.com\/magazine\/282\/access-basics?c=77\">Zur Bestellung ...<\/a><\/span><br \/>\n<span style=\"color: #ff0000;\">Danach greifen Sie sofort auf <strong>alle rund 400 Artikel<\/strong> unseres Angebots zu - auch auf diesen hier!<\/span><br \/>\n<span style=\"color: #000000;\">Oder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein:<\/span><\/p>\n<\/div>\n\n\t\n\t<form id=\"rcp_login_form\"  class=\"rcp_form\" method=\"POST\" action=\"https:\/\/access-basics.de\/data\/wp\/v2\/posts\/55000310\/\">\n\n\t\t\n\t\t<fieldset class=\"rcp_login_data\">\n\t\t\t<p>\n\t\t\t\t<label for=\"rcp_user_login\">Username or Email<\/label>\n\t\t\t\t<input name=\"rcp_user_login\" id=\"rcp_user_login\" class=\"required\" type=\"text\"\/>\n\t\t\t<\/p>\n\t\t\t<p>\n\t\t\t\t<label for=\"rcp_user_pass\">Password<\/label>\n\t\t\t\t<input name=\"rcp_user_pass\" id=\"rcp_user_pass\" class=\"required\" type=\"password\"\/>\n\t\t\t<\/p>\n\t\t\t\t\t\t<p>\n\t\t\t\t<input type=\"checkbox\" name=\"rcp_user_remember\" id=\"rcp_user_remember\" value=\"1\"\/>\n\t\t\t\t<label for=\"rcp_user_remember\">Remember me<\/label>\n\t\t\t<\/p>\n\t\t\t<p class=\"rcp_lost_password\"><a href=\"\/index.php\/data\/wp\/v2\/posts\/55000310?rcp_action=lostpassword\"><\/a><\/p>\n\t\t\t<p>\n\t\t\t\t<input type=\"hidden\" name=\"rcp_action\" value=\"login\"\/>\n\t\t\t\t\t\t\t\t\t<input type=\"hidden\" name=\"rcp_redirect\" value=\"https:\/\/access-basics.de\/data\/wp\/v2\/posts\/55000310\/\"\/>\n\t\t\t\t\t\t\t\t<input type=\"hidden\" name=\"rcp_login_nonce\" value=\"8d63f6cbe9\"\/>\n\t\t\t\t<input id=\"rcp_login_submit\" class=\"rcp-button\" type=\"submit\" value=\"Login\"\/>\n\t\t\t<\/p>\n\t\t\t\t\t<\/fieldset>\n\n\t\t\n\t<\/form>\n<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Die allermeisten Prozeduren und Funktionen des VBA-Projekts Ihrer Datenbank werden Sie in ganz normalen Modulen unterbringen. Dabei wird leicht &uuml;bersehen, dass es sich etwa bei Formularen um eine andere Art Module handelt, n&auml;mlich um Klassenmodule. Diese k&ouml;nnen Sie aber auch selbst anlegen. Erfahren Sie hier, wie Sie dabei vorgehen. Wir leiten das Thema zun&auml;chst jedoch mit den benutzerdefinierten Typen ein, welche Klassenmodule verst&auml;ndlicher machen.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[66012016,662016,44000011],"tags":[],"class_list":["post-55000310","post","type-post","status-publish","format-standard","hentry","category-66012016","category-662016","category-VBAGrundlagen"],"aioseo_notices":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v15.9.2 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Klassenmodule und benutzerdefinierte Typen - Access [basics]<\/title>\n<meta name=\"description\" content=\"Die allermeisten Prozeduren und Funktionen des VBA-Projekts Ihrer Datenbank werden Sie in ganz normalen Modulen unterbringen. Dabei wird leicht \u00fcbersehen, dass es sich etwa bei Formularen um eine andere Art Module handelt, n\u00e4mlich um Klassenmodule. Diese k\u00f6nnen Sie aber auch selbst anlegen. Erfahren Sie hier, wie Sie dabei vorgehen. Wir leiten das Thema zun\u00e4chst jedoch mit den benutzerdefinierten Typen ein, welche Klassenmodule verst\u00e4ndlicher machen.\" \/>\n<link rel=\"canonical\" href=\"https:\/\/access-basics.de\/index.php\/Klassenmodule_und_benutzerdefinierte_Typen.html\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Klassenmodule und benutzerdefinierte Typen - Access [basics]\" \/>\n<meta property=\"og:description\" content=\"Die allermeisten Prozeduren und Funktionen des VBA-Projekts Ihrer Datenbank werden Sie in ganz normalen Modulen unterbringen. Dabei wird leicht \u00fcbersehen, dass es sich etwa bei Formularen um eine andere Art Module handelt, n\u00e4mlich um Klassenmodule. Diese k\u00f6nnen Sie aber auch selbst anlegen. Erfahren Sie hier, wie Sie dabei vorgehen. Wir leiten das Thema zun\u00e4chst jedoch mit den benutzerdefinierten Typen ein, welche Klassenmodule verst\u00e4ndlicher machen.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-basics.de\/index.php\/Klassenmodule_und_benutzerdefinierte_Typen.html\" \/>\n<meta property=\"og:site_name\" content=\"Access [basics]\" \/>\n<meta property=\"article:published_time\" content=\"2020-01-24T15:59:32+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"-0001-11-30T00:00:00+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/..\/tl_files\/images\/frmAdressen3.png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Gesch\u00e4tzte Lesezeit\">\n\t<meta name=\"twitter:data1\" content=\"26\u00a0Minuten\">\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebSite\",\"@id\":\"https:\/\/access-basics.de\/#website\",\"url\":\"https:\/\/access-basics.de\/\",\"name\":\"Access [basics]\",\"description\":\"DAS ACCESS-MAGAZIN F\\u00dcR ALLE, DIE VON 0 AUF 100 WOLLEN\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":\"https:\/\/access-basics.de\/?s={search_term_string}\",\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"de\"},{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/access-basics.de\/index.php\/Klassenmodule_und_benutzerdefinierte_Typen.html#primaryimage\",\"inLanguage\":\"de\",\"url\":\"..\/tl_files\/images\/frmAdressen3.png\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/access-basics.de\/index.php\/Klassenmodule_und_benutzerdefinierte_Typen.html#webpage\",\"url\":\"https:\/\/access-basics.de\/index.php\/Klassenmodule_und_benutzerdefinierte_Typen.html\",\"name\":\"Klassenmodule und benutzerdefinierte Typen - Access [basics]\",\"isPartOf\":{\"@id\":\"https:\/\/access-basics.de\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/access-basics.de\/index.php\/Klassenmodule_und_benutzerdefinierte_Typen.html#primaryimage\"},\"datePublished\":\"2020-01-24T15:59:32+00:00\",\"dateModified\":\"-0001-11-30T00:00:00+00:00\",\"author\":{\"@id\":\"https:\/\/access-basics.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f\"},\"description\":\"Die allermeisten Prozeduren und Funktionen des VBA-Projekts Ihrer Datenbank werden Sie in ganz normalen Modulen unterbringen. Dabei wird leicht \\u00fcbersehen, dass es sich etwa bei Formularen um eine andere Art Module handelt, n\\u00e4mlich um Klassenmodule. Diese k\\u00f6nnen Sie aber auch selbst anlegen. Erfahren Sie hier, wie Sie dabei vorgehen. Wir leiten das Thema zun\\u00e4chst jedoch mit den benutzerdefinierten Typen ein, welche Klassenmodule verst\\u00e4ndlicher machen.\",\"breadcrumb\":{\"@id\":\"https:\/\/access-basics.de\/index.php\/Klassenmodule_und_benutzerdefinierte_Typen.html#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/access-basics.de\/index.php\/Klassenmodule_und_benutzerdefinierte_Typen.html\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/access-basics.de\/index.php\/Klassenmodule_und_benutzerdefinierte_Typen.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"item\":{\"@type\":\"WebPage\",\"@id\":\"https:\/\/access-basics.de\/\",\"url\":\"https:\/\/access-basics.de\/\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"position\":2,\"item\":{\"@type\":\"WebPage\",\"@id\":\"https:\/\/access-basics.de\/index.php\/Klassenmodule_und_benutzerdefinierte_Typen.html\",\"url\":\"https:\/\/access-basics.de\/index.php\/Klassenmodule_und_benutzerdefinierte_Typen.html\",\"name\":\"Klassenmodule und benutzerdefinierte Typen\"}}]},{\"@type\":\"Person\",\"@id\":\"https:\/\/access-basics.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f\",\"name\":\"Andr\\u00e9 Minhorst\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/access-basics.de\/#personlogo\",\"inLanguage\":\"de\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"caption\":\"Andr\\u00e9 Minhorst\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","_links":{"self":[{"href":"https:\/\/access-basics.de\/index.php\/data\/wp\/v2\/posts\/55000310","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/access-basics.de\/index.php\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/access-basics.de\/index.php\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/access-basics.de\/index.php\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/access-basics.de\/index.php\/data\/wp\/v2\/comments?post=55000310"}],"version-history":[{"count":0,"href":"https:\/\/access-basics.de\/index.php\/data\/wp\/v2\/posts\/55000310\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-basics.de\/index.php\/data\/wp\/v2\/media?parent=55000310"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-basics.de\/index.php\/data\/wp\/v2\/categories?post=55000310"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-basics.de\/index.php\/data\/wp\/v2\/tags?post=55000310"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}