Beiträge von hchudek

    Ich selbst loese dieses Problem mit folgenden Elementen :


    - Eine Auswahlbox mit den Namen der gewuenschten Sub-Elementen (meineSub1.xsp, meineSub2.xsp, meineSub3.xsp)
    - Die Auswahlbox ist gebunden auf eine sessionScope-Variable (z.B. sessionScope.subName)


    - Include Page-Element, der Name der Seite ist berechnet - JavaScript : sessionScope.subName (Also die oben definierte sessionScope-Variable)


    - Custom Controls mit den entsprechenden Inhalten (also meineSub1.xsp, meineSub2.xsp...)


    Damit es funktioniert, muss die Seite nach dem setzen der Variablen neu geladen werden, daher ist bei der Auswahlbox im "OnChange"-Event folgender JavaScript-Code :
    "context.reloadPage()", damit wird nach der Auswahl des Seitennamens die Komplette Seite neu geladen + das CC im Bereich dargestellt


    Funktioniert bei mir ohne Probleme, man muss nur daran denken, den SessionScope korrekt zu verwalten und beim oeffnen des Dokumentes muss man den sessionScope halt auch manuell setzen, sonst kommt der Anzeigebereich nicht.

    Hallo,


    wie sehen denn die Zugriffsrechte (auf OS-Ebene) auf das Verzeichniss resp. auf die entsprechende Datenbank aus ??


    Ich hatte ähnliche Phänomene bei meinen lokalen Datenbanken nach dem Update auf FP2 für XP, irgendwo wurden die Dateien, die von Agenten o.ä. angefasst wurden plötzlich mit anderen Zugriffsrechten versehen.


    Gruss


    Holger

    Hallo,


    1. Hat es einen bestimmten Grund, warum die auf die Gruppen im NAB/Directory prüfst und nicht entsprechende Rollen auf entsprechenden Gruppen in der ACL hältst ??


    2. Der Vorschlag war ja, die Berechtigungen zu prüfen, ein Flag auf dem Dokument zu setzen und an den entsprechenden Stellen auf das Dokumentenflag zu prüfen :


    Sub Queryopen(Source As Notesuidocument, Mode As Integer, Isnewdoc As Variant, Continue As Variant)
    Print "Starte QueryOpen"
    source.Document.editFlag = "0" //Hier natürlich die entsprechende Prüfung, "0" wenn keine Berechtigung, "1" wenn eine Berechtigung.
    End Sub


    Ab dann kannst du auf dem Dokument prüfen, ob der Wert gesetzt ist, z.B. auch im Postopen :


    Sub Postopen(Source As Notesuidocument)
    Print "Starte Postopen"
    If source.Document.editFlag(0) = "0" Then
    source.EditMode = False
    End If
    End Sub


    Hier läuft er dann nochmal durch den QueryModeChange, wenn das Uidokument auf True war und auf mit dieser Funktion auf false gesetzt wird.


    Ich stimme aber Taurec zu, ohne die Benutzung von Autorenfeldern wird es schwierig, das DOkument sicher zuzumachen. Man könnte ja mit anderen Tools auf das Dokument gehen + dort dann Feldwerte ändern, man könnte über Backend-Agents die Werte ändern, dann habe ich garkein UIdokujment + entsprechend auch keine Postopen, Queryopen-Events usw.


    Mit diesen Mitteln sperrst du dicht das Dokument an sich sondern nur den Zugriff auf das Dokument über das UI.


    mfg


    Holger

    Hallo RockWilder,


    volle Zustimmung was den Designer angeht. Soweit ich weiß sind aber am Designer einfach zu wenig Leute bei IBM dran, da kann man keine Super-Sprünge erwarten.


    Aber mit 8.5.1 wirds ja jetzt besser. Die Beta sieht ja schon mal ganz ordentlich aus und man braucht jetzt auch keine Zusatztools, um sich nur mal die Klassenhierarchien anzuschauen oder eine übersichtliche Darstellung zu bekommen, sondern hat alles in seiner IDE (die dann leider halt mal den fünf- bis zehnfachen Speicherbedarf hat und zum starten mindestens doppelt bis dreimal so lange braucht :( ).


    Zu Java : Wenn mans nicht braucht, ok, aber


    1tens. gibts halt eine Menge an fertigem, gutem Code in der Java-Community, for free + dokumentiert (z.B. Logging oder Task-Management, spezielle Implementierungen von Algorithmen wie z.B. Sortierungen, Schlüsselerzeugung ( z.B. für Hashes), Java-Frameworks für Workflows usw. Es gibt zwar auch openntf, aber die Java-Gemeinde ist einfach viel größer als die Notes-Gemeinde).


    2tens wird man durch die Eclipse-Plattform viel mehr Java-Code zu sehen bekommen + ich denke es ist dann gut, wenn man sich mit dem Thema schonmal auseinandergesetzt hat.


    3tens gibts für die eher Skript-orientierten Programmierer (hey, absolut ohne Wertung hier, einfach nur zu Beschreibung der Programier-Sprachen-Art) Möglichkeiten mit z.B. Groovy zu arbeiten, Lotus Skript ist halt "closed" und alles, was IBM nicht macht, kann man selbst kaum machen. Java ist an dieser Stelle einfach offener (auch wenn Oracle jetzt bei manchem den Daumen draufhalten wird)


    4tens kann man Java auch noch benutzen, wenn man aus dem Notes-Ökosystem heraustritt, mit den Grundlagen von Lotus Skript wird es dann schon schwieriger.



    Natürlich gibt es auch Nachteile, der Code ist schwieriger unterzubringen (In IDE erstellen, Klassen im Designer reinkopieren+ Agentenrümpfe anpassen usw..), die Lernkurve für Java ist relativ hoch und im UI kann ich (noch ???) nichts mit Java anfangen und für schnelle, kurze Programmierungen (rapid prototyping) ist es auch oft zu viel Overhead (obwohl, seitdem ich einige Skelette für Agenten, Schleifen usw benutze und mit entsprechenden Techniken direkt aus der Eclipse-Umgebung meine Tests machen kann, ohne jedesmal alles in den Notes-Client rüberzukopieren ist auch ein einfacherer Agent zeimlich genausoschnell programmiert wie ein Skript-Agent).


    Aber ich denke auch, dass man die meisten Sachen im Skript gut und schnell lösen kann + dazu keine neue Sprache lernen muss. Die meisten OOP-Ansätze funktionieren ja auch in Skript, und wem das reicht, der muß sich ja nicht verbiegen.



    Viele Grüße


    Holger

    Hallo,


    eigentlich doch eine ideale Aufgabenstellung für OOP (Objekt-Orientierte Programmierung).


    Wir haben ein Kundenobjekt, ein Auftragsobjekt und ein Bearbeiterobjekt.


    Damit sind die ganzen Teile entkoppelt und wenn sich bei einem was ändert musst du nicht alles bei den anderen ändern.


    Entweder hast du dann eine Liste der Kunden, jedes Kundenobjekt enthält dann eine Liste von Auftragsobjekten (also alle Aufträge, die beim Kunden gemacht wurden).
    Das entsprechende Auftragsobjekt enthält dann Infos zu dem Auftrag und unter anderem auch das Bearbeiterobjekt.


    oder du hast eine Liste der Aufträge (evtl. eine neue Klasse Auftragsliste), diese enthalten dann alle Aufträge und (wie oben) jeweils pro Auftrag den Kunden und den Bearbeiter.


    Auf dieser Auftragsliste kannst du dann die entsprechenden Auswertungen hin und herrechnen.


    Nachteil : Man braucht erstmal die Grundlagen für OOP, Objekte usw


    Vorteil : Ist viel flexibler für spätere Anforderungen und irgendwann braucht man OOP bzw die entsprechenden Grundlagen eh :-))), die entsprechenden Objekte kann man für andere Gelegenheiten benutzen und das ganze später auch leicht(er) in Java übertragen.


    :-))))


    Viel Spass


    Holger

    Hallo,


    den Artikel von Mikkael hatte ich auch schon gefunden, ABER : Beim Foconis-Framework werden Klassen benutzt, die bei den entsprechenden Elementen immer wieder geldaen werden und die immer die gleichen Werte enthalten. Irgendwie ist es also doch möglich, sowas wie einen Cache über die instanziierung einer Klasse zu realisieren (soweit ich die Werte im Debugger korrekt interpretiert habe). Wenn ich das Modell von Foconis richtig verstanden habe, ist alles ein Foc-Object. Da bei allen Aktionen (Datenbank-Skript, öffnen einer Maske, öffnen einer View, Aktion ausführen usw) jeweils erstmal ein Foc-Object erzeugt wird, kann man anscheinend die Foc-Klasse benutzen, um Werte zu cacehn, vielleicht mal genauer den Code anschauen + bei bedarf auf der Foconis-Seite im Forum einen Thread aufmachen).


    Gruß


    Holger

    Hallo,


    ich habe jetzt auch mal ein wenig rumgespielt, es ist wohl doch nicht so einfach wie erstmal gedacht. Beim öffnen des Dokumentes verliert der Code den Fokus. Ich kann zwar im Datenbankskript eine Variable definieren(Variant), die Klasse aufrufen und irgendwelche Werte reinschreiben. Wenn ich aber dann ein Dokument öffne, habe ich die Globale umgebung nicht mehr und wenn ich die Klasse aufrufe, wird eine neue Instanz erzeugt. Wenn ich dann später wieder auf Datenbankebene zurückgehe (z.B. über ein delete-Event), habe ich die zuerst erzeugte Variable mit dem Handle zur entsprechenden Klasse und den eingetragenen Werten. Ich werd nochmal in mich gehen. Vielleicht hat ja Thomas (Bahn, assono) noch ne Idee, ich bin mir nicht sicher, ob die in ihren Projekt-Datenbanken sowas wie caching drinhatten, wenn ich in den nächsten Tagen mal Zeit habe werde ich mir es mal anschauen.


    Grüße


    Holger

    Hallo,


    wo benutzt du den Code denn im Dokument. machst du einen Knopf und rufst dort den Code auf oder im Queryopen des Dokumentes ?? Wie instanziierst du den Aufruf den konkret ??


    Im o.a. Codebeispiel erzeugst du ja keine Instanz bzw. du greifst auf die Klasse zu (du machst ja kein konkretes Objekt aus der Klasse).


    Sobald du das Dokument zumachst wird natürlich auch die Klasse entladen (es wird ja kein Code mehr benötigt).


    Wenn du den Cache übergreifend nutzen möchstest, mußt du den Aufruf im Database-Skript implementieren, dort kannst du das ganze dann Dokumentenübergreifend benutzen, solange die Datenbank halt geöffnet ist (ob es dann Benutzerübergreifend funktioniert habe ich noch nicht getestet).


    Gruß


    Holger

    Hallo,


    hier noch eine Referenz für OOP und eine Kurzzusammenfassung der Singleton-Implementierung :
    http://www.assono.de/blog/Sear…Navigator&Query=singleton


    Ausserdem ein bisschen Code. Basis ist eine Private Klasse, diese hat aber eine öfffentliche Funktion, die den Zugriff auf eine private Insatnzvariable ermöglicht. Man kommt n diese Instanzvariable also nur über diese "Gatekeeper"-Funtkion dran (dort könnte man auch noch andere Anfragen prüfen oder z.B. mehrere Instanzen der Klasse ermöglichen + verwalten usw...:


    Script-Library "testSingleton"


    Private singletonObject As objectCache 'Ist die Instanzvariable, diese enthält die einzige Version dieser Klasse


    Private Class objectCache

    Sub new
    Print "Create instance of objectCache"
    End Sub

    Function getElement(oName As String) As String

    If Not Iselement(objectCache(oName)) Then
    Print "No Value in Object Cache"
    getElement = ""
    Else
    Print "Value in Object Cache Found"
    getElement = objectCache(oName)
    End If
    End Function

    Sub setElement(oName As String, oVal As String)
    objectCache(oName) = oVal
    End Sub

    End Class


    In der gleichen Library gibt es dann noch die folgende öffentliche Funktion :


    Function getSingletonObject As Variant
    If SingletonObject Is Nothing Then
    Set singletonObject = New objectCache
    End If
    Set getSingletonObject = singletonObject
    End Function


    Damit bekommt man den Zugriff auf die Klasse bzw. die entsprechende Version.


    Aus einem Agenten nun :


    Option Public
    Option Declare
    Use "testSingleton" 'so heisst die Script-Library bei mir(s.o.)


    und im Initialize :


    Sub Initialize
    Dim obj1 As Variant
    Dim obj2 As Variant

    Set obj1 = getSingletonObject
    Call obj1.setElement("eins", "1")
    Set obj2 = getSingletonObject
    Print obj2.getElement("eins")

    End Sub


    Das ganze sollte in einer Datenbank überall funktionieren, sobald die Klasse das erste Mal angesprochen wird, müßte die Klasse und deren Inhalt über alle Ebenen hinweg verfügbar sein.


    Interessant wird es, wenn mehrere Benutzer gleichzeitig die Funktion benutzen, ich denke dann wird es nicht funktionieren bzw. jeder Benutzer hat dann sein eigenes Singleton (also für seine Session). Habe ich aber noch nicht ausprobiert.


    Genausowenig wird es bei unterschiedlichen Datenbanken funktionieren. Mikkel Heisterberg (unter lekkimworld.com, Suche nach "Singleton") hat dazu einige interessante aspekte beigetragen.


    Viel Spaß,


    Holger

    Hallo,


    hast du auch Code-Teile, wie du es implementiert hast ? Prinzipiell ist es so möglich, wie bei nsfTools beschrieben, unter anderem ist es auch (wenn ich mich nicht irre) bei assono (http://www.assono.de) und bei foconis <http://www.foconis-object-framework.de/> (offenes Framework, auf jeden Fall mal anschauen wenn du mit OOP in Skript arbeiten willst) implementiert.


    Nachteil ist halt, dass du von aussen ein Variant hast und der Kompiler nicht mehr prüft, ob deine Funktionsaufrufe ok sind, du bekommst dann nur noch runtime-errors und must alles per Logging abfangen.


    Gruss


    Holger

    würde ich jetzt auch mal vermuten, am besten beim debuggen schauen, auf welche Datenbank versucht wird, zuzugreifen. Vielleicht ist ja auch der Server leer, dann versucht er bei lokalem Zugriff auf die lokale Datenbank zuzugreifen und beim zeitgesteuerrten Zugriff auf dem Server greift er sich die Server-Log-DB (die ggf. garnicht geändert ist).


    Viel Grlück,
    Holger

    Hallo,
    bin grundsätzlich auch ein Freund von Alias-Benutzung. Aber
    1. Manchmal gibts garkeine Aliase bei den ViewNamen
    2. Ist tatsächlich schneller, vor allem bei einer großen Anzahl von Views, weil zuerst die Klarnamen komplett durchsucht werden, dann die Aliasnamen
    3. Bei reinen programmatischen Views, die nur vom System Benutzt werden ($irgendwas) macht der Alias auch meistens keinen Sinn


    Im obigen Beispiel gebe ich dir recht, da ist die Benutzung des Alias besser, weil vermutlich in fast allen Versionen des Log-Templates der Alias so vorhanden ist und die Log-Schablone jetzt nicht wirklich viel Ansichten enthält :-)))

    Hallo,


    hast du mal versucht, den Return-Wert in ein neues Datenbankobjekt zurückzuschreiben, wie es die Designerhilfe vorsieht, vielleicht funktioniert die call-Routine hier nicht bzw. verursacht dann das Öffnen der Datenbank :


    Dim replica As NotesDatabase
    Set db = session.CurrentDatabase
    Set replica = db.CreateReplica( "Jakarta", "sales.nsf" )


    statt
    call db.CreateReplica( "Jakarta", "sales.nsf" )


    Das replica-Objekt sollte dann auch eigentlich nicht geöffnet sein,


    ist vielleicht ein Versuch wert.


    mfg


    Holger

    Hallo,


    also, das Skript will folgende View von dir haben :


    Set view = db.GetView("Database\Sizes")


    Die Datenbank, auf die Verwisen wird holt sich das skript drei Zeilen höher :


    Set db = New NotesDatabase(server,logPath)


    und die Parameter "Server" und "LogPath" bekommt es aus dem Setup-Dokument (kann man in der DB mit "Open Command Panel" aufrufen.


    Es wird anscheinend eine Datenbank auf Basis von "log.ntf" erwartet, dort sollte dann auch die View "Database\Sizes" vorhanden sein. Und hey, in der Deutschen Version (jedenfalls auf meinem 7er-Client) gibts die View garnicht. Die heißt stattdessen Dantenbank\Größe bzw im Alias "DatabaseSize".


    Also: Mal die Zeile


    Set view = db.GetView("Database\Sizes")


    ersetzen durch


    Set view = db.GetView("DatabaseSizes")


    oder mit dem Designer mal selbst die entsprechende Datenbank prüfen, welche View dort vorhanden ist bzw. wie sie heißt.


    Am besten den ersten Namen (also den Klarnamen verwenden, ist etwas schneller beim Zugriff), wenn du keine multi-Sprachumgebung verwendest.


    Viel Spass,


    Holger