Autor Thema: Prüfung auf "Dokument verwaist" und dessen Umwandlung in Hauptdokument  (Gelesen 7710 mal)

Offline Stefanie

  • Frischling
  • *
  • Beiträge: 5
Hallo zusammen,

zuerst einmal muss ich betonen, dass ich der absolute Newbie in der Notes-Entwicklung bin.
Es geht um folgendes:
In unserer Firma ist in einer Datenbank ein Ansichtsfehler aufgefallen.
Die Ansicht "Alle Dokumente" ist mit Antwortdokumente hierarchisch anzeigen eingestellt.
Somit werden uns jedoch in dieser Ansicht die verwaisten Dokumente (Dokumente ohne Hauptdokument) nicht angezeigt.

Ich möchte einen Vergleich programmieren, der prüft, ob die Antwortdokumente (unterschiedliche Formen - Memos, Replys, Response..) auch ein Hauptdokument mit dem selben UNID besitzt.
Wenn NEIN, dann soll dieses Antwort-Dokument in ein Hauptdokument gewandelt werden.
Das alles müsste dann wieder in der Ansicht "Alle Dokumente" mit Hierarchierung auftauchen.
Oder?

Ich habe schon verschiedene Artikel hier durchgelesen, aber leider keinen passenden gefunden.

Wie gesagt bin ich ein absoluter Frischling in der Notes-Entwicklung und habe mich erst minimalst eingelesen. Am besten kann ich mit Formelsprache arbeiten, aber das ist glaube ich so nicht lösbar.

Ich hoffe sehr, dass ihr mir weiterhelfen könnt!!
 :)

Habt DANK!!

Offline pram

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.170
  • Geschlecht: Männlich
    • Foconis Object Framework
Hallo Stefanie,

willkommen hier im Forum.

Der Grund, warum du diese Dokumente nicht siehst, ist weil die Ansicht auf "hierarchisch" steht.
Damit du also an alle Dokumente ran kommst, brauchst du eine Ansicht die nicht auf hierarchisch steht.

Um die unsichtbaren Dokumente zu identifizieren
kannst du evlt. 2 Ansichten bauen, welche alle und welche nur die sichtbaren Dokumente anzeigt.
Dann machst du eine Spalte, die die UNID des Doks anzeigt, wenn du nun diese 2 Spalten "subtrahierst", dann hättest du alle UNIDs die betroffen sind.
=> Mit subtrahieren meine ich die UNIDs aus der Liste entfernen, das kannst du entweder mit Formelsprache der Art:
unsichtbareUNIDs := @unique(@Replace(AlleUNIDs;SichtbareUNIDs;"")) machen oder mit Texteditor/Excel/was weiß ich.

Diese Dokumente verschiebst du in einen Folder (oder gibst die Liste als Select-Formel an) und entfernst dann von all diesen Dokumenten das "$REF" Feld.

Dann sollten das wieder Hauptdokumente sein.
Alles natürlich vorher in einer Kopie testen ;)

Gruß
Roland
Roland Praml

IBM Certified Application Developer - Lotus Notes and Domino 8
Ich verwende das Foconis Object Framework

Offline Peter Klett

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.713
  • Geschlecht: Männlich
Formelsprache ist hier wirklich nicht das geeignete Mittel.

Du solltest Dich soweit in Script einlesen (die Hilfe mit den Beispielen ist dafür sehr gut geeignet), dass Du eine NotesDocumentCollection durchlaufen kannst.

Dein Script könnte sinngemäß so aussehen:

Zuerst holst Du Dir mittels eines NotesDatabase.Search alle Dokumente, die ein Item "$REF" haben. Selektionsformel im Search = @IsAvailable ($REF).

Diese Collection durchläufst Du Dokument für Dokument und prüfst anhand der Propertie ParentDocumentUNID (das ist die UniversalID des Elterndokuments), ob es das Elterndokument überhaupt gibt. Ein dafür brauchbarer Befehl wäre NotesDatabase.GetDocumentByUnid. Das Blöde an dem Befehl ist, dass der bei Nichtvorhandensein des Dokuments aussteigt, da müsstest Du mit On Error darum herumbasteln.

Findest Du ein Dokument ohne Elterndokument, löschst Du das $REF mit NotesDocument.RemoveItem, danach nicht vergessen, das Dokument zu speichern.

Fang einfach an, Dich mit Script vertraut zu machen. Wenn Du dann irgendwo hängst, frag gerne noch mal konkret nach. Fertige Scripte schreiben wir hier allerdings nur selten bzw. ungern.

EDIT: Dass Formelsprache kein geeignetes Mittel ist, bezieht sich nicht auf den Beitrag von Roland. Ich dachte eher an einen dauerhaften Reparaturagenten und nicht an eine einmalige Aufräumaktion.
« Letzte Änderung: 23.07.13 - 16:52:18 von Peter Klett »

Offline ascabg

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 3.697
  • Geschlecht: Männlich
@pram
Klingt zwar irgendwie einleuchtend, aber eine kleine Frage/Anmerkung hierzu.

Wie kommen die Werte in die beiden Variablen "AlleUNIDs" und "SichtbareUNIDs"?


Andreas

Offline Peter Klett

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.713
  • Geschlecht: Männlich
@pram
Klingt zwar irgendwie einleuchtend, aber eine kleine Frage/Anmerkung hierzu.

Wie kommen die Werte in die beiden Variablen "AlleUNIDs" und "SichtbareUNIDs"?


Andreas

@DBColumn

Könnte aber schnell ein 32 oder 64 kB-Problem geben.

Offline ascabg

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 3.697
  • Geschlecht: Männlich
@Peter
Daher auch meine Frage an pram.  ;)
(so durch die Blume)


Andreas

Offline Peter Klett

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.713
  • Geschlecht: Männlich
Andererseits ist der Hinweis nicht wirklich schlecht.

Zwei Ansichten mit den sortierten UniversalIDs (@Text (@DocumentUniqueID)), diese als Tabelle kopieren und in Excel in zwei Spalten übernehmen. Dort mit SVerweis die Differenzen suchen.

Aus der langen Liste über SVerweis den Partner aus der kurzen Liste suchen und einen entsprechenden Verweis im Fehlerfall ausgeben, danach sortieren. Kennt man sich damit aus, ist das auch in ein paar Minuten erledigt.

Offline pram

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.170
  • Geschlecht: Männlich
    • Foconis Object Framework
Hallo Peter @DBColumn hat kein 32KB Problem was die Gesamtdatenmenge betrifft. (zumindest in Notes 7 / 8.5)

DBColumn/DBLookup kann 65530 Werte zurück geben (auch wenn jeder 32 Zeichen hat), solange man diese nicht in einem Feld speichert, kann man mit den Variablen arbeiten und auch Replaces / unique etc. ausführen, bis das Ergebnis klein genug ist, um es in ein Feld zu speichern. (Wenn es nicht mehr als 65530 Dokumente gibt, sollte also ein @DBcolum gehen)
Die Gesamtdatenmenge die per Formelsprache verarbeitet werden kann, liegt bei 65530 Mehrfachwerten (sofern dies keine Felder sind) und geschätztem 1MB

Alternativ kann man natürlich die View auch nach Excel/CSV exportieren und hier diese Treffer herausfiltern.

(Mir ist bewusst, dass es mit Script einfacher geht, aber das kann Stefanie nicht)

Gruß
Roland

« Letzte Änderung: 23.07.13 - 17:14:22 von pram »
Roland Praml

IBM Certified Application Developer - Lotus Notes and Domino 8
Ich verwende das Foconis Object Framework

Offline koehlerbv

  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 20.460
  • Geschlecht: Männlich
Das ist aber mehr für One-Night-Stands geeignet und nicht für eine dauernde Maintenance.  
Andererseits ergibt sich für die Frage, warum in einer offensichtlichen Mail-DB da die View-Properties der "($All)" geändert wurden.

Dein Vorschlag, Peter, geht schon genau in die richtige Richtung, allerdings muss man da noch die Forms explizit nennen. Kalenderdokumente haben ja auch $Ref-Items (wiederkehrende Termine), und es ist natürlich unschön, wenn jemand den Termin wegknallt und dann das Child als Orphan zurückbehält. Wenn das dann aber dem $Ref beraubt wird, hat man auch sehr "lustige" Effekte.

@Stefanie: Willkommen bei AtNotes!
Bernhard

Offline pram

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.170
  • Geschlecht: Männlich
    • Foconis Object Framework
@Bernhard

Stefanie schrieb
Zitat
In unserer Firma ist in einer Datenbank ein Ansichtsfehler aufgefallen.
Ich gehe deshalb davon aus, dass das einmalig repariert werden sollte und wenn man sich ein wenig in Formelsprache/Excel auskennt hat man das ja wirklich innerhalb kurzer Zeit erledigt. (Script-Kenntnisse wären natürlich optimal)

Dein Einwand zur $ALL-Ansicht/Kalender-Dokumenten ist zwar berechtigt, aber soweit ich dem ersten Post entnehme, handelt es sich nicht unbedingt um eine Mail-DB.

Gruß
Roland
Roland Praml

IBM Certified Application Developer - Lotus Notes and Domino 8
Ich verwende das Foconis Object Framework

Offline ascabg

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 3.697
  • Geschlecht: Männlich
@pram,
Zitat
Accessing the return values
If multiple values are returned by @DbColumn, they are formatted as a list and are separated with the multivalue separator designated for the current field in the field InfoBox.
@DbColumn can return no more than 64K bytes of data. Use the following equations to determine how much of your data can be returned using @DbColumn.
For lookups that return text:
2 + (2 * number of entries returned) + total text size of all entries
For lookups that return numbers or dates:
(10 * number of entries returned) + 6

Dann sei mir die Frage zu diesem Auszug aus der Hilfe elaubt.
Steht diese Aussage nicht im Gegensatz zu Deiner getroffenen Aussage?
(oder interpretiere ich hier etwas total falsch)


Andreas

Offline pram

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.170
  • Geschlecht: Männlich
    • Foconis Object Framework
Diese Aussage in der Hilfe stimmt offensichtlich nicht, bzw nur dann wenn man den Wert in ein Feld speichert. (Dies zeigt z.B. der erste Satz, der auf das Feldtrennzeichen eingeht)

Hab folgendes gerade in einer DB probiert in dem ich folgende Formeln per SHIFT-F9 in einem Feld ausgeführt habe

@elements(@DBcolumn("";"";"myView";1)) = 4565 (Anzahl der Dokumente)
@Sum(@length(@DBcolumn("";"";"myView";1)))  = 213966 (Gesamtlänge aller Strings = 213kb)

@Andreas, probiere es bitte selber mal aus.

Gruß
Roland



Roland Praml

IBM Certified Application Developer - Lotus Notes and Domino 8
Ich verwende das Foconis Object Framework

Offline Stefanie

  • Frischling
  • *
  • Beiträge: 5
Zuerst einmal Herzlichen Dank für die vielen Antworten.

Um meine Problematik nochmal detailliert zu umschreiben.
Es handelt sich tatsächlich um eine Mail-DB, von daher um einen möglichen dauerhaften Fehler
(Antwort-Dokument auf ein Hauptdokument, welches nicht mehr existiert wird an die DB verschickt).
Dieser Fehler soll in der Ansicht Alle Dokumente vermieden werden.
Nur leider habe ich mich in das Scripten noch gar nicht eingearbeitet.

@Peter
Ich bin schon in vielen Foren auf getDocumentbyUnid gestoßen, nur leider weis ich es nicht wirklich umzusetzen.

Ich habe zuerst einmal eine Kopie der DB erstellt und in dieser eine neue Test-Ansicht.
In dieser habe ich die Ansichtsauswahl SELECT @IsAvailable ($REF) gesetzt.
Somit sehe ich jetzt alle Dokumente, die eine "Referenz-ID" haben.
Aber diese wiederum will ich mit den Hauptdokumenten vergleichen.

Gibt es denn eine Art Vergleich?
Sprich Vergleiche alle $Ref mit allen $Orig, wenn ein Eintrag $Ref existiert, ABER KEIN zugehöriger $Orig (Hauptdokument), dann lösche $Ref (bilde also ein Hauptdokument daraus).

In der Hilfe habe ich schon ähnliche Scripts gefunden, aber leider kein Vergleich von den UNIDs.

Sicher geht es nur über das Scripten.
Fertige Scripts möchte ich auch eher weniger, da ist der Lerneffekt so gering.
Aber kleine Hinweise, wo man was macht, wären super hilfreich.

Über nochmalige Tipps bin ich super happy.

DANKE und Grüße



Offline Peter Klett

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.713
  • Geschlecht: Männlich
Vorschlag: Versuche mit der Designer-Hilfe einen Script-Agenten zu bauen, der eine NotesDocumentCollection durchläuft und von jedem Dokument irgendetwas ausgibt, z.B. die UniversalID (Print). Eine Collection für den Anfang wäre die NotesDatabase.AllDocuments.

Wenn Du das geschafft hast, hast Du schon halb gewonnen :)

Danach schränkst Du die Collection ein, dass Du nur die Dokumente hast, die Du überprüfen willst, also alle die mit dem Item $REF und evtl. einer Liste von relevanten Formen.

Der nächste Schritt wäre dann die Überprüfung auf die Anwesenheit des Elterndokuments.

Als letztes kommt das Umwandeln der Antwort in ein Hauptdokument.


Das sind m.E. die einzelnen Schritte, die Du der Reihe nach umsetzen könntest, bei denen Du nach jedem Schritt auch das entsprechende Erfolgserlebnis hast, dass das bis dahin funktioniert.

Hängst Du an einer Stelle, poste Dein bisheriges Script hier und nenne das aktuelle Problem, das Du hast, dann findet sich bestimmt jemand, der Dir weiterhilft.

Danach wirst Du nicht nur ein lauffähiges Script haben, sondern vermutlich auch verstanden haben, wie Du es selbst erstellen kannst.

Traue Dich auch, Fehler zu posten, hier lacht keiner, denn niemand konnte das schon von Geburt an ...




Offline Stefanie

  • Frischling
  • *
  • Beiträge: 5
Hallöchen,

ich habe nun ein Code via Notes Script gebastelt, orientiert an einen anderen aus der Designer-Hilfe.
Diesen Code habe ich im Initialize-Objekt meiner Test-Ansicht in der DB geschrieben.
Beim Debuggen bleibt er kurz bei Set Session = New NotesSession stehen.
Jedoch ohne Fehlermeldung.
Danach arbeitet er weiter.
Aber das Feld $Ref wird beim jeweiligen Antwort-Dokument ohne Hauptdokument nicht "geleert".
Vielleicht verstehe ich ja den Befehl
DocUNID = doc.ParentDocumentUNID
Set Parent = db.GetDocumentByUNID(DocUNID)
falsch.
Die verwaisten Dokumente haben zwar eine Parent-Unid, aber diese ist in der DB nicht vorhanden.

Kann mir bitte jemand einen Tipp geben, wie ich das prüfe?
Hier mein bisheriger Code:
Sub Initialize
   
   Dim Session As NotesSession
   Dim db As NotesDatabase
   Dim Ansicht As NotesView
        Dim Doc As NotesDocument
   Dim Parent As NotesDocument   
   Dim DocUNID As String
   
   Set Session = New NotesSession
   Set db = Session.Currentdatabase
   Set Ansicht = db.GetView("Test")
   Set doc = Ansicht.GetFirstDocument
   
   
   While Not Doc Is Nothing
      If Doc.Form(0) = "Memo" Then      
         DocUNID = doc.ParentDocumentUNID
         Set Parent = db.GetDocumentByUNID(DocUNID)
         If Parent Is Nothing Then
            Call doc.RemoveItem( "$Ref" )
            Call doc.Save( True, True )
         End If
      Else
         If Doc.Form(0) = "Reply" Then      
            DocUNID = doc.ParentDocumentUNID
            Set Parent = db.GetDocumentByUNID(DocUNID)
            If Parent Is Nothing Then
               Call doc.RemoveItem( "$Ref" )
               Call doc.Save( True, True )
            End If
         End If
      End If
      
      Set Doc = Ansicht.GetNextDocument(doc)
   Wend
End Sub

Über eine Kollektion habe ich es nicht gelöst, da ich bereits einen Filter auf alle Dokumente mit $Ref habe.


Habt riesen Dank!!
 :)

Offline koehlerbv

  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 20.460
  • Geschlecht: Männlich
Eigentlich müsstest Du in der Zeile
Set Parent = db.GetDocumentByUNID(DocUNID)
immer dann auf einen Fehler laufen ( lsERR_NOTES_BAD_UNID (4091)), wenn das $Ref auf ein nicht mehr vorhandenes Dokument verweist. Diesen Fehler musst Du in einem speziellen ErrorHandler abfangen und dort reagieren.
Es gibt hierzu ebenfalls in der DesignerHelp ein Code-Beispiel.

Bernhard

Offline dnotes

  • Aktives Mitglied
  • ***
  • Beiträge: 106
  • Geschlecht: Männlich
Auf einen Fehler wirst Du wahrscheinlich nicht immer laufen. Korrigiere mich falls das nicht stimmt.
Das Problem könnte sein, dass Du bei set Parent auch gelöschtre Dokumente angezeigt bekommst; allerdings ohne nennenswerten Inhalt.
Hängt m.E. mit den deletionsstub zusammen.
Du musst also noch überprüfen, ob das Dok ein Deletionstub ist oder nicht.
Vielleicht als erster Ansatz überprüfen, ob das parent.Authors(0) = "" ist.
Das dürfte nur bei einem solchen deletionstub der Fall sein.

Offline Peter Klett

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.713
  • Geschlecht: Männlich
Nach parent.Authors zu suchen, ist nicht zu empfehlen. In einer zufällig ausgewählten Mail in meiner Maildatenbank existiert dieses Feld nicht. Besser ist m.E. zu prüfen, ob Items vorhanden sind

If Not Isarray (Parent.Items) Then
   'Dokument ist gelöscht
End If

In Deinem Script wirst Du auf einen Fehler laufen, wenn Du tatsächlich ein Dokument änderst. Deine Ansicht ist gefiltert nach Vorhandensein des Items $REF. Änderst Du das aktuelle Dokument, hat dieses nicht mehr das Item und bei

Set Doc = Ansicht.GetNextDocument(doc)

bekommst Du den Hinweis, dass das Dokument doc nicht in der Ansicht enthalten ist. Eine Collection ist da mein persönlicher Favorit, alternativ musst Du mit mehreren Document-Objekten hantieren oder ein Aktualisieren-Flag in der Ansicht setzen, was aber nachher wieder zurückgesetzt werden muss.

EDIT: noch ein Nachsatz zur besseren Wartbarkeit

Anstelle von
Code
While Not Doc Is Nothing
      If Doc.Form(0) = "Memo" Then      
         DocUNID = doc.ParentDocumentUNID
         Set Parent = db.GetDocumentByUNID(DocUNID)
         If Parent Is Nothing Then
            Call doc.RemoveItem( "$Ref" )
            Call doc.Save( True, True )
         End If
      Else
         If Doc.Form(0) = "Reply" Then      
            DocUNID = doc.ParentDocumentUNID
            Set Parent = db.GetDocumentByUNID(DocUNID)
            If Parent Is Nothing Then
               Call doc.RemoveItem( "$Ref" )
               Call doc.Save( True, True )
            End If
         End If
      End If
      
      Set Doc = Ansicht.GetNextDocument(doc)
   Wend

würde ich die Bedingung mit einem OR schreiben, dann hast Du den Schleifeninhalt nur einmal

Code
While Not Doc Is Nothing
      If Doc.Form(0) = "Memo" Or Doc.Form(0) = "Reply" Then      
         DocUNID = doc.ParentDocumentUNID
         Set Parent = db.GetDocumentByUNID(DocUNID)
         If Parent Is Nothing Then
            Call doc.RemoveItem( "$Ref" )
            Call doc.Save( True, True )
         End If
      End If
      
      Set Doc = Ansicht.GetNextDocument(doc)
   Wend

Das aber nur am Rande ...
« Letzte Änderung: 29.07.13 - 11:02:51 von Peter Klett »

Offline dnotes

  • Aktives Mitglied
  • ***
  • Beiträge: 106
  • Geschlecht: Männlich
parent.Authors ist kein Feld in einem Dokument sondern ein Eigenschaft des Objektes Dokument.
Ich kann mir kein Dokument vorstellen, daß diese Eigenschaft nicht besitzt.

Offline Peter Klett

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.713
  • Geschlecht: Männlich
parent.Authors ist kein Feld in einem Dokument sondern ein Eigenschaft des Objektes Dokument.
Ich kann mir kein Dokument vorstellen, daß diese Eigenschaft nicht besitzt.

Stimmt natürlich. Ist das im Falle des gelöschten Dokuments auch zwingend ein Array? Mich irritierte die (0) in Deinem Post ...

 

Impressum Atnotes.de  -  Powered by Syslords Solutions  -  Datenschutz