{"id":55000232,"date":"2004-10-01T00:00:00","date_gmt":"2023-02-10T14:49:24","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=232"},"modified":"2024-02-19T08:15:06","modified_gmt":"2024-02-19T08:15:06","slug":"objektorientiertes_programmieren_mit_klassen","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/objektorientiertes_programmieren_mit_klassen\/","title":{"rendered":"Objektorientiertes Programmieren mit Klassen"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg06.met.vgwort.de\/na\/078cc562117c4a3a81756c25a6262675\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>Andr&eacute; Minhorst, Duisburg<\/b><\/p>\n<p><b>VBA wird im Allgemeinen die Eigenschaft abgesprochen, eine objektorientierte Programmiersprache zu sein. Um diese Aussage zu untersuchen, m&uuml;sste man erst einmal festlegen, ab wann eine Sprache objektorientiert ist und welche Eigenschaften f&uuml;r diese Bezeichnung vorhanden sein m&uuml;ssen. L&auml;sst man einmal au&szlig;en vor, dass Vererbung und Polymorphismus im VBA-Sprachgebrauch Fremdw&ouml;rter sind, kann man VBA sicher als objektorientierte Sprache auffassen. Wie auch immer &#8211; im vorliegenden Beitrag erfahren Sie, wie Sie sich die objektorientierten Eigenschaften von VBA zu Nutze machen.<\/b><\/p>\n<p>Wer mit Access arbeitet und dabei VBA f&uuml;r die Entwicklung von Datenbankanwendungen verwendet, kann vermutlich mit Objekten verschiedenen Typs umgehen &#8211; wenn er auch vielleicht noch nie einen eigenen Objekttyp erstellt hat.<\/p>\n<p>Sicher hat jeder schon einmal ein Recordset via VBA ge&ouml;ffnet und auf die darin enthaltenen Methoden wie Open, MoveNext, AddNew, Update oder Close zugegriffen oder Informationen aus Eigenschaften wie RecordCount, EOF oder Filter verwendet. Beispiele daf&uuml;r zeigt die Routine aus Quellcode 1, die eine auf der Tabelle tblKontakte basierende Datensatzgruppe &ouml;ffnet und den Inhalt der einzelnen Datens&auml;tze ausgibt. Mit diesem Code erzeugt man unter anderem eine Instanz des Objekttyps Recordset, legt einige seiner Eigenschaften wie beispielsweise die Datenherkunft und die zugrunde liegende Verbindung fest und greift anschlie&szlig;end auf die so verf&uuml;gbar gemachten Daten zu.<\/p>\n<pre>Public Sub OpenRecordset()\n    Dim cnn As ADODB.Connection\n    Dim rst As ADODB.Recordset\n    Set cnn = CurrentProject.Connection\n    Set rst = New ADODB.Recordset\n    rst.Open \"tblKontakte\", cnn, adOpenKeyset, _        adLockPessimistic\n    Do While Not rst.EOF\n        Debug.Print rst!KontaktID, rst!Vorname, _            rst!Nachname\n        rst.MoveNext\n    Loop\n    rst.Close\n    Set rst = Nothing\n    Set cnn = Nothing\nEnd Sub<\/pre>\n<p><b>Quellcode 1<\/b><\/p>\n<p>Eine weitere, ganz offensichtliche Objektart ist beispielsweise ein Formular &#8211; wie f&uuml;r ein Objekt &uuml;blich, verf&uuml;gt es &uuml;ber Methoden, Eigenschaften und Ereignisse. Ein Formularobjekt kann wiederum Steuerelemente enthalten, die ebenfalls Objekttypen repr&auml;sentieren.<\/p>\n<p>Mit den in Access vorhandenen Objekttypen l&auml;sst sich jede Menge n&uuml;tzlicher Dinge anstellen. Ein wichtiger Aspekt dabei ist, dass die unterschiedlichen Objekttypen bestimmte Methoden, Eigenschaften und Ereignisse enthalten.  Ein  Objekt des Typs Recordset fasst beispielsweise eine Menge Funktionalit&auml;t zusammen. Und das Beste daran ist, dass man sich gar nicht darum k&uuml;mmern muss, was im Innern dieses Objekts passiert &#8211; es reicht v&ouml;llig aus, dass man die Methoden, Eigenschaften und Ereignisse kennt. Wen interessiert denn schon, was intern alles abl&auml;uft, wenn man die Methode AddNew eines Recordset-Objekts aufruft Wichtig ist allein das Kennen der Schnittstelle und dass das Objekt die gew&uuml;nschten Reaktionen und Ergebnisse auf die get&auml;tigten Eingaben liefert.<\/p>\n<h3>Hinweis<\/h3>\n<p>Um keine Verwirrung bez&uuml;glich der hier verwendeten Begriffe aufkommen zu lassen, sollen folgende Definitionen gelten: Der Inhalt eines Klassenmoduls definiert eine Klasse. Eine Klasse wird auch Objekttyp genannt. Das Instanzieren einer Klasse beziehungsweise eines Objekttyps erzeugt ein Objekt. Auf das Objekt kann man in der Folge &uuml;ber die Objektvariable zugreifen. Das Klassenmodul enth&auml;lt also einen Entwurf dessen, wie das Objekt sich verhalten soll. Dieser Entwurf besteht aus der Definition geeigneter Eigenschaften, Methoden und Ereignisse sowie der dahinter liegenden Funktionen. <\/p>\n<p>Nun bietet Access nur eine begrenzte Menge Objekttypen, die allerdings bereits viele Anforderungen abdecken. Genau genommen sind Art und Menge der Objekttypen gerade so bemessen, dass sie als vern&uuml;nftige Grundlage f&uuml;r den Aufbau der jeweils individuell abzubildenden Gesch&auml;ftsprozesse einer Anwendung dienen.<\/p>\n<p>Damit gibt es bereits einige gute Gr&uuml;nde, um eigene Objekttypen zu schaffen:<\/p>\n<li>Objekttypen enthalten Methoden, Eigenschaften und Ereignisse und machen diese &uuml;ber eine leicht zug&auml;ngliche Schnittstelle verf&uuml;gbar. <\/li>\n<li>Affinit&auml;t: Mit der Definition eines Objekttyps macht man Softwareentwicklung wesentlich greifbarer, denn reelle Objekte wie beispielsweise der nachfolgend vorgestellte Kontakt k&ouml;nnen &uuml;ber realit&auml;tsnahe Attribute angesprochen werden.<\/li>\n<li>Komplexit&auml;t verbergen: Objekttypen verbergen mitunter komplexe Vorg&auml;nge, um die man sich, wenn sie einmal gestestet und praxiserprobt sind, keine Gedanken mehr machen muss. Der ansonsten offen liegende Code verschwindet in einer Black Box; nicht mehr die darin enthaltenen Techniken interessieren, sondern allein die Schnittstelle.<\/li>\n<li>Wiederverwendbarkeit: Auf den Funktionsumfang eines Objekts kann man von der ganzen Anwendung aus zugreifen; unter Umst&auml;nden k&ouml;nnen Objekttypen sogar in weiteren Anwendungen zum Einsatz kommen &#8211; beispielsweise, wenn die Klassen nicht an eine bestimmte Datenherkunft gebunden sind.<\/li>\n<li>Weitergabe: Objekttypen k&ouml;nnen in Form von Klassenmodulen leicht weitergegeben werden; eine funktionierende Schnittstelle und eine brauchbare Dokumentation vorausgesetzt, k&ouml;nnen andere Entwickler diese leicht weiterverwenden.<\/li>\n<p>Wie bereits oben erw&auml;hnt, ist einer der Vorteile der Verwendung von Objekttypen, dass man reelle Objekte und deren Eigenschaften in einer Einheit zusammenfassen kann, deren Methoden, Eigenschaften und Ereignisse &uuml;ber eine entsprechende Schnittstelle erreichbar sind. Unter VBA spricht man in diesem Zusammenhang von einem Klassenmodul.<\/p>\n<p>Als Beispiel f&uuml;r die Erl&auml;uterung des Aufbaus und der Verwendung von Objekttypen dient ein Kontakt. Er enth&auml;lt bestimmte Informationen zu einer Person wie Vorname, Nachname, Geschlecht und Adressdaten. Um nicht nur die Verwendung von Eigenschaften, sondern auch den Einsatz von Methoden vorzustellen, erh&auml;lt die Beispielobjektklasse zus&auml;tzlich eine Routine zur Ausgabe der Adressdaten in Form einer Anschrift.<\/p>\n<h3>Hinweis<\/h3>\n<p>Die zu den nachfolgenden Beispielen geh&ouml;renden Objekte und Codes finden Sie in der Beispieldatenbank OOMitAccess.mdb f&uuml;r Access 2000 und h&ouml;her auf der beiliegenden CD. <\/p>\n<h2>Erstellen eines Klassenmoduls<\/h2>\n<p>Access stellt drei unterschiedliche Modularten zur Verf&uuml;gung: die Klassenmodule von Formularen und Berichten, Standardmodule sowie Klassenmodule, die nicht an ein bestimmtes Objekt wie ein Formular oder einen Bericht gebunden sind. Die Klassenmodule von Formularen und Berichten sind prinzipiell mit den im Anschluss vorgestellten Klassenmodulen identisch; der einzige Unterschied ist, dass Letztere keine Oberfl&auml;che in Form eines Formulars oder Berichts enthalten.<\/p>\n<p>Um ein solches Klassenmodul zu erstellen, w&auml;hlen Sie im VBA-Editor von Access den Men&uuml;eintrag Einf&uuml;gen\/Klassenmodul aus. Daraufhin &ouml;ffnet Access ein fast leeres neues Klassenmodul, das Sie am besten direkt unter dem gew&uuml;nschten Namen speichern &#8211; beispielsweise clsKontakt. W&auml;hlen Sie den Namen eines Klassenmoduls immer so, dass er auch verr&auml;t, welches Objekt sich dahinter verbirgt &#8211; sp&auml;ter werden Sie &uuml;ber diesen Namen auf diese Klasse zugreifen.<\/p>\n<h3>Praxis-Tipp<\/h3>\n<p>Damit der Debugger sich meldet, wenn eine Variable nicht ordnungsgem&auml;&szlig; deklariert ist, sollten Sie im Prozedurkopf die Anweisung Option Explicit hinzuf&uuml;gen. <\/p>\n<h2>Schreib- und lesbare Variablen<\/h2>\n<p>Die Eigenschaften eines Objekttyps speichert man in herk&ouml;mmlicher Weise in Variablen. Die Zugriffsm&ouml;glichkeiten auf diese Variablen kann man allerdings wesentlich flexibler gestalten als in Prozeduren in Standardmodulen.<\/p>\n<p>Sie k&ouml;nnen eine Variable innerhalb eines Klassenmoduls nat&uuml;rlich als &ouml;ffentlich zug&auml;nglich deklarieren, indem Sie etwa folgende Anweisung verwenden:<\/p>\n<pre>Public Vorname As String<\/pre>\n<p>Damit k&ouml;nnen Sie den Wert dieser Variablen von au&szlig;en lesen und auch &auml;ndern, haben aber keinerlei Vorteile der in Klassenmodulen &uuml;blichen Art der Deklaration.<\/p>\n<p>Dort gibt es n&auml;mlich so genannte Property-Funktionen, &uuml;ber die man von au&szlig;en den Wert einer Variablen lesen und &auml;ndern kann. Daher deklariert man Variablen in Klassenmodulen niemals als &ouml;ffentlich, sondern immer als privat. Die Property-Funktionen erlauben nicht nur den schreibenden und lesenden Zugriff auf die privaten Variablen (wobei es f&uuml;r jede Zugriffsart eine eigene Funktion gibt), sondern man kann dort beliebige weitere Anweisungen unterbringen. Auf diese Weise l&auml;sst sich beispielsweise ein Zeiger setzen, der Informationen dar&uuml;ber enth&auml;lt, ob sich eine Variable seit Erstellung der Objektinstanz ge&auml;ndert hat.<\/p>\n<h3>Namenskonventionen<\/h3>\n<p>Die Variablen, die &uuml;ber Property-Funktionen f&uuml;r die Au&szlig;enwelt erreichbar sein sollen, kennzeichnet man durch Voranstellen eines weiteren Buchstabens zum eigentlichen Variablennamen. Genau genommen w&auml;hlt man einen Namen aus, unter dem die Variable nach au&szlig;en erscheinen soll, wie beispielsweise Vorname, und nennt die Variable intern mVorname.<\/p>\n<h2>Hinzuf&uuml;gen einer Variablen<\/h2>\n<p>Um eine bessere Vorstellung davon zu bekommen, was es mit diesen Property-Funktionen auf sich hat, f&uuml;gen Sie der Klasse einfach eine Variable hinzu und erstellen zwei passende Property-Funktionen:<\/p>\n<pre>Dim mVorname As String\nPublic Property Get Vorname() As String\n    Vorname = mVorname\nEnd Property\nPublic Property Let Vorname(strVorname _    As String)\n    mVorname = strVorname\nEnd Property<\/pre>\n<h2>Testen der Variablen<\/h2>\n<p>Zum Testen der Funktionsweise verwenden Sie eine Prozedur namens BeispielKontakt in einem beliebigen Standardmodul. Um die Klasse verf&uuml;gbar zu machen, deklarieren Sie zun&auml;chst eine entsprechende Objektvariable:<\/p>\n<pre>Public Sub KontaktBeispiel()\n    Dim objKontakt As clsKontakt\n    ''... weitere Anweisungen\nEnd Sub<\/pre>\n<p>Nach der Eingabe des Schl&uuml;sselwortes As erscheint die Liste aller verf&uuml;gbaren Objekttypen, unter denen sich nun auch die neu erstellte Klasse befindet &#8211; wenn Sie also sp&auml;ter mal eine ganze Menge eigener Objekttypen verwenden, m&uuml;ssen Sie sich noch nicht einmal mehr deren Namen genau merken.<\/p>\n<p>Anschlie&szlig;end erzeugen Sie eine Instanz dieses Objekttyps, die Sie in der Prozedur verwenden m&ouml;chten:<\/p>\n<pre>Set objKontakt = New clsKontakt<\/pre>\n<p>Sie k&ouml;nnten die ersten beiden Anweisungen auch zu einer einzigen Anweisung zusammenfassen:<\/p>\n<pre>Dim objKontakt As New clsKontakt<\/pre>\n<p>Dadurch sparen Sie zwar eine Zeile, aber wenn Sie die Objektinstanz m&ouml;glicherweise erst sp&auml;ter ben&ouml;tigen oder es sich erst im Verlaufe der Prozedur herausstellt, ob Sie diese &uuml;berhaupt brauchen, verschwenden Sie unter Umst&auml;nden wertvolle Ressourcen.<\/p>\n<p>Damit auch alles seine Ordnung hat und Objekte nicht unn&ouml;tig Speicherplatz belegen, obwohl sie nicht mehr ben&ouml;tigt werden, legen Sie vorsichtshalber jetzt schon die Anweisung zum Zerst&ouml;ren des Objektes an:<\/p>\n<pre>Set objKontakt = Nothing<\/pre>\n<p>Das ist zwar im vorliegenden Fall nicht unbedingt erforderlich, da das Objekt ohnehin nach Beenden der Prozedur zerst&ouml;rt wird, aber es ist programmiertechnisch sauberer. Die folgenden Beispielanweisungen f&uuml;gen Sie nat&uuml;rlich vor dieser Anweisung ein, da sie sich sonst auf ein nicht mehr vorhandenes Objekt bez&ouml;gen.<\/p>\n<p>Und nun geht&#8220;s an die Variable mVorname und deren Property-Prozeduren, die zusammen die les- und schreibbare Eigenschaft Vorname ergeben. Die folgende Anweisung setzt den Wert dieser Variablen auf den Wert Heinz:<\/p>\n<pre>objKontakt.Vorname = \"Heinz\"<\/pre>\n<p>Dank Intellisense erscheint der Eigenschaftsname direkt nach der Eingabe des Punktes hinter objKontakt in der Liste der verf&uuml;gbaren Eigenschaften, Methoden und Ereignisse dieses Objekts &#8211; bisher also allein auf weiter Flur (s. Abb. 1).<\/p>\n<p><IMG height=\"283\" src=\"..\/fileadmin\/_temp_\/{71294750-B980-48F7-AFE7-5FAB892305CE}\/pic001.png\" width=\"462\" border=\"0\"><\/p>\n<p><b><\/b><\/p>\n<p><b>Abb. 1: Intellisense vereinfacht den Zugriff auf Objekteigenschaften.<\/b><\/p>\n<p>Um zu &uuml;berpr&uuml;fen, ob die Zuweisung funktioniert, geben Sie mit nachfolgender Anweisung den Inhalt der Eigenschaft im Testfenster aus:<\/p>\n<pre>Debug.Print objKontakt.Vorname<\/pre>\n<h3>Was ist passiert<\/h3>\n<p>&uuml;ber die Zuweisung der Zeichenkette an objKontakt.Vorname haben Sie die Property Let-Methode aufgerufen.  Diese nimmt den &uuml;bergebenen Wert &uuml;ber den Parameter strVorname entgegen und weist ihn der privaten Variablen mVorname zu.<\/p>\n<p>Bei der nachfolgenden Ausgabe l&auml;uft es umgekehrt: Die Propery Get-Prozedur ermittelt den Wert der Variablen mVorname und schickt ihn &uuml;ber die Eigenschaft Vorname zur Ausgabe.<\/p>\n<h3>Hinweis<\/h3>\n<p>Vielleicht haben Sie den gro&szlig;en Vorteil dieser Vorgehensweise schon erkannt: Sie k&ouml;nnen mit Hilfe von Get- und Let-Prozeduren f&uuml;r eine Property festlegen, ob diese zum Lesen, Schreiben oder gar f&uuml;r beide Zugriffsarten verf&uuml;gbar sein soll. <\/p>\n<h3>Im Gleichschritt: Marsch!<\/h3>\n<p>Nachdem Sie sich von der Funktionsweise der Eigenschaft Vorname &uuml;berzeugt haben, k&ouml;nnen Sie nun die Variablen f&uuml;r die weiteren Eigenschaften des Kontakts wie Nachname, Strasse, PLZ, Ort, Land und Unternehmen sowie die entsprechenden Property Let und Property Get-Prozeduren anlegen. Damit h&auml;tten Sie eine Klasse erzeugt, die wichtige Eigenschaften eines Kontaktes erhalten und wieder ausgeben kann.<\/p>\n<h2>Die Ereignisse Initialize und Terminate<\/h2>\n<p>Klassenmodule stellen zwei eingebaute Ereigniseigenschaften zur Verf&uuml;gung, die beim Erzeugen und beim Zerst&ouml;ren einer Objektinstanz ausgel&ouml;st werden.<\/p>\n<p>Um die entsprechenden Ereigniseigenschaften zu erzeugen, w&auml;hlen Sie einfach im VBA-Editor im linken Kombinationsfeld den Eintrag Class und im rechten den Namen der gew&uuml;nschten Ereignisprozedur aus (s. Abb. 2).<\/p>\n<p><IMG height=\"182\" src=\"..\/fileadmin\/_temp_\/{71294750-B980-48F7-AFE7-5FAB892305CE}\/pic002.png\" width=\"329\" border=\"0\"><\/p>\n<p><b><\/b><\/p>\n<p><b>Abb. 2: Erzeugen einer Ereignisprozedur einer Klasse<\/b><\/p>\n<p>Diese Eigenschaften k&ouml;nnen Sie beispielsweise verwenden, um beim Erzeugen der Objektinstanz Variablen auf bestimmte Startwerte oder Verweise auf andere Objekte zu setzen. Beim Zerst&ouml;ren einer Objektinstanz erledigt man mit der entsprechenden Ereignisprozedur notwendige Aufr&auml;umarbeiten.<\/p>\n<h2>Verwenden von Enumerationen<\/h2>\n<p>Sicher kennen Sie die M&ouml;glichkeit, per Intellisense eine vordefinierte Konstante f&uuml;r einen Parameter auszuw&auml;hlen. Das Gleiche ist auch mit den Eigenschaften einer Objektinstanz m&ouml;glich. Um bei unserem Beispiel mit den Kontaktdaten zu bleiben, f&uuml;gen wir diesem noch eine Eigenschaft namens Geschlecht hinzu. Daf&uuml;r gibt es unter normalen Umst&auml;nden nur zwei m&ouml;gliche Eintr&auml;ge, deren Auswahl man dem Benutzer gerne abnimmt. Die passende Enumeration sieht folgenderma&szlig;en aus:<\/p>\n<pre>Public Enum enumGeschlecht\n    m&auml;nnlich\n    weiblich\nEnd Enum<\/pre>\n<p>Die Definition der entsprechenden Variablen sowie der Property Let- und Get-Prozeduren sieht wie folgt aus:<\/p>\n<pre>Dim mGeschlecht As enumGeschlecht\nPublic Property Get Geschlecht() As enumGeschlecht\n    Geschlecht = mGeschlecht\nEnd Property\nPublic Property Let Geschlecht(lngGeschlecht As enumGeschlecht)\n    mGeschlecht = lngGeschlecht\nEnd Property<\/pre>\n<p>Es gibt also prinzipiell keine Unterschiede zu herk&ouml;mmlichen Datentypen, mit der Ausnahme, dass der Datentyp als Enumeration definiert wird.<\/p>\n<p>Hier sind zwei Dinge zu beachten: Beim Zugriff auf diese Objekteigenschaft stehen zwar die beiden Konstanten zur Verf&uuml;gung (s. Abb. 3). Wenn man sich den ausgew&auml;hlten Wert nachher ausgeben l&auml;sst, erh&auml;lt man aber nicht den ausgew&auml;hlten Ausdruck, sondern die dahinter stehende Konstante.<\/p>\n<pre>Public Function Anschrift() As String\n    Dim strAnschrift As String\n    Dim strAnrede As String\n    If mGeschlecht = m&auml;nnlich Then\n        strAnrede = \"Herrn \"\n    Else\n        strAnrede = \"Frau \"\n    End If\n    If Not mUnternehmen = \"\" Then\n        strAnschrift = strAnschrift & mUnternehmen & vbCrLf\n        strAnschrift = strAnschrift & strAnrede & mVorname & \" \" & mNachname & vbCrLf\n    Else\n        strAnschrift = strAnschrift & strAnrede & vbCrLf\n        strAnschrift = strAnschrift & mVorname & \" \" & strNachname & vbCrLf\n    End If\n    strAnschrift = strAnschrift & mStrasse & vbCrLf\n    strAnschrift = strAnschrift & mPLZ & \" \" & mOrt & vbCrLf\n    strAnschrift = strAnschrift & mLand\n    Anschrift = strAnschrift\nEnd Function<\/pre>\n<p><b>Quellcode 1<\/b><\/p>\n<p>Womit wir direkt beim zweiten Punkt w&auml;ren: Man kann den einzelnen Teilen der Enumeration direkt entsprechende Zahlenwerte mitgeben oder diese wie in obigem Beispiel weglassen. In dem Fall nummeriert Access die Werte hinter den Eintr&auml;gen bei 0 beginnend durch. F&uuml;r ein wenig mehr Kontrolle sollten Sie also selbst entsprechende Werte vergeben, also etwa folgenderma&szlig;en:<\/p>\n<pre>Public Enum enumGeschlecht\n    M&auml;nnlich = 1\n    Weiblich = 2\nEnd Enum<\/pre>\n<p><IMG height=\"348\" src=\"..\/fileadmin\/_temp_\/{71294750-B980-48F7-AFE7-5FAB892305CE}\/pic003.png\" width=\"462\" border=\"0\"><\/p>\n<p><b><\/b><\/p>\n<p><b>Abb. 3: Enumerationen k&ouml;nnen die Auswahl von Konstanten vereinfachen.<\/b><\/p>\n<h2>Methoden von Objekttypen<\/h2>\n<p>Was kann man nun mit einer Klasse anfangen, die es erlaubt, Eigenschaften eines Kontaktes einzugeben und wieder abzurufen Ein einfaches Beispiel ist das Zusammenstellen einer Anschrift aus den eingegebenen Daten und deren Ausgabe.<\/p>\n<p>Dazu legen Sie einfach die Prozedur aus Quellcode 1 im Klassenmodul clsKontakt an.<\/p>\n<h3>Function oder Sub<\/h3>\n<p>Genau wie in anderen Modulen kann man auch die &ouml;ffentlich zug&auml;nglichen Prozeduren in Klassenmodulen als Function oder Sub ausf&uuml;hren. Der einzige Unterschied ist, dass eine Function ein Ergebnis an die aufrufende Routine zur&uuml;ckliefert. Das ist im Falle des Zusammenstellens einer Anschrift aus Adressdaten nat&uuml;rlich sinnvoll.<\/p>\n<p>Alternativ k&ouml;nnte man nat&uuml;rlich auch eine Eigenschaft f&uuml;r den Objekttyp festlegen, der die fertige Anschrift enth&auml;lt. Die Function k&ouml;nnte man dann in eine Sub-Prozedur umwandeln, die das Ergebnis in eine der Eigenschaft entsprechende Variable schreibt. Die aufrufende Routine w&uuml;rde dann das Zusammenstellen der Anschrift ansto&szlig;en und anschlie&szlig;end das Ergebnis aus der Objekteigenschaft Anschrift ermitteln. Das ist aber nicht sinnvoll, da sich so unter Umst&auml;nden Redundanzen innerhalb der Klasse ergeben.<\/p>\n<p>Wenn die Anschrift einmal erzeugt ist und eine Eigenschaft wie beispielsweise der Vorname ge&auml;ndert wird, w&uuml;rden die Daten der Anschrift und der zugrunde liegenden Eigenschaften nicht mehr &uuml;bereinstimmen. Man m&uuml;sste dann schon die Property Let-Prozeduren jeder einzelnen Eigenschaft so anpassen, dass bei &auml;nderung einer Eigenschaft auch direkt die Anschrift neu zusammengestellt wird &#8211; und das w&auml;re im vorliegenden Beispiel nicht sehr sinnvoll. Daher ist die R&uuml;ckgabe des Ergebnisses als Funktionswert der bessere Weg.<\/p>\n<pre>Public Sub KontaktBeispiel()\n    Dim objKontakt As clsKontakt\n    Set objKontakt = New clsKontakt\n    With objKontakt\n        .Vorname = \"Heinz\"\n        .Nachname = \"M&uuml;ller\"\n        .Geschlecht = m&auml;nnlich\n        .Strasse = \"Teststra&szlig;e 12\"\n        .PLZ = \"12345\"\n        .Ort = \"Beispielstadt\"\n        .Unternehmen = \"M&uuml;ller''s \" _            & \"Klassenmodule\"\n        MsgBox .Anschrift\n    End With\n    Set objKontakt = Nothing\nEnd Sub<\/pre>\n<p><b>Quellcode 2<\/b><\/p>\n<p><IMG height=\"0\" src=\"..\/fileadmin\/_temp_\/{71294750-B980-48F7-AFE7-5FAB892305CE}\/pic004.png\" width=\"0\" border=\"0\"><\/p>\n<p><b><\/b><\/p>\n<p><b>Abb. 4: Ergebnis der Methode Anschrift des Klassenmoduls<\/b><\/p>\n<p>Die Anwendung der Funktion Anschrift des Klassenmoduls sieht nun wie in Quellcode 2 aus. Abb. 4 zeigt, wie die durch die Prozedur KontaktBeispiel erzeugte Anschrift aussieht.<\/p>\n<h3>Funktionsparameter oder Objekteigenschaften<\/h3>\n<p>Eine weitere wichtige Frage, die sich gerade bei dem soeben beschriebenen Beispiel aufdr&auml;ngt, ist folgende: Warum soll man eigentlich extra Eigenschaften erzeugen, um Werte zu &uuml;bergeben, die man auch per Funktionsparameter &uuml;bermitteln k&ouml;nnte Die Antwort f&uuml;r den vorliegenden Fall lautet: Im diesem Fall k&ouml;nnte man die ben&ouml;tigten Werte ebenso per Funktionsparameter &uuml;bergeben. Der Grund daf&uuml;r, dass wir dennoch f&uuml;r jeden Wert eine eigene Eigenschaft inklusive Property-Funktionen angelegt haben, ist der, dass der Objekttyp in den folgenden Beispielen noch um einige Funktionen erweitert werden soll, die die Verwendung der Eigenschaften rechtfertigen.<\/p>\n<p>Wenn eine Anwendung von verschiedenen Stellen aus auf in Tabellen gespeicherte Daten zugreift, enth&auml;lt sie zwangsl&auml;ufig Routinen mit immer gleichen oder zumindest &auml;hnlichen Anweisungen f&uuml;r den Datenzugriff. Mit einer Klasse f&uuml;r den Zugriff auf die Daten einer Tabelle lassen sich derartige immer wiederkehrende Programmierarbeiten vereinfachen.<\/p>\n<p>Die nachfolgenden beiden Beispielprozeduren zeigen, wie Sie die Daten eines Objekts in eine Tabelle schreiben und von dort wieder einlesen k&ouml;nnen. Sp&auml;ter erfahren Sie, wie Sie diese Prozeduren verwenden k&ouml;nnen, um ungebundene Formulare mit Daten zu f&uuml;llen.<\/p>\n<h2>Schreiben von Objektdaten in eine Tabelle<\/h2>\n<p>Die Routine aus Quellcode 3 schreibt die aktuellen Kontaktdaten in die Tabelle tblKontakte, die wie in Abb. 5 aufgebaut ist und alle Felder enth&auml;lt, die auch in der Klasse clsKontakt als Eigenschaft vorhanden sind.<\/p>\n<pre>Public Function Save() As Boolean\n    Dim cnn As ADODB.Connection\n    Dim rst As ADODB.Recordset\n    Set cnn = CurrentProject.Connection\n    Set rst = New ADODB.Recordset\n    rst.Open \"SELECT * FROM tblKontakte WHERE \" _        & \"KontaktID = \" & mID, cnn, adOpenKeyset, _        adLockPessimistic\n    With rst\n        If .EOF Then\n            .AddNew\n            mID = !KontaktID\n        End If\n        !Vorname = mVorname\n        !Nachname = mNachname\n        !Geschlecht = mGeschlecht\n        !Strasse = mStrasse\n        !PLZ = mPLZ\n        !Ort = mOrt\n        !Land = mLand\n        !Unternehmen = mUnternehmen\n        .Update\n    End With\n    Save = True\nSave_Exit:\n    rst.Close\n    Set rst = Nothing\n    Set cnn = Nothing\n    Exit Function\nSave_Err:\n    Save = False\n    GoTo Save_Exit\nEnd Function<\/pre>\n<p><b>Quellcode 3<\/b><\/p>\n<p><IMG height=\"0\" src=\"..\/fileadmin\/_temp_\/{71294750-B980-48F7-AFE7-5FAB892305CE}\/pic005.png\" width=\"0\" border=\"0\"><\/p>\n<p><b><\/b><\/p>\n<p><b>Abb. 5: Entwurfsansicht der Tabelle tblKontakte<\/b><\/p>\n<p>Die Routine erstellt erst die erforderlichen Connection- und Recordset-Instanzen. Das Recordset f&uuml;llt sie mit allen Datens&auml;tzen der Tabelle tblKontakte, deren KontaktID dem in der Variablen mID gespeicherten Wert entspricht.<\/p>\n<p>Wenn ein solcher Datensatz noch nicht vorhanden ist, legt die Methode einen neuen Datensatz an und speichert die KontaktID des neuen Datensatzes in der Variablen mID der Klasse. <\/p>\n<p>Anschlie&szlig;end stellt sie die &uuml;brigen Felder der Tabelle auf die in den Objekteigenschaften gespeicherten Werte ein und aktualisiert die Tabelle. Die rudiment&auml;re Fehlerbehandlung sorgt lediglich daf&uuml;r, dass die Methode beim Auftreten eines Fehlers den Wert False als Funktionswert an die aufrufende Routine zur&uuml;ckgibt.<\/p>\n<p>Der Aufruf k&ouml;nnte wie in Quellcode 4 aussehen. Wie in den vorherigen Beispielen versieht auch diese Routine die einzelnen Eigenschaften mit entsprechenden Werten (in Quellcode 4 aus Platzgr&uuml;nden entfernt). Das Ergebnis des Aufrufs der Save-Methode des Objekts objKontakt wertet die Routine so aus, dass ein Meldungsfenster mit einer entsprechenden Nachricht den Erfolg oder das Scheitern des Speichervorgangs mitteilt.<\/p>\n<h2>Einlesen von Daten in ein Objekt<\/h2>\n<p>Die Prozedur zum Einlesen eines Kontaktes aus der Tabelle tblKontakte in ein Objekt des Typs clsKontakt sieht wie in Quellcode 5 aus. Sie &ouml;ffnet ein Recordset mit dem Datensatz, dessen KontaktID der ID des Objekts entspricht.<\/p>\n<pre>Public Sub KontaktSpeichern()\n    Dim objKontakt As clsKontakt\n    Set objKontakt = New clsKontakt\n    With objKontakt\n        ''...Eigenschaftszuweisungen...\n        If objKontakt.Save = True Then\n            MsgBox \"Speichern erfolgreich!\"\n        Else\n            MsgBox \"Speichern missgl&uuml;ckt!\"\n        End If\n    End With\n    Set objKontakt = Nothing\nEnd Sub<\/pre>\n<p><b>Quellcode 4<\/b><\/p>\n<pre>Public Function Load() As Boolean\n    Dim cnn As ADODB.Connection\n    Dim rst As ADODB.Recordset\n    Set cnn = CurrentProject.Connection\n    Set rst = New ADODB.Recordset\n    rst.Open \"SELECT * FROM tblKontakte WHERE \" _        & \"KontaktID = \" & mID, cnn, adOpenKeyset, _        adLockPessimistic\n    With rst\n        If Not .EOF Then\n            mVorname = !Vorname\n            mNachname = !Nachname\n            mGeschlecht = !Geschlecht\n            mStrasse = !Strasse\n            mPLZ = !PLZ\n            mOrt = !Ort\n            mLand = !Land\n            mUnternehmen = !Unternehmen\n            Load = True\n        Else\n            Load = False\n        End If\n    End With\nLoad_Exit:\n    rst.Close\n    Set rst = Nothing\n    Set cnn = Nothing\n    Exit Function\nLoad_Err:\n    Load = False\n    GoTo Load_Exit\nEnd Function<\/pre>\n<p><b>Quellcode 5<\/b><\/p>\n<p>Anders als in der Prozedur Save aus Quellcode 3 liest diese Prozedur die einzelnen Feldwerte der Tabelle in die Eigenschaften der Objektinstanz ein. Auch hier sorgt die Fehlerbehandlung daf&uuml;r, dass die Funktion in jedem Fall eine Erfolgs- oder Misserfolgsmeldung zur&uuml;ckgibt.<\/p>\n<p>Der Aufruf dieser Methode erfolgt beispielsweise wie in der Prozedur aus Quellcode 6. Zu Beispielzwecken erfolgt ein &#8222;hartes&#8220; Setzen der ID des gew&uuml;nschten Datensatzes.<\/p>\n<p>Wenn die Load-Methode f&uuml;ndig wird, erscheint ein Meldungsfenster mit Vor- und Nachnamen des gesuchten Kontakts.<\/p>\n<p>Nat&uuml;rlich greifen Sie nicht immer nur von Prozeduren aus auf eine Klasse zu, die beispielsweise die Daten einer Tabelle kapselt. Um praktischen Nutzen aus der soeben erstellten Klasse zum Laden und Speichern eines Kontaktes zu ziehen, lernen Sie nachfolgend, wie Sie ein ungebundenes Formular zur Anzeige und zum Bearbeiten der gew&uuml;nschten Kontaktdaten verwenden k&ouml;nnen. <\/p>\n<p>Abb. 6 zeigt das Formular in der Formularansicht. Alle Felder des Formulars sind ungebunden, nur die mit den beiden Kombinationsfeldern ausw&auml;hlbaren Informationen stammen aus den entsprechenden Tabellen.<\/p>\n<p>Dabei dient das Kombinationsfeld cboKontaktID zur Auswahl des anzuzeigenden Kontakts. <\/p>\n<p><IMG height=\"0\" src=\"..\/fileadmin\/_temp_\/{71294750-B980-48F7-AFE7-5FAB892305CE}\/pic006.png\" width=\"0\" border=\"0\"><\/p>\n<p><b><\/b><\/p>\n<p><b>Abb. 6: Ungebundenes Formular zur Anzeige von Kontaktdaten<\/b><\/p>\n<h2>Vorteile von ungebundenenFormularen<\/h2>\n<p>Wenn Sie statt eines herk&ouml;mmlichen, an eine Datenherkunft gebundenen Formulars ein ungebundenes Formular verwenden, das seine Daten aus einem Objekt bezieht, haben Sie mehrere Vorteile. Sie k&ouml;nnen beispielsweise viel genauer steuern, wann Daten in das Formular gelangen, wie Sie zwischen den vorhandenen Datens&auml;tzen navigieren oder wann die Daten gespeichert werden.<\/p>\n<h2>Laden eines Kontaktes<\/h2>\n<p>Die Auswahl eines Eintrags des Kombinationsfeldes zur Anzeige der vorhandenen Kontakte l&ouml;st die entsprechende Ereigniseigenschaft aus, die wiederum die Prozedur LoadKontakt startet.<\/p>\n<p>Diese Prozedur (s. Quellcode 7) erzeugt zun&auml;chst eine neue Instanz der Klasse clsKontakt und weist ihrer Eigenschaft ID die KontaktID des im Kombinationsfeld ausgew&auml;hlten Eintrags zu.<\/p>\n<p>Mit dieser ID im Gep&auml;ck darf anschlie&szlig;end die Load-Methode des Kontakt-Objekts seinen Dienst verrichten; die so in die Klasse geladenen Daten landen direkt in den entsprechenden Feldern des Formulars.<\/p>\n<pre>Public Sub KontaktLaden()\n    Dim objKontakt As clsKontakt\n    Set objKontakt = New clsKontakt\n    With objKontakt\n        .ID = 10\n        If .Load = True Then\n            MsgBox \"Vorname: \" _                & .Vorname & vbCrLf _                & \"Nachname: \" _                & .Nachname\n        Else\n            MsgBox \"Der Datensatz ist \" _                & \" nicht vorhanden.\"\n        End If\n    End With\n    Set objKontakt = Nothing\nEnd Sub<\/pre>\n<p><b>Quellcode 6<\/b><\/p>\n<pre>Private Sub LoadKontakt()\n    Dim objKontakt As clsKontakt\n    Set objKontakt = New clsKontakt\n    With objKontakt\n        .ID = Me!cboKontaktID\n        If .Load = True Then\n            Me!txtVorname = .Vorname\n            Me!txtNachname = .Nachname\n            Me!cboGeschlechtID = _                .Geschlecht\n            Me!txtStrasse = .Strasse\n            Me!txtPLZ = .PLZ\n            Me!txtOrt = .Ort\n            Me!txtLand = .Land\n            Me!txtUnternehmen = _                .Unternehmen\n        Else\n            MsgBox \"Kontakt kann \" _                & \"nicht angezeigt \" _                & \"werden.\"\n        End If\n    End With\nEnd Sub<\/pre>\n<p><b>Quellcode 7<\/b><\/p>\n<h2>Speichern eines Kontaktes<\/h2>\n<p>Ein Klick auf die Speichern-Schaltfl&auml;che des Formulars ruft &uuml;ber die entsprechende Ereigniseigenschaft die Prozedur SaveKontakt auf (s. Quellcode 8). Diese weist einer frisch erzeugten Instanz der Kontakt-Klasse die in den Feldern des Formulars enthaltenen Daten zu &#8211; inklusive der ID des aktuell im Kombinationsfeld ausgew&auml;hlten Eintrags. Beim Scheitern des Speichervorgangs erscheint eine entsprechende Meldung, anderenfalls aktualisiert die Prozedur das Kombinationsfeld cboKontaktID und setzt es auf die ID des soeben gespeicherten Datensatzes. Das mag auf den ersten Blick unn&ouml;tig erscheinen, ist es aber nicht &#8211; wie der n&auml;chste Abschnitt zeigen wird.<\/p>\n<pre>Private Sub SaveKontakt()\n    Dim objKontakt As clsKontakt\n    Set objKontakt = New clsKontakt\n    With objKontakt\n        .ID = Me!cboKontaktID\n        .Vorname = Me!txtVorname\n        .Nachname = Me!txtNachname\n        .Geschlecht = Me!cboGeschlechtID\n        .Strasse = Me!txtStrasse\n        .PLZ = Me!txtPLZ\n        .Ort = Me!txtOrt\n        .Land = Me!txtLand\n        .Unternehmen = Me!txtUnternehmen\n        If Not .Save = True Then\n            MsgBox \"Speichern nicht \" _                & \"erfolgreich.\"\n        Else\n            Me!cboKontaktID.Requery\n            Me!cboKontaktID = .ID\n        End If\n    End With\nEnd Sub<\/pre>\n<p><b>Quellcode 8<\/b><\/p>\n<h2>Anlegen eines neuen Kontakts<\/h2>\n<p>Die Schaltfl&auml;che cmdNeuerKontakt leert alle vorhandenen Felder des Formulars. Nach Eingabe der Daten des neuen Kontakts kann dieser mit der Prozedur aus Quellcode 8 gespeichert werden. Damit findet sich auch der Grund f&uuml;r die Aktualisierung des Kombinationsfeldes und die Zuweisung der aktuellen ID: Beim Speichern des neuen Datensatzes zeigt das Kombinationsfeld cboKontaktID keinen Wert an, weil der neue Kontakt ja noch nicht in der Tabelle verf&uuml;gbar ist und er auch noch keine ID hat. Diese ist erst nach dem Speichern des Datensatzes bekannt. Daher kann (und muss) das Kombinationsfeld erst nach dem Speichern auf den neuen Wert eingestellt werden. Wenn das nicht passiert und man erneut die Speichern-Schaltfl&auml;che bet&auml;tigt, speichert die Prozedur SaveKontakt den Kontakt erneut &#8211; in einem neuen Datensatz.<\/p>\n<p>Die hier vorgestellten Techniken sind eventuell nicht f&uuml;r die Quick-and-Dirty-Anwendung geeignet, die in einer halben Stunde programmiert werden und einen Tag halten soll. Wenn Sie aber den Wunsch versp&uuml;ren, leicht zu wartende und auch von anderen Personen leicht erfassbaren Code zu erstellen, werden Sie bald von der Anwendung der Klassenmodule begeistert sein.<\/p>\n<p>Einige interessante Techniken l&auml;sst dieser Beitrag bewusst offen, da sich weitere Beitr&auml;ge genauer damit besch&auml;ftigen &#8211; dazu geh&ouml;rt etwa die Verwendung des Collection-Objekts. Damit k&ouml;nnen Sie selbst Paare verkn&uuml;pfter Tabellen abbilden, indem Sie zu jeder Tabelle einen passenden Objekttyp erstellen, von denen der eine Objekte des anderen Typs in einer Collection erfassen kann. Um dieses Thema geht es im Beitrag Relationale Verkn&uuml;pfungen mit Objekten nachbilden in der der kommenden Ausgabe von Access im Unternehmen.<\/p>\n<p>Des Weiteren besteht die M&ouml;glichkeit, benutzerdefinierte Ereignisse f&uuml;r Objekte festzulegen &#8211; auch diese Eigenschaft beschreibt der vorliegende Beitrag nicht.<\/p>\n<p>Die Erzeugung von Objekttypen sollte &auml;u&szlig;erst sorgf&auml;ltig erfolgen, da diese unter Umst&auml;nden von vielen Stellen aus referenziert und gegebenenfalls auch in weiteren Anwendungen weiterverwendet werden sollen. Bei der Entwicklung ausgefeilter Klassen hilft eine spezielle Vorgehensweise &#8211; die so genannte Testgetriebene Entwicklung (aus dem Englischen: Test Driven Development, kurz: TDD). Dieser Methode widmet sich der Beitrag Testgetriebene Entwicklung mit Access, den Sie ebenfalls in dieser Ausgabe finden.<\/p>\n<h2>Downloads zu diesem Beitrag<\/h2>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>OOMitKlassen00.mdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/36A9113F-CEDF-4CEB-A35F-540FD3860B2C\/aiu_232.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>VBA wird im Allgemeinen die Eigenschaft abgesprochen, eine objektorientierte Programmiersprache zu sein. Um diese Aussage zu untersuchen, m&uuml;sste man erst einmal festlegen, ab wann eine Sprache objektorientiert ist und welche Eigenschaften f&uuml;r diese Bezeichnung vorhanden sein m&uuml;ssen. L&auml;sst man einmal au&szlig;en vor, dass Vererbung und Polymorphismus im VBA-Sprach&not;ge&not;brauch Fremdw&ouml;rter sind, kann man VBA sicher als objektorientierte Sprache auffassen. Wie auch immer &#8211; im vorliegenden Beitrag erfahren Sie, wie Sie sich die objektorientierten Eigenschaften von VBA zu Nutze 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":[662004,66052004,44000025],"tags":[],"class_list":["post-55000232","post","type-post","status-publish","format-standard","hentry","category-662004","category-66052004","category-VBA_und_Programmiertechniken"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.4) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Objektorientiertes Programmieren mit Klassen - Access im Unternehmen<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/access-im-unternehmen.de\/objektorientiertes_programmieren_mit_klassen\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Objektorientiertes Programmieren mit Klassen\" \/>\n<meta property=\"og:description\" content=\"VBA wird im Allgemeinen die Eigenschaft abgesprochen, eine objektorientierte Programmiersprache zu sein. Um diese Aussage zu untersuchen, m&uuml;sste man erst einmal festlegen, ab wann eine Sprache objektorientiert ist und welche Eigenschaften f&uuml;r diese Bezeichnung vorhanden sein m&uuml;ssen. L&auml;sst man einmal au&szlig;en vor, dass Vererbung und Polymorphismus im VBA-Sprach&not;ge&not;brauch Fremdw&ouml;rter sind, kann man VBA sicher als objektorientierte Sprache auffassen. Wie auch immer - im vorliegenden Beitrag erfahren Sie, wie Sie sich die objektorientierten Eigenschaften von VBA zu Nutze machen.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/objektorientiertes_programmieren_mit_klassen\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2023-02-10T14:49:24+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-02-19T08:15:06+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg06.met.vgwort.de\/na\/078cc562117c4a3a81756c25a6262675\" \/>\n<meta name=\"author\" content=\"Andr\u00e9 Minhorst\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andr\u00e9 Minhorst\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"21\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/objektorientiertes_programmieren_mit_klassen\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/objektorientiertes_programmieren_mit_klassen\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"Objektorientiertes Programmieren mit Klassen\",\"datePublished\":\"2023-02-10T14:49:24+00:00\",\"dateModified\":\"2024-02-19T08:15:06+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/objektorientiertes_programmieren_mit_klassen\\\/\"},\"wordCount\":3804,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/objektorientiertes_programmieren_mit_klassen\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/078cc562117c4a3a81756c25a6262675\",\"articleSection\":[\"2004\",\"5\\\/2004\",\"VBA und Programmiertechniken\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/objektorientiertes_programmieren_mit_klassen\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/objektorientiertes_programmieren_mit_klassen\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/objektorientiertes_programmieren_mit_klassen\\\/\",\"name\":\"Objektorientiertes Programmieren mit Klassen - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/objektorientiertes_programmieren_mit_klassen\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/objektorientiertes_programmieren_mit_klassen\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/078cc562117c4a3a81756c25a6262675\",\"datePublished\":\"2023-02-10T14:49:24+00:00\",\"dateModified\":\"2024-02-19T08:15:06+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/objektorientiertes_programmieren_mit_klassen\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/objektorientiertes_programmieren_mit_klassen\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/objektorientiertes_programmieren_mit_klassen\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/078cc562117c4a3a81756c25a6262675\",\"contentUrl\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/078cc562117c4a3a81756c25a6262675\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/objektorientiertes_programmieren_mit_klassen\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Objektorientiertes Programmieren mit Klassen\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"name\":\"Access im Unternehmen\",\"description\":\"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access\",\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/access-im-unternehmen.de\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\",\"name\":\"Andr\u00e9 Minhorst Verlag\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"contentUrl\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"width\":370,\"height\":111,\"caption\":\"Andr\u00e9 Minhorst Verlag\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\",\"name\":\"Andr\u00e9 Minhorst\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"caption\":\"Andr\u00e9 Minhorst\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Objektorientiertes Programmieren mit Klassen - Access im Unternehmen","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/access-im-unternehmen.de\/objektorientiertes_programmieren_mit_klassen\/","og_locale":"de_DE","og_type":"article","og_title":"Objektorientiertes Programmieren mit Klassen","og_description":"VBA wird im Allgemeinen die Eigenschaft abgesprochen, eine objektorientierte Programmiersprache zu sein. Um diese Aussage zu untersuchen, m&uuml;sste man erst einmal festlegen, ab wann eine Sprache objektorientiert ist und welche Eigenschaften f&uuml;r diese Bezeichnung vorhanden sein m&uuml;ssen. L&auml;sst man einmal au&szlig;en vor, dass Vererbung und Polymorphismus im VBA-Sprach&not;ge&not;brauch Fremdw&ouml;rter sind, kann man VBA sicher als objektorientierte Sprache auffassen. Wie auch immer - im vorliegenden Beitrag erfahren Sie, wie Sie sich die objektorientierten Eigenschaften von VBA zu Nutze machen.","og_url":"https:\/\/access-im-unternehmen.de\/objektorientiertes_programmieren_mit_klassen\/","og_site_name":"Access im Unternehmen","article_published_time":"2023-02-10T14:49:24+00:00","article_modified_time":"2024-02-19T08:15:06+00:00","og_image":[{"url":"http:\/\/vg06.met.vgwort.de\/na\/078cc562117c4a3a81756c25a6262675","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"21\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/objektorientiertes_programmieren_mit_klassen\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/objektorientiertes_programmieren_mit_klassen\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"Objektorientiertes Programmieren mit Klassen","datePublished":"2023-02-10T14:49:24+00:00","dateModified":"2024-02-19T08:15:06+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/objektorientiertes_programmieren_mit_klassen\/"},"wordCount":3804,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/objektorientiertes_programmieren_mit_klassen\/#primaryimage"},"thumbnailUrl":"http:\/\/vg06.met.vgwort.de\/na\/078cc562117c4a3a81756c25a6262675","articleSection":["2004","5\/2004","VBA und Programmiertechniken"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/objektorientiertes_programmieren_mit_klassen\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/objektorientiertes_programmieren_mit_klassen\/","url":"https:\/\/access-im-unternehmen.de\/objektorientiertes_programmieren_mit_klassen\/","name":"Objektorientiertes Programmieren mit Klassen - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/objektorientiertes_programmieren_mit_klassen\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/objektorientiertes_programmieren_mit_klassen\/#primaryimage"},"thumbnailUrl":"http:\/\/vg06.met.vgwort.de\/na\/078cc562117c4a3a81756c25a6262675","datePublished":"2023-02-10T14:49:24+00:00","dateModified":"2024-02-19T08:15:06+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/objektorientiertes_programmieren_mit_klassen\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/objektorientiertes_programmieren_mit_klassen\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/objektorientiertes_programmieren_mit_klassen\/#primaryimage","url":"http:\/\/vg06.met.vgwort.de\/na\/078cc562117c4a3a81756c25a6262675","contentUrl":"http:\/\/vg06.met.vgwort.de\/na\/078cc562117c4a3a81756c25a6262675"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/objektorientiertes_programmieren_mit_klassen\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"Objektorientiertes Programmieren mit Klassen"}]},{"@type":"WebSite","@id":"https:\/\/access-im-unternehmen.de\/#website","url":"https:\/\/access-im-unternehmen.de\/","name":"Access im Unternehmen","description":"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access","publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/access-im-unternehmen.de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/access-im-unternehmen.de\/#organization","name":"Andr\u00e9 Minhorst Verlag","url":"https:\/\/access-im-unternehmen.de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/","url":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","contentUrl":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","width":370,"height":111,"caption":"Andr\u00e9 Minhorst Verlag"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f","name":"Andr\u00e9 Minhorst","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","caption":"Andr\u00e9 Minhorst"}}]}},"_links":{"self":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000232","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/comments?post=55000232"}],"version-history":[{"count":1,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000232\/revisions"}],"predecessor-version":[{"id":88075290,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000232\/revisions\/88075290"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55000232"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55000232"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55000232"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}