Hallo zusammen! Ich habe ein sehr seltsames Problem. Ich möchte über eine kleine Funktion das Personen Dokument aus dem öffentlichen Adressbuch abfragen. Ich rufe diese Funktion aus einer anderen Routine der gleichen Skriptbibliothek auf. Innerhalb der Funktion wird das Personendokument auch ordnungsgemäß gefunden und in 'UserDocInNames' gesetzt, allerdings wird es nicht an die Function übergeben, aus der heraus ich diese Funktion aufrufe; tdoc bleibt Nothing.
Irgendwo habe ich wahrscheinlich einen Denkfehler. Nachstehend des Skriptcode der gesamten Bibliothek.
Option Public
Option Declare
Dim tdoc As NotesDocument
Sub Initialize
End Sub
Sub Terminate
End Sub
Function test
Dim session As New NotesSession
Dim workspace As New NotesUIWorkspace
Dim uidoc As NotesUIDocument
Dim db As NotesDatabase
Dim doc As NotesDocument
Set uidoc = workspace.CurrentDocument
Set db = session.CurrentDatabase
Set doc = uidoc.Document
Set tdoc = UserDocInNames("CN=Max Meier/O=STOKAS", Db)
End Function
Function UserDocInNames (searchkey As String,db) As NotesDocument
Dim session As NotesSession
Set session = db.Parent
Dim namesview As NotesView
Dim namesdb As NotesDatabase
Dim confdoc As NotesDocument
Set confdoc = db.GetProfileDocument("Konfiguration")
Set namesdb = session.GetDatabase(confdoc.ServerNames(0),confdoc.PathNames(0))
If ((namesdb.IsOpen) = False) Then
MessageBox "Das öNab konnte nicht geöffnet werden. Kontrollieren Sie die Pfad- und Serverangaben in der Konfiguration im Abschnitt 'Schnittstellen' Einstellungen.", 16, "Hinweis"
End If
Set namesview = namesDb.GetView( "($Users)" )
Set UserDocInNames = namesview.GetDocumentByKey( searchkey, True )
End Function
Hallo dnotes,
nein der Code funktioniert vom Design her schon mal nicht. Siehe hier:
Function UserDocInNames (searchkey As String,db) As NotesDocument
....
Set namesdb = session.GetDatabase(confdoc.ServerNames(0),confdoc.PathNames(0))
Set namesview = namesDb.GetView( "($Users)" )
Set UserDocInNames = namesview.GetDocumentByKey( searchkey, True )
End Function
Beim Verlassen der Funktion räumt die GC alle nicht mehr benötigten Variablen aus dem Speicher. (Diese sind in dem Fall namesDB und namesView)
Wenn dann kein anderer Codeteil eine Referenz auf die DB hält (Die interne parent-Referenz im Dokument zählt dabei nicht) und sie dadurch noch offen hält, dann kann aus dieser DB kein Dokument zurückgegeben werden.
Selbes Problem tritt auch mit anderen Notesklassen auf. Beispiel folgende Funktion:
Function getFirstAclEntry(db as NotesDatabase) as NotesACLEntry
Set acl = db.getACL()
set getFirstAclEntry = acl.getFirstEntry()
End function
Anwendungsbeispiel:
...
set entry = getFirstAclEntry(currentDB)
' entry ist hier NOTHING, da die ACL stirbt, weil niemand eine Referenz darauf hält
...
set acl = currentDB.getACL
set entry = getFirstAclEntry(currentDB)
' entry hat nun einen Inhalt, da unser Code eine Referenz auf "acl" hat.
...
set acl = Nothing
' acl UND entry ist nun Nothing, da es keine Referenz mehr auf die ACL gibt und somit
' auch alle Kindelemente.
Auch "one liner" wie currentDB.getAcl().getFirstEntry() sind von diesem Problem betroffen.
Dies erfordert leider oft einen etwas unorthodoxen Programmierstil :(
Wenn du das dann versuchst zu debuggen ist das Verhalten oft komplett anders (und es funktioniert ggf. sogar), da durch den Debugger Referenzen gehalten werden (z.B. im Variableneigenschaften Fenster)
Es kommt dabei auch oft darauf an, ob man z.B. ein Doc aufgeklappt hat oder nicht (hier ist ja die Parent-Referenz drin)
Sowas nennt man dann einen "Heisenbug"
Hoffe das einigermaßen verständlich erklärt zu haben :)
Gruß
Roland
(Keywords für Suche: Funktion Rückgabewert plötzlich unerklärlich Nothing, verliert Wert, funktioniert im Debbugger ohne nicht)