Discussion:
Access VBA: Klassenmodul schreiben
(zu alt für eine Antwort)
Thomas Schulze
2009-04-30 11:55:02 UTC
Permalink
Hallo,

ich habe mal wieder ein Problem.

In Access möchte ich eigene Klassen definieren, die so in ungefähr wie
das Collection-Objekt arbeitet.

Konkret hätte ich gerne folgendes:

ich definiere das Ding als "Mitglieder", und durch den Aufruf
"Mitglieder()" erhalte ich ein Array mit allen Namen drin. Mit
"Mitglieder.add("Benni Beispiel") füge ich ein neues Mitglied hinzu,
das dann wieder Eigenschaften hat. Mit "Mitglieder("Benni Beispiel")"
bekomme ich einen String zurück mit den Detaileigenschaften des
entsprechenden Mitglieds, oder könnte per "Mitglieder("Benni
Beispiel").BeitragBezahlt=true" diese auch verändern.

Also brauche ich einmal eine Klasse für ein einzelnes Mitglied und
dann eine Liste aller Mitglieder.

Wie stelle ich das nun an? Ich bräuchte ja einmal eine Methode, die
beim Aufruf der Liste standardmäßig aufgerufen wird und dann eben das
String-Array zurückliefert, und dann eine zweite Methode die beim
Aufruf der Liste mit einem Parameter aufgerufen wird, und eben das
Mitglied zurückliefert. Genau hier fehlt mir der Ansatz, wie ich das
anstellen kann.

Wie kriege ich das elegant gelöst?

Danke schonmal und Gruß, Thomas
Stefan Hoffmann
2009-04-30 12:41:41 UTC
Permalink
hallo Thomas,
Post by Thomas Schulze
Wie kriege ich das elegant gelöst?
http://www.databaseadvisors.com/newsletters/newsletter200503/0503usingcustomcollections/using%20custom%20collections%20in%20microsoft%20access.asp


mfG
--> stefan <--
--
Access-FAQ http://www.donkarl.com/
KnowHow.mdb http://www.freeaccess.de
Newbie-Info http://www.doerbandt.de/Access/Newbie.htm
Thomas Schulze
2009-04-30 13:14:35 UTC
Permalink
Hallo Stefan,

danke für den Link.

Bei einer echten Collection ist es jedoch möglich, die Elemente sowohl
mit "blablubb(3)" als auch mit "blablubb.Items(3)" anzusprechen.
Sowohl im Beispiel als auch bei meiner Bastelei, die auf ein ähnliches
Ergebnis rausläuft, klappt das nicht.

Gibt es dazu noch einen Trick?

Was ich auch schade finde ist, dass ich nicht ".Add" doppelt vergeben
kann mit einmal "Add(Contact)" und einmal "Add(Name, Telefon,
Rating)". Das schneidet er im Beispiel zwar an, löst es aber nicht.
Ich denke, mit der in VBA fehlenden Option, dieselbe Methode einfach
zweimal zu definieren, ist das auch nur sehr umständlich möglich.

Gruß, Thomas
Mark Doerbandt
2009-04-30 13:34:41 UTC
Permalink
Hallo, Thomas,
Post by Thomas Schulze
Bei einer echten Collection ist es jedoch möglich, die Elemente sowohl
mit "blablubb(3)" als auch mit "blablubb.Items(3)" anzusprechen.
Sowohl im Beispiel als auch bei meiner Bastelei, die auf ein ähnliches
Ergebnis rausläuft, klappt das nicht.
Gibt es dazu noch einen Trick?
das hat Paul in einem seiner AEK-Vorträge beschrieben, ich denke in

http://www.donkarl.com/AEK/AEKDownloads/AEK7_Klassen.zip

oder

http://www.donkarl.com/AEK/AEKDownloads/AEK8_Klassen_konkret.zip
Post by Thomas Schulze
Was ich auch schade finde ist, dass ich nicht ".Add" doppelt vergeben
kann mit einmal "Add(Contact)" und einmal "Add(Name, Telefon,
Rating)". Das schneidet er im Beispiel zwar an, löst es aber nicht.
Ich denke, mit der in VBA fehlenden Option, dieselbe Methode einfach
zweimal zu definieren, ist das auch nur sehr umständlich möglich.
Gar nicht? Nutze .net ... ;-)

Gruss - Mark
--
Informationen fuer Neulinge in den Access-Newsgroups unter
http://www.doerbandt.de/Access/Newbie.htm

Bitte keine eMails auf Newsgroup-Beiträge senden.
Thomas Möller
2009-04-30 15:40:33 UTC
Permalink
Hallo Thomas,
Post by Mark Doerbandt
Post by Thomas Schulze
Bei einer echten Collection ist es jedoch möglich, die Elemente sowohl
mit "blablubb(3)" als auch mit "blablubb.Items(3)" anzusprechen.
Sowohl im Beispiel als auch bei meiner Bastelei, die auf ein ähnliches
Ergebnis rausläuft, klappt das nicht.
Gibt es dazu noch einen Trick?
das hat Paul in einem seiner AEK-Vorträge beschrieben, ich denke in
http://www.donkarl.com/AEK/AEKDownloads/AEK7_Klassen.zip
oder
http://www.donkarl.com/AEK/AEKDownloads/AEK8_Klassen_konkret.zip
auf Basis von Pauls Vortrag (und mit seinem konstruktiven Feedback) habe
ich ein kleines Add-In geschrieben. Dieses Add-In erlaubt es, eine
beliebige Tabelle aus einer Datenbank auszuwählen und daraus zwei
Klassen erstellen zu lassen. Eine Klasse für die einzelnen Elemente und
eine Klasse, die die Auflistung der einzelnen Elemente (Datensätze) enthält.
Vielleicht findest Du in den von diesem Add-In generierten Klassen noch
einige Anregungen.

Du findest den TM DatenKlassenGenerator hier:
http://www.team-moeller.de/access/add-ins/accdatenklassengenerator.html
(Link in einer Zeile)

HTH
--
Thomas

Homepage: www.Team-Moeller.de
Thomas Wolf
2009-05-05 09:49:33 UTC
Permalink
Hallo Thomas
Post by Thomas Möller
http://www.team-moeller.de/access/add-ins/accdatenklassengenerator.html
(Link in einer Zeile)
Ich habe Deinen Generator bei mir eingefügt und wollte ihn testen. Als ich
die Klassen einfügen wollte, kam die Meldung: "VBA-Projekt ist durch ein PW
geschützt". Dies ist aber nicht der Fall. Es scheint so, als würde der Code
versuchen, die Klassen in Deinem .mda zu erstellen, womit die Meldung
korrekt wäre. Ich kann ja nicht viel anderes machen als das AddIn einfach
aufrufen, oder? Habe A03 auf WXP Pro.

Du hast noch eine Auflistung über die geplanten Erweiterungen integriert.
Sind die immer noch geplant? :o)

Gruss
Thomas
Thomas Möller
2009-05-05 15:39:40 UTC
Permalink
Hallo Thomas,
Post by Thomas Wolf
Post by Thomas Möller
http://www.team-moeller.de/access/add-ins/accdatenklassengenerator.html
(Link in einer Zeile)
Ich habe Deinen Generator bei mir eingefügt und wollte ihn testen. Als
ich die Klassen einfügen wollte, kam die Meldung: "VBA-Projekt ist durch
ein PW geschützt". Dies ist aber nicht der Fall. Es scheint so, als
würde der Code versuchen, die Klassen in Deinem .mda zu erstellen, womit
die Meldung korrekt wäre. Ich kann ja nicht viel anderes machen als das
AddIn einfach aufrufen, oder? Habe A03 auf WXP Pro.
dieser Fehler wurde mir schon einmal berichtet. IIRC hat es damals
geholfen, das Add-In einfach noch einmal neu zu starten.
Ich selber habe diesen Fehler noch nicht feststellen können. Daher fehlt
mir gerade auch die Idee, an welcher Stelle ich den Code ändern müsste.
Ist der Fehler nur einmal aufgetreten? Oder tritt er laufend auf?
Post by Thomas Wolf
Du hast noch eine Auflistung über die geplanten Erweiterungen
integriert. Sind die immer noch geplant? :o)
Momentan liegen meine Prioritäten bei anderen Projekten. ;-)
Aber vielleicht findet sich ja mal die Zeit, die Ideen umzusetzen.
Welches Feature würde Dich denn am meisten interessieren?

CU
--
Thomas

Homepage: www.Team-Moeller.de
Thomas Wolf
2009-05-06 08:27:29 UTC
Permalink
Hallo Thomas
Post by Thomas Möller
dieser Fehler wurde mir schon einmal berichtet. IIRC hat es damals
geholfen, das Add-In einfach noch einmal neu zu starten.
Ich selber habe diesen Fehler noch nicht feststellen können. Daher fehlt
mir gerade auch die Idee, an welcher Stelle ich den Code ändern müsste.
Ist der Fehler nur einmal aufgetreten? Oder tritt er laufend auf?
In einer neuen DB funktioniert es
Post by Thomas Möller
Momentan liegen meine Prioritäten bei anderen Projekten. ;-)
Aber vielleicht findet sich ja mal die Zeit, die Ideen umzusetzen. Welches
Feature würde Dich denn am meisten interessieren?
Mich? Nun die Erstellung und Berücksichtigung in einem Formular,
Fehlerbehandlung
Als Idee: Eine Beschreibung der Funktionen, damit auch 'Klassenneulinge'
sich schneller zurecht finden.

Noch eine Anmerkung zur Element-Klasse: Bei den Deklarationen steht z.B.
"Private Const mcf_streld1... "
Sollte das nicht "mcf_strFeld1" heissen? Es ist überall das 'F' abhanden
gekommen. Aber hat natürlich keinen Einfluss auf die Funktionalität, nur auf
die Lesbarkeit.

Gruss
Thomas
Thomas Schulze
2009-05-06 06:35:33 UTC
Permalink
Hallo,

erstmal danke für die hilfreichen Antworten.
Post by Mark Doerbandt
Post by Thomas Schulze
Gibt es dazu noch einen Trick?
das hat Paul in einem seiner AEK-Vorträge beschrieben, ich denke in
 http://www.donkarl.com/AEK/AEKDownloads/AEK7_Klassen.zip
Das war es. Ich habe mich ein wenig abgequält, aber so sollte es
gleich gehen:
Keinen Kommentar in der Attribute-Zeile. Ich hatte den erst
mitkopiert, aber nix da. Nur den Code einfügen ohne den Kommentar
hintendran.
Und: die Zeile gleich hinter die Definition von der Property oder vom
Sub. Keine Kommentare zwischendrin.

Ich bin ans Kommentieren gewöhnt und habe mir einen Wolf gesucht.
Vielleicht klappt es bei anderen mit dem Hinweis schneller.
Post by Mark Doerbandt
Gar nicht? Nutze .net ... ;-)
Oh wei, ich glaube das wird nichts. Einmal tauchen meine Klassen in
Access auf, einmal kommen sie gleich mit rüber in eine Nicht-Office-
Anwendung, die VBA lizenziert hat. Keine Ahnung ob das mit .net auch
geht. Und ob es dafür so ein Gespann gibt wie bei Java, frei
erhältlichen "Compiler" und frei erhältliche Arbeitsumgebung wie
Eclipse.

Nochmals vielen Dank für die tollen Tipps.

Gruß, Thomas
Mark Doerbandt
2009-05-06 07:39:26 UTC
Permalink
Hallo, Thomas,
Post by Thomas Schulze
Post by Mark Doerbandt
Gar nicht? Nutze .net ... ;-)
Oh wei, ich glaube das wird nichts. Einmal tauchen meine Klassen in
Access auf, einmal kommen sie gleich mit rüber in eine Nicht-Office-
Anwendung, die VBA lizenziert hat. Keine Ahnung ob das mit .net auch
geht. Und ob es dafür so ein Gespann gibt wie bei Java, frei
erhältlichen "Compiler" und frei erhältliche Arbeitsumgebung wie
Eclipse.
jo, portablen Code kann man natuerlich auch mit .net schreiben,
allerdings dann nicht mehr VBA - auch wenn VB.net und VBA ähnlich sind
(Jehova!). VB Express ist imo besser als Eclipse und auch frei, der
Compiler sowieso.

Gruss - Mark
--
Informationen fuer Neulinge in den Access-Newsgroups unter
http://www.doerbandt.de/Access/Newbie.htm

Bitte keine eMails auf Newsgroup-Beiträge senden.
Thomas Schulze
2009-05-06 09:03:49 UTC
Permalink
Hallo,

darf ich hier nochmal nachhaken?
Post by Mark Doerbandt
jo, portablen Code kann man natuerlich auch mit .net schreiben,
allerdings dann nicht mehr VBA - auch wenn VB.net und VBA ähnlich sind
(Jehova!).
Mein Arbeitsablauf sieht mit VBA bisher so aus: Chef kommt mit schier
unlösbarer Aufgabe, ich werfe Access an oder Excel oder was auch immer
ich für am sinnvollsten erachte, drücke Alt+F11 und bin "zuhause".
Dann löse ich das Ding irgendwie.

Wie würde sowas in der Grundstruktur in VB.net aussehen? Da müsste ich
ja dann auch an die Anwendungen (meist Access/Excel) andocken, wo
bisher VBA einfach "drinsteckt". Also mein Programm oder Modul müsste
ja dann in Access bekannt gemacht werden.
Post by Mark Doerbandt
VB Express ist imo besser als Eclipse und auch frei, der Compiler sowieso.
Bevor ich hier ein "Pffft" werfe, teste ich das lieber selbst ;-)

Gruß, Thomas
Mark Doerbandt
2009-05-06 09:11:55 UTC
Permalink
Hallo, Thomas,
Post by Thomas Schulze
darf ich hier nochmal nachhaken?
gerne doch.
Post by Thomas Schulze
Mein Arbeitsablauf sieht mit VBA bisher so aus: Chef kommt mit schier
unlösbarer Aufgabe, ich werfe Access an oder Excel oder was auch immer
ich für am sinnvollsten erachte, drücke Alt+F11 und bin "zuhause".
Dann löse ich das Ding irgendwie.
Wie würde sowas in der Grundstruktur in VB.net aussehen? Da müsste ich
ja dann auch an die Anwendungen (meist Access/Excel) andocken, wo
bisher VBA einfach "drinsteckt". Also mein Programm oder Modul müsste
ja dann in Access bekannt gemacht werden.
Wenn die Zielplattform Office ist, würde auch ich bei VBA bleiben.
VSTO als .net-Pendant ist aus meiner Sicht etwas umständlich und auch
nicht besonders verbreitet. Da mag ich mich mangels Erfahrung aber
irren. Wenn Du wie ich in VBA "zu Hause" bist, ist das natürlich
(gerade was RAD angeht, besonders in Access) der einfachste und imo
auch richtige Weg.

Die Anmerkung bezog sich ja eigentlich auf Deinen Wunsch, Methoden
überladen zu können - das kann VBA leider nicht.
Post by Thomas Schulze
Post by Mark Doerbandt
VB Express ist imo besser als Eclipse und auch frei, der Compiler sowieso.
Bevor ich hier ein "Pffft" werfe, teste ich das lieber selbst ;-)
Jo, mach mal. Ist ganz Ernst gemeint. Die Visual Studio IDE ist das
beste, was ich kenne. Ich habe auch mit Eclipse gearbeitet und sicher
gibt es da das eine oder andere nette Feature, aber in Summe ist VS
mein eindeutiger Favorit. Aber das gehört wohl hier nicht wirklich
her, daher mache ich da mal schnell Schluss. ;-)

Gruss - Mark
Josef Poetzl
2009-05-06 09:47:14 UTC
Permalink
Hallo!
Post by Thomas Schulze
Post by Mark Doerbandt
jo, portablen Code kann man natuerlich auch mit .net schreiben,
allerdings dann nicht mehr VBA - auch wenn VB.net und VBA ähnlich sind
(Jehova!).
Mein Arbeitsablauf sieht mit VBA bisher so aus: Chef kommt mit schier
unlösbarer Aufgabe, ich werfe Access an oder Excel oder was auch immer
ich für am sinnvollsten erachte, drücke Alt+F11 und bin "zuhause".
Dann löse ich das Ding irgendwie.
Wie würde sowas in der Grundstruktur in VB.net aussehen? Da müsste ich
ja dann auch an die Anwendungen (meist Access/Excel) andocken, wo
bisher VBA einfach "drinsteckt". Also mein Programm oder Modul müsste
ja dann in Access bekannt gemacht werden.
Falls die von dir erstellte Routine/Anwendung/"oder was auch immer"
für unterschiedliche Excel-/Access-Dateien genutzt soll, könntest du
ein COM-AddIn erstellen.

Wenn du nur die Office-Dokumente fernsteuern willst, kannst du unter
.net die jeweiligen Bibliotheken einbinden und die Anwendungen mittels
Automation steuern. (auch Latebinding wäre möglich)

Falls du den Code nur als Bibliothek für VBA nutzen willst, würde eine
COM-dll passen. (Eine "normale" .net-dll kann leider nicht verwendet
werden.)
Anm.: In der COM-Biblothek kann aber eine Methode auch nicht
unterschiedlich belegt werden (2x Add() mit unterschiedlichen
Parametern ist nicht möglich). Falls du so etwas einsetzen willst,
müsstet du das im jeweiligen Code berücksichtigen.
Diese "Umgehung" funktioniert dann aber auch unter VBA.

Prinzip:
| Add(Contact)
| Add(Name, Telefon, Rating)
Public Sub Add(optional byval NameOderContact as variant, _
Optional Byval Telefon as variant, _
optional byval Rating as variant)

If VarType(NameOderContact) = vbString Then
addName NameOderContact, Telefon, Rating
ElseIf IsNumeric(NameOderContact) Then
addContact NameOderContact
End If

end sub

private sub addContact(byval contact as long)
...
end sub
private sub addName(byval sName as string, ...)
...
end sub

Die Prüfungen mit VarType bzw. IsNumeric sind nur als Beispiel zu
sehen. Welche Prüfungsart sinnvoll ist, hängt vom Einsatz ab.
Post by Thomas Schulze
Post by Mark Doerbandt
VB Express ist imo besser als Eclipse und auch frei, der Compiler sowieso.
Bevor ich hier ein "Pffft" werfe, teste ich das lieber selbst ;-)
Du kannst auch SharpDevelop einsetzen. :-)


mfg
Josef
Thomas Schulze
2009-05-06 11:07:06 UTC
Permalink
Hallo,
Post by Josef Poetzl
Falls du den Code nur als Bibliothek für VBA nutzen willst, würde eine
COM-dll passen. (Eine "normale" .net-dll kann leider nicht verwendet
werden.)
Also hätte ich dann eine DLL, in der meine verschachtelten Klassen
drinliegen. Und sobald die mitgeladen ist, kann ich die sowohl in
Excel als auch in Access als auch in der verwendeten
Steuerungssoftware einspielen, die auch VBA kann? Klingt gut.
Post by Josef Poetzl
Anm.: In der COM-Biblothek kann aber eine Methode auch nicht
unterschiedlich belegt werden (2x Add() mit unterschiedlichen
Parametern ist nicht möglich). Falls du so etwas einsetzen willst,
müsstet du das im jeweiligen Code berücksichtigen.
Diese "Umgehung" funktioniert dann aber auch unter VBA.
| Add(Contact)
| Add(Name, Telefon, Rating)
Public Sub Add(optional byval NameOderContact as variant, _
               Optional Byval Telefon as variant, _
               optional byval Rating as variant)
Das hätte doch die Konsequenz, dass ich das prinzipiell aufrufen
könnte mit 'Add("Name des Kunden")' und im weiteren Code selbst
nachprüfen muss, ob die Parameter stimmen oder einen Fehler werfen?

Da finde ich die Java-Möglichkeit mit zwei verschiedenen Add()s
schöner gelöst, da bekomme ich gleich in der IDE einen Fehler
zurückgemeldet, dass das so nicht passt. Und Java nicht um
irgendwelche Glaubenskriege anzuzetteln, sondern weil ich das schlicht
besser kann als .net.

Folglich mit der DLL den Code zweifach nutzen, aber bei Add() und
AddContact() bleiben.

Gruß, Thomas
Josef Poetzl
2009-05-06 12:55:01 UTC
Permalink
Hallo!
Post by Thomas Schulze
Post by Josef Poetzl
Falls du den Code nur als Bibliothek für VBA nutzen willst, würde eine
COM-dll passen. (Eine "normale" .net-dll kann leider nicht verwendet
werden.)
Also hätte ich dann eine DLL, in der meine verschachtelten Klassen
drinliegen. Und sobald die mitgeladen ist, kann ich die sowohl in
Excel als auch in Access als auch in der verwendeten
Steuerungssoftware einspielen, die auch VBA kann? Klingt gut.
Im Prinzip so:
dim x as object
set x = CreateObject("DeineLib.StartKlasse")

oder auch per Early binding, wenn du den Verweis auf die Lib setzt:
dim x as DeineLib.StartKlasse
set x = new DeineLib.StartKlasse

Bei .net-COM sieht das im VBA-Code genauso aus. im Hintergrund läuft
das aber etwas anders ab, als bei den "normalen" COM-dll.
Wenn du ein wenig auf den MSDN/.net-Seiten suchst, solltest du einiges
über die COM(Component Object Model)-Erstellung aus .net finden.

Wenn ich mich richtig erinnere, kann es z. B. unter Office 2003 mit
.net-COM Probleme geben, wenn hohe Makrosicherheit eingestellt ist.
Post by Thomas Schulze
Post by Josef Poetzl
Anm.: In der COM-Biblothek kann aber eine Methode auch nicht
unterschiedlich belegt werden (2x Add() mit unterschiedlichen
Parametern ist nicht möglich). Falls du so etwas einsetzen willst,
müsstet du das im jeweiligen Code berücksichtigen.
Diese "Umgehung" funktioniert dann aber auch unter VBA.
| Add(Contact)
| Add(Name, Telefon, Rating)
Public Sub Add(optional byval NameOderContact as variant, _
               Optional Byval Telefon as variant, _
               optional byval Rating as variant)
Das hätte doch die Konsequenz, dass ich das prinzipiell aufrufen
könnte mit 'Add("Name des Kunden")' und im weiteren Code selbst
nachprüfen muss, ob die Parameter stimmen oder einen Fehler werfen?
Ich ging davon aus, dass Contact eine Zahl ist und die ID deines
Datensatzes beinhaltet. Da vermutlich niemand 12234 heißen wird,
könnte das eine ausreichende Trennung sein.

Prinzip wie bei
DaoRecordset.Fields("abc") und DaoRecordset.Fields(17)
Post by Thomas Schulze
Da finde ich die Java-Möglichkeit mit zwei verschiedenen Add()s
schöner gelöst, da bekomme ich gleich in der IDE einen Fehler
zurückgemeldet, dass das so nicht passt.
Das ist auf jeden Fall besser. Nur kann das VBA eben nicht. ;-)
Post by Thomas Schulze
Und Java nicht um
irgendwelche Glaubenskriege anzuzetteln, sondern weil ich das schlicht
besser kann als .net.
... mit der Ausnahme, dass du Java imo überhaupt nicht in VBA nutzen
kannst. Oder gibt es eine Möglichkeit die COM-Schnittstelle mit Java
zu bedienen? (Ich kann es mir aufgrund der doch sehr großen
Unterschiede im Aufbau nicht vorstellen.)
Post by Thomas Schulze
Folglich mit der DLL den Code zweifach nutzen, aber bei Add() und
AddContact() bleiben.
Oder so:
xxx.Contacts.Add()
xxx.Wasweißich.Add()


mfg
Josef
--
EPT: (Access Error Prevention Table) http://access.joposol.com/
FAQ: (Access-FAQ von Karl Donaubauer) http://www.donkarl.com/
Thomas Möller
2009-05-06 15:34:36 UTC
Permalink
Hallo Thomas,
Post by Thomas Schulze
Post by Josef Poetzl
Falls du den Code nur als Bibliothek für VBA nutzen willst, würde eine
COM-dll passen. (Eine "normale" .net-dll kann leider nicht verwendet
werden.)
Also hätte ich dann eine DLL, in der meine verschachtelten Klassen
drinliegen. Und sobald die mitgeladen ist, kann ich die sowohl in
Excel als auch in Access als auch in der verwendeten
Steuerungssoftware einspielen, die auch VBA kann? Klingt gut.
wenn Du dieses Thema vertiefen möchtest, dann kannst Du Dir mal diesen
Artikel näher ansehen:
http://msdn.microsoft.com/de-de/library/aa902693(en-us).aspx
(Link in einer Zeile)

CU
--
Thomas

Homepage: www.Team-Moeller.de
Loading...