Neuigkeiten:

Ist euer Problem gelöst, dann bitte den Knopf "Thema gelöst" drücken!

Mobiles Hauptmenü

VBA Projekt als Klassenbibliothek

Begonnen von Milvus, Oktober 23, 2018, 16:33:17

⏪ vorheriges - nächstes ⏩

markusxy

Zitat von: Milvus am November 02, 2018, 10:17:09Kann mir da jemand helfen, einen Tipp geben?

Deinen Verstand benützen - dann findet sich auch eine Lösung.  :)


Wurliwurm

Zitat von: Milvus am Oktober 26, 2018, 20:11:43
Aber das passt ganz gut in mein Konzept. Ich werde erst mal einige Klassenmodule sammeln und die zentral in einem Projekt zur Verfügung stellen. Dann glaube ich, ist der Schritt in eine echte Bibliothek nicht mehr so groß.
An Deiner Stelle würde ich mir wirklich überlegen, ob es sich nicht lohnen würde, sich in Plattformen einzuarbeiten, welche für solche mehrschichtigen Anwendungen konzipiert sind. Ich würde das, was Du vorhast, nicht tun, weil man da irgendwann in den Wald kommt und dann das ganze Access-mdb-mde-Knäuel in die Tonne wandern muß und monatelanges Frickeln dann für die Katz war. Google mal nach "dll hell" und "dependency hell".

Josef P.

#17
Hallo!

Zuerst zur eingebundenen "Bibliothek":
Du könntest die mde-Bibliothek als Add-In (mda/accda) einbinden, dann muss sie nicht als Verweis gesetzt sein. (Für die Entwicklung würde ich den Verweise schon nutzen, damit Intellisense zur Verfügung steht.)
Als Bibliothek könntest du aber auch eine COM-dll verwenden, die du mit .net schreibst.

Eine andere Variante ist der Umweg über eine "Starter-Anwendung" als mdb/accdb, die 2 mde-Biblitheken (eigentliche Anwendung und Bibliothek) nutzt. In einem AEK-Vortrag von Paul Rohorzka ist dieses Konzept erklärt.

Weiters:
Ist das Neusetzen des Pfades einer Bibliotheksdatei überhaupt notwendig, wenn du die Bibliotheks-mde im Anwendungsverzeichnis hast. Ich dachte, Access stellt das dann selbst um.


Nun zu der Variante, die ich in meinen Anwendungen verwende:
Jede Anwendung enthält alle notwendigen Codemodule. In diesem Code sind auch die wiederverwendbaren Module, welche automatisiert aktualisiert werden, falls ich die aktuelle Version in der jeweiligen Anwendung haben will. Verbessere ich in einer meiner Anwendung eines dieser wiederverwendbaren Codemodule, dann wird es aus dieser Anwendung in ein Repository eine Quellcodeverwaltung exportiert und kann (nach Tests) in den anderen Anwendungen wieder importiert werden.
Akutalisierungen gibt es bei dieser Variante natürlich nur durch ein Update der Anwendung. Das kann man als Nachteil aber auch als Vorteil betrachten.

mfg
Josef


Milvus

Info:

Ich habe eine Lösung im gefunden. Mittels Application.run kann eine Funktion in einem allgemeinen Modul der externen Datei gestartet werden, welche wiederum das Object des Klassenmoduls der externen Datei bildet und in der aufgerufenen Datei zur Verfügung steht.

Zumindest interpretiere ich den Ablauf so.


Milvus

Zitat von: Wurliwurm am November 09, 2018, 14:58:35
An Deiner Stelle würde ich mir wirklich überlegen, ob es sich nicht lohnen würde, sich in Plattformen einzuarbeiten, welche für solche mehrschichtigen Anwendungen konzipiert sind. Ich würde das, was Du vorhast, nicht tun, weil man da irgendwann in den Wald kommt und dann das ganze Access-mdb-mde-Knäuel in die Tonne wandern muß und monatelanges Frickeln dann für die Katz war. Google mal nach "dll hell" und "dependency hell".

Geht es um den Übergang von Klassenmodulen in eine dll oder den Ansatz eines zentralen Projekts generell (vermute ersteres)?

Das zentrale Projekt verschlankt erst mal das ganze Zeugs, da es nur einmal existiert. SO zumindest mein Ziel.

Wurliwurm

Zitat von: Milvus am November 14, 2018, 13:07:37
Zitat von: Wurliwurm am November 09, 2018, 14:58:35
An Deiner Stelle würde ich mir wirklich überlegen, ob es sich nicht lohnen würde, sich in Plattformen einzuarbeiten, welche für solche mehrschichtigen Anwendungen konzipiert sind. Ich würde das, was Du vorhast, nicht tun, weil man da irgendwann in den Wald kommt und dann das ganze Access-mdb-mde-Knäuel in die Tonne wandern muß und monatelanges Frickeln dann für die Katz war. Google mal nach "dll hell" und "dependency hell".
Geht es um den Übergang von Klassenmodulen in eine dll oder den Ansatz eines zentralen Projekts generell (vermute ersteres)?
Ob die Bibliothek als VB oder DLL vorliegt, macht prinzipiell keinen großen Unterschied in Bezug zu dem, was ich meine.
Der Unterschied zwischen einer guten verteilten Anwendung und Deiner Lösung ist, daß man bei ersterer Schnittstellen definieren kann und außerdem eine Versionskontrolle hat. Anschaulich:
Wenn der Client ein Objekt vom Typ XY von der zentralen Instanz haben will um darauf Methoden aufzurufen, wird zuerst eine Schnittstelle vom Typ IF_XY definiert mit dem ganzen ("vertraglich vereinbarten") Methoden. Die zentrale Instanz führt eine Registry, reagiert auf die Abfrage des Clients in der Registry nach Interface IF_XY und gibt ein passendes Objekt zurück. Vorteil ist, daß die zentrale Instanz jederzeit die interne Implementierung ändern kann, ohne daß es Änderungsbedarf bei den Clients gibt.
Bei Deiner Lösung sehe ich die Gefahr, daß bei Änderung ständig sowohl die Clients als auch das Programmrepository geändert werden müssen. Und daß es keine Kontrolle darüber gibt, wenn ein Client nicht (mehr) zur Repositorybibliothek passt. Es crasht dann immer erst zur Laufzeit.
Im Ergebnis mußt Du vieles per Hand nachprogrammieren (wie die Verlinkung der Bibliotheken in den Clients), was es alles schon fertig gibt und wo viele Mannjahre Entwicklung dafür investiert wurden.

markusxy

Zitat von: Milvus am November 02, 2018, 10:17:09
Jetzt zum Problem: Das neu Setzen des Verweises zum VB-Projekt funktioniert zwar bei mdb-Dateien, nicht aber bei einer kompilierten mde-Datei.

Ich hätte jetzt nicht geglaubt, dass diese Kleinigkeit zu so einem Problem wird.
Wenn du eine MDE in eine MDE einbinden willst, kannst du den Pfad der eingebundenen Datei nicht mehr ändern.
Ergo musst also dafür sorgen, dass am Entwicklungsrechner und am Client für die MDE mit den Funktionen der selbe Pfad verwendet wird.

Die Datei ins Netzwerk zu legen, halte ich für keine gute Idee.
Da sollte man an die Folgen bei Änderungen denken.
Wie du aber siehst ändern Programmierer ihre Ansichten im laufe der Zeit, was verschiedene Themen betrifft.
Aus meiner Sicht hat jede Vorgehensweise bestimmte Vorteile, und man soll einfach immer das passende nutzen.

Ich persönliche lege in die eingebundene Datei nur Methoden und Klassen für absolut allgemeine Funktionen rein die ich in jeder DB benötige und mit dadurch mit einem Schlag zur Verfügung stehen. Vor allem für meine viele Test DBs ist das ein großer Vorteil.

Ich mache das jetzt schon einige Zeit so.
Die ganzen Bedenken von Wurliwurm kann ich zwar nachvollziehen - sind aber kein Problem so lange man sich an gewisse Prinzipien hält.

Da kann man dann natürlich nicht einfach die Schnittstelle eines Codes ändern.
Es muss dann halt wie bei jeder Software "Abwärtskompatibilität" gesichert sein.

Gruß Markus

Josef P.

#22
Hallo!

ZitatWenn du eine MDE in eine MDE einbinden willst, kannst du den Pfad der eingebundenen Datei nicht mehr ändern.
Ergo musst also dafür sorgen, dass am Entwicklungsrechner und am Client für die MDE mit den Funktionen der selbe Pfad verwendet wird.
Wenn die Bibliothek-MDE im gleichen Verzeichnis (oder darunter) liegt, muss die Anwendung bzw. Bibliothek nicht im gleichen Ort wie auf dem Entwicklungsrechner liegen.

Der Nachteil bei einer mde-Anwendung mit einer verknüpften mde-Bibilothek ist, dass eine neue Version dieser Biblithek nicht mehr kompatibel zur alten Version ist und somit eine Neuerstellung der mde-Anwendung erforderlich wird. => Wird in der mde-Biblothek eine Funktion verbressert, ohne die Schnittstellen zu ändern, muss trotzdem die Anwendung neu verteilt werden. Daher nehme ich lieber gleich alle erforderlichen Code-Module in die Anwendung auf. Dann weiß ich wenigstens, das das zusammenpasst. ;)

Bei einer eingebundenen COM-dll muss die Anwendung nicht neu kompliert werden, wenn das Interface (inkl. GUID-Kennungen) von der alten Version unverändert bleiben.

mfg
Josef

markusxy

Zitat von: Josef P. am November 14, 2018, 21:48:33
Wenn die Bibliothek-MDE im gleichen Verzeichnis (oder darunter) liegt, muss die Anwendung bzw. Bibliothek nicht im gleichen Ort wie auf dem Entwicklungsrechner liegen.

Das wäre auf jeden Fall eine Erleichterung.
Muss ich mal testen.
Ich habe aber auch mit dem fixen Ordner kein Problem.

Zitat...Neuerstellung der mde-Anwendung erforderlich wird.

Ich weiß - ein Nachteil.
Es müssen dann beide Dateien neu erstellt werden.
Sollten also bei einem User mehrere Frontends die Datei eingebunden haben, müssen auch alle anderen Frontends neu erstellt werden.  ;D
Sollte man so arbeiten, ist man also gut beraten dass per Code erledigen zu lassen. Genauso die Updates beim User.
Bei den Updates müssen dann auch nach alle betroffenen Frontends geschlossen sein. Alles sehr mühsam.
Ich würde mir so was gar nicht anfangen.  ;D

Milvus

Zitat von: markus888 am November 14, 2018, 18:09:13
Ich persönliche lege in die eingebundene Datei nur Methoden und Klassen für absolut allgemeine Funktionen rein die ich in jeder DB benötige und mit dadurch mit einem Schlag zur Verfügung stehen. Vor allem für meine viele Test DBs ist das ein großer Vorteil.

Merci, exakt so!

Gebaut ist das Teil (geerbt) prozedural (Schachteln ohne Ende und das Modulüberbgreifend. Dann sind die Strukturen in unterschiedlichen Frontends (die unterschiedlichen Zwecken diesenen) nachgebaut und zu ca. 70% identisch). D.h. die beschriebene Situation liegt hier eigentlich schon vor.  :(

Ich arbeite vorzugsweise mit cls-Modulen, bzw. will die Menge dieser ausbauen. Mein Ziel ist ja genau das, aus dem Wald rauszukommen (zumindest ein Stück weit). Von einer echten Bibliothek sind wir weit entfernt und ich hab schon Mühe, die cls durchzukämpfen. Aber nicht nur das, ich arbeite strickt modular, d.h. ich hab was, das kopiere ich irgendwo rein und das läuft, Punkt! So nutze ich nun z.B. Formulare, die in mehrere Anwendungen gebraucht werden und halte die identisch, diese wiederum nutzen die Libary. D.h., ich kopier ein Formular irgendwo rein und es läuft!

Also ich habe jetzt jedenfalls eine positive Erfahrung: Ich habe eine cls-Libary gebaut, die bei der Verteilung mit in das gleiche Verzeichnis gelegt wird. Aufruf dann der cls über Public Functions über Application run ohne direkren Verweis!



markusxy

Zitat von: Milvus am November 16, 2018, 16:01:16
Also ich habe jetzt jedenfalls eine positive Erfahrung: Ich habe eine cls-Libary gebaut, die bei der Verteilung mit in das gleiche Verzeichnis gelegt wird. Aufruf dann der cls über Public Functions über Application run ohne direkren Verweis!

Das ist (aus meiner Sicht) die schlechtest mögliche Variante.
Schlechte Performance, ohne die Möglichkeit für den Compiler zu prüfen, Error Handling problematisch.
Run bzw. CallByName sollte man wirklich nur für absolute Notfälle verwenden.

LG M

Josef P.

Hallo!

Auch wenn ich selbst nicht diese Variante verwenden würde, finde ich die Vorgehensweise über ein per VBA aufgerufenes Add-In nicht so kiritisch.
Es ist zumindest bei einer Access-Bibliothek eine Möglichkeit die Bibliothek auszutauschen, ohne die Anwendung (mde) austauschen zu müssen.
Man muss bei mehreren Anwendungen, die diese Bibliothek verwenden, aber sehr sorgfältig prüfen, dass keine Schnittstellenverletzungen gemacht werden.

ZitatSchlechte Performance, ...
Das muss meiner Meinung nach nicht unbedingt sein. Man könnte einmal über Application.Run eine Instanz einer Klasse holen, mit der man dann für alle anderen Klassen aus der Bibliothek Instanzen erstellen kann.

Der Earlybinding vs. Latebinding-Geschwindigkeitsunterschied besteht natürlich. Der dürfte aber vernachlässigbar (vermutlich gar nicht messbar) sein.

Zitat... ohne die Möglichkeit für den Compiler zu prüfen, ...
Zur Entwicklungszeit könnte man mit Verweis auf die Bibliothek arbeiten und diesen erst vor Auslieferung auf die "Add-In"-Technik umstellen.

ZitatError Handling problematisch.
Fehler sollten eigentlich schon nach oben weitergereicht werden.

ZitatRun bzw. CallByName sollte man wirklich nur für absolute Notfälle verwenden.
Da gilt wie immer: Wenn man weiß, was man tut, kann man vieles machen, auch wenn es für "Anfänger" nicht empfehlenswert ist. ;)


@Milvus:
Verwendest du für deinen Code eine Quellcodeverwaltung bzw. hast dich damit schon einmal beschäftigt?
Damit kann man nämlich wiederverwendbaren Code sehr gut verwalten und in die Anwendungen integrieren.
Wenn man dann für den wiederverwendbaren Code automatisierte Tests gestaltet, können auch mögliche Schnittstellenprobleme u. ä. frühzeitig erkannt werden.

mfg
Josef

Lachtaube

@Josef

schließen Add-Ins nicht die Nutzung einer Access-Runtime-Umgebung aus?

Ich integriere bis auf wenige Ausnahmen auch immer den kompletten Code ins Frontendend. Ausnahmen sind komplexe oder zeitkritische Methoden, die sich in VBA nur schwierig realisieren lassen.  Dafür verwende ich vorzugsweise klassische DLLs, die allerhöchstens als externe Abhängigkeit die auf allen Windows-Rechnern installierte msvcrt.dll aufweisen.
Grüße von der (⌒▽⌒)

Josef P.

Hallo!

Zitatschließen Add-Ins nicht die Nutzung einer Access-Runtime-Umgebung aus?
Ich bin nicht sicher, ob Application.Run mit einer Access-Runtime-Version läuft, da ich das nur für Entwickler-Aufrufe verwende.

ZitatIch integriere bis auf wenige Ausnahmen auch immer den kompletten Code ins Frontendend.
So mache ich das auch. Die Ausnahmen sind allerdings auch keine Access-Bibliotheken sondern COM-dlls, welche ich mit C# erstelle.

Das Einspielen des wiederverwendbaren Code sieht bei mir so aus:
http://access-codelib.net/videos/ACLib-Import-Wizard/neue-anwendung-erstellen/neue-anwendung-erstellen.mp4

mfg
Josef

markusxy

@Josef,
ich war wohl unpräzise:
Run und CallbyName brauchen ein vielfaches der Zeit wie direkte Aufrufe.
Run gibt keinen Error weiter.

Diese Punkte sind für mich aber nur bei einfachen Prozeduren und Funktionen von Bedeutung.
Die machen bei mir aber sicher 60% aus.

Bei Klassen müsste alles per LateBinding funktionieren.
Im Frontend müsste man immer als Objekt deklarieren, da die Klasse unbekannt ist.
Der Compiler kann also keine Änderungen der Schnittstellen feststellen.
Ein absolutes NO GO.

Im Vergleich zum direkten einbinden eine ganze Menge Nachteile, gegenüber praktisch Zero Vorteilen.
Keine gute Bilanz.