Domino 9 und frühere Versionen > ND8: Entwicklung

Object variable not set bei DetDocumentByKey

<< < (3/4) > >>

Peter Klett:
Ich hab das jetzt mal nachgebaut:

Bei mir funktioniert folgendes (in der Ansicht habe ich @Text (@NoteID) als erste sortierte Spalte):


--- Code: ---Sub Initialize
Dim workspace As New NotesUIWorkspace
Dim uidoc As NotesUIDocument
Set uidoc = workspace.CurrentDocument
Dim doc As NotesDocument
Set doc = uidoc.Document
doc.Feldx = "irgendwas"

Dim db As NotesDatabase
Set db = doc.ParentDatabase
Dim view As NotesView
Set view = db.GetView ("noteid")
Dim iddoc As NotesDocument
Dim id As String
id = "NT" & Right ("00000000" & doc.NoteID, 8)
Set iddoc = view.GetDocumentByKey (id)
Msgbox iddoc.Feldx (0)
End Sub

--- Ende Code ---

Msgbox gibt korrekterweise nichts aus.

Dagegen


--- Code: ---Sub Initialize
Dim workspace As New NotesUIWorkspace
Dim uidoc As NotesUIDocument
Set uidoc = workspace.CurrentDocument
Dim doc As NotesDocument
Set doc = uidoc.Document
doc.Feldx = "irgendwas"

Dim db As NotesDatabase
Set db = doc.ParentDatabase
Dim iddoc As NotesDocument
Set iddoc = db.GetDocumentByID (doc.NoteID)
msgbox iddoc.Feldx (0)
End Sub

--- Ende Code ---

geht es nicht mit db.GetDocumentByID, da dann das Dokument im Speicher verwendet wird (hatte mir das gedacht, musste ich aber erst überprüfen). Hier wird also "irgendwas" ausgegeben.

Beim Evaluate bekommst Du die NoteID so zurück, wie sie in der Ansicht steht. Bei doc.NoteID musst Du ein "NT" und den Rest 8-stellig mit führenden Nullen aufbauen. Da wäre mir das Evaluate lieber, falls sich da mal was ändert, ist aber sicher Geschmacksache.

db.GetDocumentByID bringt Dich aber auf keinen Fall weiter.

thkn777:
@Peter Klett
Wenn man auf das NotesSession Objekt verzichtet und die db einfach über db.Open(Server, Pfad) öffnet, dann kann man auch GetDocumentById verwenden.


--- Code: ---Private Sub showEingabe(Byval db3name As String, Byval db3server As String, Byval NoteId3 As String)
Dim session3 As New NotesSession
Dim doc3 As NotesDocument
Dim db3 As New NotesDatabase( "", "" )

' Set db3 = session3.GetDatabase(db3server, db3name)
Call db3.Open( db3server, db3name )

Set doc3 = db3.GetDocumentByID(noteId3)
If doc3 Is Nothing Then
Print "doc3 is nothing"
Else
Print Str$(Now()) & " doc3.eingabe = " & doc3.eingabe(0)
End If
End Sub
--- Ende Code ---

- Ich habe diese Sub in einer Maske eingebunden.
- ich gebe in das Feld "eingabe" etwas ein (z.B. "1") und speichere, danach rufe ich die Sub auf --> "1"
- das Dokument verbleibt weiter im Edit-Mode
- ich gebe in das Feld "eingabe" etwas anderes ein (z.B. "2") ohne zu speichern und rufe die Sub auf --> immer noch "1"

Benutze ich stattdessen "Set db3 = session3.GetDatabase(db3server, db3name)" (oben auskommentiert), dann tritt der von Dir beschriebene Effekt ein, daß über das im Client nur einmal verwendete NotesSession Objekt das in-memory Dokument verwendet wird. Folgerichtig wird dann der nicht gespeicherte Wert "2" angezeigt.

Ich bin immer noch der Meinung, daß es auch ohne Ansicht geht und direkt die DocumentId verwendet werden kann. Wie sich das ganze performancetechnisch verhält, müßte man noch gucken. Mir fehlt im Moment auch die Zeit auszutesten, wie weit man db3 in die Globals schieben kann. Wenn das geht, dann sollte die Sub sehr schnell sein.

Gruß,
Th.

P.S. @cococo69 Entschuldige, Deine Frage in dem Thread war eine andere und es geht Dir eigentlich um die GetDocumentByKey Fehler - vielleicht kommt aber trotz des "Hijacking" etwas Gutes für Dich bei dieser Diskussion heraus.  ;)

thkn777:
Mit einem Evaluate geht auch so etwas in der Maske (gleiches Scenario wie oben):


--- Code: ---Sub Click(Source As Button)
Dim ws As New NotesUIWorkspace
Dim uidoc As NotesUIDocument
Dim unid As String
Dim res As Variant

Set uidoc = ws.CurrentDocument
unid = uidoc.Document.UniversalID

res = Evaluate (|@GetDocField("| & unid & |"; "eingabe")|)
Print Str$(Now()) & " eingabe = " & res(0)
End Sub
--- Ende Code ---

D.h. mit @GetDocField kann man sich - sofern man in der gleichen DB arbeitet - das DB.Open sparen. Es wird auch hier der Inhalt des NotesItems aus dem Backend angezeigt.

Schönen Feierabend wünsch' ich.

pram:
Eine (evtl übertriebene) Anmerkung meinerseits:

Bei Codestücken wie diesen läuten bei mir immer die Alarmglocken:

--- Code: ---res = Evaluate (|@GetDocField("| & unid & |"; "eingabe")|)
--- Ende Code ---

Durch sowas baut man sich nämlich sehr oft (hier zwar nicht) eine Sicherheitslücke.
Wenn UNID aus einem Feld kommen würde, kann Code injiziert werden.
Deshalb sollte man, wenn möglich, immer eine konstante Formel verwenden und für die Parameterübergabe ein Dokument verwenden.

Besser wäre:

--- Code: ---res = Evaluate (|@GetDocField(@DocumentUniqueID; "eingabe")|, uidoc.document)
--- Ende Code ---
(evtl muss um @DocumentUniqueID noch ein @Text() rum)

Hat weiterhin den Vorteil, dass die Formel schon bei der Compilezeit überprüft wird.

Gruß
Roland

Peter Klett:

--- Zitat von: thkn777 am 20.01.14 - 17:38:34 ---@Peter Klett
Wenn man auf das NotesSession Objekt verzichtet und die db einfach über db.Open(Server, Pfad) öffnet, dann kann man auch GetDocumentById verwenden.
...

--- Ende Zitat ---
Cool, dann würde ich das an Armins Stelle genau so machen und auf die Ansicht verzichten. Da die Ansicht jedesmal refresht wird, kann GetDocumentByID nur schneller sein.

Navigation

[0] Themen-Index

[#] Nächste Seite

[*] Vorherige Sete

Zur normalen Ansicht wechseln