Das Notes Forum
Domino 9 und frühere Versionen => ND7: Entwicklung => Thema gestartet von: sja am 29.12.06 - 16:50:27
-
Hallo @All,
Vielen Dank im Voraus, wenn jemand mir bei Folgendem helfen würde:
In einem Rich Text Feld (Datenbank1) habe ich Link zu einem Dokument in der Datenbank2
so bekome ich ID:
....
Set rtlink = rtnav.GetElement
IDrtlink = rtlink.DocUnID
Anhand dieser ID soll auf das Dokument in der Datenbank2 zugegriffen werden.
Wenn das Dokument mit der ID in der Datenbank2 vorhanden ist, dann kein Problem
Wenn das Dokument mit solche ID in der Datenbank 2 nicht vorhanden ist, dann bei
Set doc = Datenbank2.GetDocumentByUNID( IDrtlink )
bekomme ich natürlich die Fehlermeldung
Invalid universal id
Habe nichts gefunden wie kann ich vorher feststellen, ob das Dokument mit der ID = Idrtlink in der Datenbank2 vorhanden ist.
Schoene Gruesse
Sofia
-
Du kannst dies in einem ErrorHandler abfangen und dort auf
lsERR_NOTES_BAD_UNID (=4091)
prüfen. Für diesen Fall kannst Du dann entsprechend Deiner Vorhaben weiter verfahren.
Ich mache das zumindest so ;)
Bernhard
PS: Dir und Deinem Mann, Sofia, "Vsjevo choroshevo s novym godom!"
-
Hallo Bernhard,
herzlichen Dank für die Hilfe!
Habe gehofft, das gibt's was anderes als ErrorHandler und habe viel Zeit auf die Suche verloren.
Aber wenn Du so sagst, dann probiere ich auch mit einem ErrorHandler.
Mы желаем тоже тебе и твоей семье счастья в новом году! :)
Liebe Gruesse
Sofia
-
Hallo @All,
also, mein Problem (Festlegung, ob eine Datenbank ein Dokument mit bekannte ID enthält) habe ich versucht mit dem ErrorHandler zu lösen.
Allerdings habe ich damit Schwierigkeiten: kann nicht das ErrHandle und das AfterError in dem Programm richtig platzieren, obwohl ich
Best Practices: Error Handling in Lotus Script: Einleitung http://atnotes.de/index.php?topic=11980.0
und andere Beiträge fleissig studiert habe. Ich habe das in meiner Funktion Update() aber es scheint falsch zu sein, oder das war falsche Platz in der Funktion.
Herzlichen Dank im Voraus, wenn jemand mir dabei helfen würde.
Hier ist der Code mit Kommentaren
'%INCLUDE "lsxbeerr.lss" 'Für den Test wird numerischer Code verwendet
Dim s As NotesSession
'Archiv PYM
Dim db As NotesDatabase
Dim dc As NotesDocumentCollection
Dim doc As NotesDocument
Dim view As NotesView
Dim VEC As NotesViewEntryCollection
Dim ve As NotesViewEntry
Dim rti As NotesRichTextItem
Dim rtnav As NotesRichTextNavigator
Dim rtlink As NotesRichTextDocLink
'MailCopyDB
Dim dbMailCopy As NotesDatabase
Dim vMailCopy As NotesView
Dim IDdbMailCopy As String
Dim IDvMailCopy As String
Dim IDrtlink As String
Dim docMC As NotesDocument
'Archiv MailCopyDB
Dim AdbMC As NotesDatabase
Dim AvMC As NotesView
Dim tmpAvMC As NotesView
Dim IDAdbMC As String
Dim IDAvMC As String
Dim AdocMC As NotesDocument
Dim IDAdocMC As String
Dim item As NotesItem
Sub Initialize
Set s = New NotesSession
'MailCopyDB
Set dbMailCopy = s.GetDatabase( "", "test\mailcopy.nsf" )
IDdbMailCopy = dbMailCopy.ReplicaID
Set vMailCopy = dbMailCopy.GetView( "($All)" )
IDvMailCopy = vMailCopy.UniversalID
'ArchivMailCopyDB
Set AdbMC = s.GetDatabase( "", "test\archivMC.nsf" )
IDAdbMC = AdbMC.ReplicaID
Set AvMC = AdbMC.GetView( "($All)" )
IDAvMC = AvMC.UniversalID
Set tmpAvMC = AdbMC.GetView( "tmpArchiv" ) 'temporary Anscht wird erhalten das Link-Dokument mit dem Flag = "archiv"
'Archiv PYM
Set db = s.CurrentDatabase
Set view =db.getview("UpdateLink")
Set VEC = view.AllEntries
Set ve = VEC.GetFirstEntry()
While Not (ve Is Nothing)
Set doc = ve.Document 'PYM-Dokument mit den Links
'Das PYM-Dokument kann das Feld "DateiHyperlink" oder
'das Feld "DateiHyperlink" oder die beide Felder
'mit den Links enthalten
If doc.HasItem("DateiHyperlink") Then
Set rti = doc.GetFirstItem("DateiHyperlink")
Call Update()
End If
If doc.HasItem("DateiHyperlink_1") Then
Set rti = doc.GetFirstItem("DateiHyperlink_1")
Call Update()
End If
Set ve = VEC.getNextEntry(ve)
Wend
End Sub
Function Update()
On Error 4091 Goto ErrHandle 'lsERR_NOTES_BAD_UNID (=4091)
Set rtnav = rti.CreateNavigator
If rtnav.FindFirstElement(RTELEM_TYPE_DOCLINK) Then
'Wenn wenigstens ein Link in dem Dokument vorhandes ist
Do
Set rtlink = rtnav.GetElement
IDrtlink = rtlink.DocUnID
Set docMC = dbMailCopy.GetDocumentByUNID(IDrtlink)
'Link-Dokument in der MailCopyDB
If docMC.IsValid = True Then
'Wenn das Link-Dokument in der MailCopyDB vorhanden ist und nicht gelöscht
docMC.Categories = "archiv" 'Setzen Flag = "archiv"
Call docMC.Save( True, True )
Call docMC.CopyToDatabase( AdbMC )
'Das Link-Dokument aus der MailCopyDB in der ArchivMailCopyDB kopieren
Call tmpAvMC.Refresh
'Das kopierte Link-Dokument mit dem Flag = "archiv" erscheint in der Ansicht "tmpArchiv" in der ArchivMailCopyDB
Set AdocMC = tmpAvMC.GetFirstDocument
IDAdocMC = AdocMC.UniversalID
Call docMC.Save( True, True )
'Temporary für testen wird das Link-Dokument in der MailCopyDB mit dem Flag "archiv" gespeichert
'In der Produktion muss dieses Dokument gelöscht werden
'Call docMC.Remove(True)
'Der Link in dem PYM-Dokument bekommt neuen IDs zu dem Link-Dokument in der ArchivMailCopyDB
rtlink.DbReplicaID = IDAdbMC
rtlink.ViewUNID = IDAvMC
rtlink.DocUnID = IDAdocMC
'PYM-Dokument wird mit dem aktualisierten Link gespeichert
Call doc.Save( True, True )
AdocMC.Categories = ""
'Flag "archiv" in dem Link-Dokument in der Archiv MailCopyDB wird auf "" gesetzt
Call AdocMC.Save( True, True )
'Das Dokument verschwindet aus dem Ansicht "tmpArchiv"
Call tmpAvMC.Refresh
End If
Loop While rtnav.FindNextElement(RTELEM_TYPE_DOCLINK)
doc.UpdateLink = "1"
’Setzt Flag UpdateLink in dem PYM-Dokument auf „1“, d.h. UpdateLink für dises Dokument wurde durchgeführt und Link-Dokument wurde in der Datenbank MailCopy gefunden
Call doc.Save( True, True )
AfterError:
doc.UpdateLink = "2"
’Setzt Flag UpdateLink in dem PYM-Dokument auf „2“, d.h. UpdateLink für dises Dokument wurde durchgeführt und die Datenbank MailCopy enthält kein Dokument mit ID = Link-ID
Call doc.Save( True, True )
End If
ErrHandle:
'Messagebox "Error" & Str(Err) & ": " & Error$
Resume AfterError
End Function
Ein glücklikes, gesundes neues JahrIch wünsche ich allen !
Sofia
-
Hi,
so auf den ersten Blick kann ich keinen Fehler entdecken.
Was sagt denn der Debugger.
Alles Gute im neuen Jahr.
Axel
-
Sofia, Du lässt im Fehler- wie im Erfolgsfall letztlich Dein Script unverändert durchlaufen.
Zunächst: Du brauchst einen allgemeingültigen ErrorHandler, der auf jeden Fehler reagieren muss: On Error Goto ErrorHandler.
Dann würde ich folgende Veränderungen vorschlagen:
’Setzt Flag UpdateLink in dem PYM-Dokument auf „1“, d.h. UpdateLink für dises Dokument wurde durchgeführt und Link-Dokument wurde in der Datenbank MailCopyDB gefunden
Call doc.Save( True, True )
Dein Code läuft jetzt weiter und macht daher alles wieder kaputt. Wenn aber der Code bis hierher gelaufen ist, dann ist alles in bester Ordnung, daher:
Exit Function
Vorher fehlt noch ein End If - hier stimmt was an Deiner Logik nicht. Siehe bitte unten.
AfterError:
doc.UpdateLink = "2"
’Setzt Flag UpdateLink in dem PYM-Dokument auf „2“, d.h. UpdateLink für dises Dokument wurde durchgeführt und die Datenbank MailCopyDB enthält kein Dokument mit ID = Link-ID
Call doc.Save( True, True )
End If
Das End If ist hier falsch - siehe oben!
Es fehlt wieder ein sauberer Ausgang:
Exit Function
ErrHandle:
Das muss ein sauberer ErrorHandler werden, daher:
If Err = 4091 Then 'Doc an Hand von UNID nicht gefunden!
Resume AfterError
Else
Messagebox "Error" & Str(Err) & ": " & Error$ 'Allgemeines Gemecker bei jedem anderen Fehler
Exit Function 'Fehlerstatus wird gelöscht
End If
End Function
Das kann aber nur als Anregung dienen und (natürlich) ist nicht in Deinem Kontext getestet.
HTH,
Bernhard
-
Hallo Bernhard,
bin unendlich dankbar für Deine Hilfe!
Jetzt, dank Dir, habe ich begriffen, dass für den Fall, wenn für alle Links in dem PYM-Dokument wurden die entsprechenden Dokumente in der MailCopyDB gefunden (d. h. die Schleife Do ... Loop While beendet ist) sollte das Funktions-Ende so aussehen
doc.UpdateLink = "1"
'Setzt Flag UpdateLink auf "1", d.h. UpdateLink für dises Dokument wurde durchgeführt
Call doc.Save( True, True )
End If
Exit Function
Aber verstehe nicht mit dem Fall, wenn in der Schleife Do ... Loop While für einen von Links wird kein Dokument in der Datenbank MailCopyDB gefunden. Dann wird der Fehler 4091 auftreten und es kommt zum Label AfterError. Wenn da wird
exit Funktion
dann wird aus dem Funktion raus d.h. die Schleife Do ... Loop While wird nicht bis zum Ende ausgeführt, aber es kann sein, dass in dem PYM-Dokument gib es noch weitere Links, für welche die Dokumente in der MailCopyDB vorhanden sind.
Also,
AfterError:
doc.UpdateLink = "2"
’Setzt Flag UpdateLink in dem PYM-Dokument auf „2“, d.h. UpdateLink für dises Dokument wurde durchgeführt und die Datenbank MailCopy enthält kein Dokument mit ID = Link-ID
Call doc.Save( True, True )
...
und weiter weiss nicht was sollte hier sein, damit wenn die Schleife Do ... Loop While noch nicht beendet ist, zurück in der Schleife.
Oh Gott, ob ich das alles verständlich ausgedrückt habe.
Noch mal herzlichen Dank für die Hilfe.
Liebe Gruesse
Sofia
-
Mal Dir am besten den Programmablauf mal genau auf, um zu entscheiden, wie nach einem 4091er Error dann verfahren werden soll. So auf einen schnellen Blick würde ich sagen, dass Du statt dem Exit Function (ich hatte Deinen Code hier nicht genau genug analysiert) ein Goto ContinueAfter4091 benötigst, dass genau vor dem Lopp While eingefügt werden muss.
Du musst dann aber noch schauen, was mit doc.UpdateLink passieren soll: Jetzt ist ja der Status "1" oder "2" etwas ... undefiniert, je nachdem, ob zwischendurch mal ein GetDocumentByUNID in die Hose geht oder nicht.
Wie gesagt: FlowChart aufmalen.
Bernhard
-
Hallo Bernhard,
alles klar, vielen vielen Dank. Für das Feld UpdateLink ist mir wichtig zu wiessen, ob Update ausgeführt ist, d. h UpdateLink != "", oder wenigstens ein Link hat kein Dokument, d. h. doc.UpdateLink = "2".
Dann probiere ich so:
...
...
ContinueAfter4091:
Loop While rtnav.FindNextElement(RTELEM_TYPE_DOCLINK)
If Not doc.UpdateLink = "2" Then
doc.UpdateLink = "1"
'Setzt Flag Upd3ateLink auf "1", d.h. UpdateLink für dises Dokument wurde durchgeführt
End If
Call doc.Save( True, True )
End If
Exit Function
AfterError:
doc.UpdateLink = "2"
'Setzt Flag UpdateLink auf "2", d.h. UpdateLink für dises Dokument wurde durchgeführt'Die Datenbank MailCopyDB enthält kein Dokument mit ID = Link-ID
Call doc.Save( True, True )
Goto ContinueAfter4091
ErrHandle:
If Err = 4091 Then 'Doc an Hand von UNID nicht gefunden!
Resume AfterError
Else
Messagebox "Error" & Str(Err) & ": " & Error$
Exit Function 'Fehlerstatus wird gelöscht
End If
End Function
Большое спасибо. Здоровья, счастья и всего самого наилучшего в Новом Году!
Liebe Gruesse
Sofia
-
Ohla,
ist zwar schon gelöst, aber ich wollt hier noch eine alternative anbieten (mit welcher ich z.B. getDocByUNID immer absichere).
Einfach folgende Function hinzufügen welche dann mit übergabe der UNID und der DB immer ein true o. false zurückliefert.
---
Function validateUNID( UNID As String, db As NotesDatabase ) As Variant
On Error Goto ende
Dim doc As NotesDocument
If Not( db Is Nothing ) Then
Set doc = db.GetDocumentByUNID( UNID )
If Not( doc Is Nothing ) Then
validateUNID = True
Else
validateUNID = False
End If
Else
validateUNID = False
End If
Exit Function
ende:
validateUNID = False
Exit Function
Resume Next
End Function
---
-
@S2000
Ist das eine Alternative? ??? :-:
Du machst doch auch eine Fehlerbehandlung. Nur Deine ist ausgelagert...
-
Ohla,
es ist insoweit eine alternative, als das du keinen error-code (wieder etwas, was ich mir nicht zu merken brauche) brauchst, es in eine scriptlib aufnehmen kannst und imho es einfacher zu verwenden ist ;-)
Gruß
-
Nun ja, drei Möglichkeiten ein False zu bekommen ist ja auch nicht schlecht...
Ich kann dann Raten, DB nicht gefunden, Doc nicht gefunden oder was anderes ist passiert.
Oder habe ich da was elementares übersehen?
-
als das du keinen error-code (.....) brauchst
Also: Man braucht dann generell keine Error-Code ;) ;D ^-^