Hallo,
ich habe verschiedene kleine Klassen dich ich nur initialisieren möchte und darin immer die gleiche Funktion aufrufe z. B. so:
Dim vObject = MeineKlasse1 'MeineKlasse2 usw.
Set vObject = New MeineKlasse1(vNotesDocument) 'Datentyp NotesDocument soll übergeben werden
Call vObject.Run()
Welche der Klassen aufgerufen wird, soll mittels eines Formular entschieden werden. Also steht dies erst zur Laufzeit fest.
Da ich ich davon ausgehe, dass die Anzahl dieser kleinen Klassen immer mehr werden, wollte ich mir ein Mapping ersparen. Mit der Funktion Execute bin ich leider auch nicht weiter gekommen, da diese keine Objekte zurückgibt. Nun kann ich sicher alle Klassen Public setzen und das Call vObject.Run() im Execute ausführen aber wäre auch nicht so schön ::) (zumal die Klassen Public sein müssten).
Ich hoffe, dass ich mich einigermaßen verständlich ausgedrückt habe... ;) Kennt ihr eine Möglichkeit das (besser) zu lösen?
Vielen Dank und schönen Feierabend.
Gruß Kristian
Man kann in Lotus Script Vererbung, Polymorphie und eine Anlehnung an das Pattern Fabrikmethode (https://de.wikipedia.org/wiki/Fabrikmethode) für die Lösung deines Problems nutzen:
1. Schaffe eine Oberklasse zu deinen MeineKlasseX, nennen wir Sie MeineOberKlasse
2. In der Oberklasse erstelle eine Methode Run(), die nichts tut.
3. Deine Meine Klasse leitet von MeineOberKlasse ab und implementiert die Methode Run(). Wenn ich mich recht erinnere ging das etwa so (https://www.ibm.com/developerworks/lotus/library/ls-object_oriented_LotusScript):
Class MeineKlasseX As MeineOberklasse
...
4. Für die dynamische Auswahl der richtigen MeineKlasse erstellst du dir eine Function, die dir kontextabhängig eine Instanz der richtigen Unterklasse zurückgibt. Das ist dann die Fabrikmethode, wie eingangs erwähnt.
Hallo Kristian,
per Execute ist es auch machbar. Im Internet gibt es diese Beispiele zu finden ("Dynamic Lotusscript"). Hier ist meine Umsetzung dazu.
Zuerst eine Scriptbibliothek anlegen (z.B. "libNewObj") und dort die zwei globale Variablen in Declarations definieren:
Private vntFactories List As Variant
Public vntNewObj_factory As Variant
Dann diese Funktion in die Scriptblibliothek einfügen:
Function fktNewObj( strClassName As String ) As Variant
'Fehlerbehandlung
On Error GoTo Error_Handler
'
'Variablendeklaration
Dim strScript As String
'
'Prozedur
If Not IsElement(vntFactories(strClassName)) Then
strScript = |
Use "| & strClassName & |"
Sub Initialize
Set vntNewObj_factory = New | & strClassName & |Factory
End Sub
|
Execute (strScript)
Set vntFactories(strClassName) = vntNewObj_factory
End If
Set fktNewObj = vntFactories(strClassName).produce
e:
Exit Function
Error_Handler:
Set fktNewObj = Nothing
'... hier entsprechendes Error-Handling einfügen
Resume e
End Function
In jeder deiner Scriptbibliotheken muss dann zusätzlich zu deiner Klasse eine weitere (Mini-)Klasse angelegt werden:
Class MeineKlasse1Factory
Function produce As Variant
Set produce = New MeineKlasse1
End Function
End Class
In der Maske oder auch z.B. einem Agent muss in den Options
eingefügt werden und dann per Aufruf der Funktion fktNewObj verwendet werden:
Dim strKlasse As String
' Variable mit dem Klassennamen setzen (in deinem Beispiel z.B. aus einem Feldwert)
strKlasse = "MeineKlasse1"
' neues Objekt zu der Klasse erzeugen
Set objMeineKlasse1 = fktNewObj(strKlasse)
' Methode der Klasse im Objekt aufrufen
Call objMeineKlasse1.Run()
Leider können keine Parameter direkt übergeben werden, aber das kann man umgehen, in dem man in der jeweiligen Klasse eine "Init"-Funktion anlegen und die dann per
objMeineKlasse1.Init(doc, view, Param3, Param4, ...)
zuweist.
MFG
ERR