Das Notes Forum

Domino 9 und frühere Versionen => ND6: Entwicklung => Thema gestartet von: Notestime am 11.10.04 - 10:24:33

Titel: Dokumente in Datenbank kopieren
Beitrag von: Notestime am 11.10.04 - 10:24:33
Hallo!

Ich stehe vor einem Problem und weiß nicht so recht wie ich es angehen soll:

Aus einer Datenbank sollen ausgewählte Dokumente per Knopfdruck in eine andere Datenbank, die im Web liegt und KEINE Replik der DB ist kopiert werden und mit einem Flag "veröffentlicht" versehen werden. Werden dann Veränderungen an einem "lokalen" Dokument vorgenommen oder das Dokument gelöscht werden, so soll sich die Änderung auch auf das Dokument im Web auswirken.

Ich denke, die Dokumente findet man am sichersten über die DocumentUniqID, oder?

Wie gehe ich die Sache am besten an?

Velleicht hat jemand ein paar Codeschnipsel parat. Wäre echt super!

Danke und Gruß
Bernd
Titel: Re: Dokumente in Datenbank kopieren
Beitrag von: klaussal am 11.10.04 - 10:46:42
Kopieren geht wohl am besten mit copytodatabase.
Dem neuen Dok würde ich in einem hidden-Feld die UNID des Ursprungsdocs mitgeben und mit der das Dokument später suchen (... und hoffentlich finden).

klaus

PS: Sehe gerade, dass man bei copytodatabse dem neuen dok keine neuen Felder mitegeben kann. Also musst du wohl den Weg über create gehen.
Titel: Re: Dokumente in Datenbank kopieren
Beitrag von: Semeaphoros am 11.10.04 - 11:37:52
Create, dann CopyAllItems und dann die Zusatzinfos. Das Mitnehmen der UNID ist fast ein MUSS, um die Originalseite dann wieder zu finden, gleichzeitig würde ich noch das LastModified-Datum mit übergeben und auch noch im Originaldokument die UNID des neuen Dokumentes in der anderen Datenbank hinterlegen, damit sind dann wohl alle relevanten Daten abgelegt
Titel: Re: Dokumente in Datenbank kopieren
Beitrag von: Notestime am 11.10.04 - 13:00:25
Danke erstmal für die Antworten.

Ich werde das mal so angehen und hoffen, daß ich es hinbekomme.

Gruß
Titel: Re: Dokumente in Datenbank kopieren
Beitrag von: Notestime am 13.10.04 - 15:29:28
Huhu!

Klappt soweit ganz gut.

Eine frage noch:
Wie kann ich bei

Set Zieldoc = Zieldb.getdocumentbyunid(Quelldoc.ZielDocUniqID(0))

abfangen, wenn noch kein Zieldoc da ist, daß es eine Fehlermeldung gibt?

Dank und Gruß
Bernd
Titel: Re: Dokumente in Datenbank kopieren
Beitrag von: Notestime am 13.10.04 - 15:34:43
Danke,

habs rausbekommen:

on Error Resume Next

Bernd
Titel: Re: Dokumente in Datenbank kopieren
Beitrag von: Semeaphoros am 13.10.04 - 16:11:55
Aber dann dahinter her gleich sofort wieder abstellen, sonst gibts nie wieder Fehlermeldungen, und das wäre fatal
Titel: Re: Dokumente in Datenbank kopieren
Beitrag von: koehlerbv am 13.10.04 - 16:17:40
Da ist aber irgendwas faul: Die Zeile wäre ja vollkommen überflüssig, da sie nichts bewirkt. Sag mal genaueres - eine Resume Next ist garantiert überflüssig.

Bernhard
Titel: Re: Dokumente in Datenbank kopieren
Beitrag von: Notestime am 13.10.04 - 16:28:03
Na denn, so sieht's aus. Wenn ich das On Error Resume Next weglasse, krieg ich ne FM (invalid universalid), wenn das Dokument noch nicht da ist:

Option Public
Option Declare

Dim s As notessession
Dim Zieldb As notesdatabase
Dim Quelldb As notesdatabase
Dim selecteddocs As notesdocumentcollection
Dim Quelldoc As notesdocument
Dim Zieldoc As notesdocument

Sub Initialize
   Set s = New notessession
   Set Quelldb = s.currentdatabase
   Set Zieldb = s.getdatabase("","Eigene Datenbanken\Ziel.nsf")
   Set selecteddocs = Quelldb.unprocesseddocuments
   Set Quelldoc = selecteddocs.getfirstdocument
   While Not Quelldoc Is Nothing
      If Quelldoc.ZielDocUniqID(0) = "" Then
         Call CreateEntry
      Else
         Call UpdateEntry
      End If
      Call Zieldoc.save(True,True)
      Quelldoc.ZielDocUniqID = Zieldoc.universalid
      Call Quelldoc.save(True, True)
      Set Quelldoc = selecteddocs.getnextdocument(Quelldoc)
   Wend
End Sub

Sub CreateEntry
   Set Zieldoc = Zieldb.createdocument
   
   Call Zieldoc.replaceitemvalue("QuellDocUniqID",Quelldoc.universalid)   
   Call Zieldoc.replaceitemvalue("Form","Maske")
   Call Zieldoc.replaceitemvalue("Beruf",Quelldoc.Beruf(0))
End Sub

Sub UpdateEntry
   Set Zieldoc = Nothing
   On Error Resume Next   
   Set Zieldoc = Zieldb.getdocumentbyunid(Quelldoc.ZielDocUniqID(0))
   If Zieldoc Is Nothing Then
      Set Zieldoc = Zieldb.createdocument
   End If
   
   Call Zieldoc.replaceitemvalue("QuellDocUniqID",Quelldoc.universalid)   
   Call Zieldoc.replaceitemvalue("Form","Maske")
   Call Zieldoc.replaceitemvalue("Beruf",Quelldoc.Beruf(0))
End Sub

Dann hab ich noch ein Scipt, über das ich die Dokument in der ZielDB wieder rausnehmen kann:

Sub Initialize
   Set s = New notessession
   Set Quelldb = s.currentdatabase
   Set Zieldb = s.getdatabase("","Eigene Datenbanken\Ziel.nsf")
   Set selecteddocs = Quelldb.unprocesseddocuments
   Set Quelldoc = selecteddocs.getfirstdocument
   While Not Quelldoc Is Nothing
      Set Zieldoc = Nothing
      On Error Resume Next   
      Set Zieldoc = Zieldb.getdocumentbyunid(Quelldoc.ZielDocUniqID(0))
      Call Zieldoc.Remove(True)
      Quelldoc.ZielDocUniqID = ""
      Call Quelldoc.save(True, True)
      Set Quelldoc = selecteddocs.getnextdocument(Quelldoc)
   Wend
End Sub

Gruß
Bernd

P.S. Da ist sicher Vieles zu verbessern, ich bin nicht so der Script-Freak
Titel: Re: Dokumente in Datenbank kopieren
Beitrag von: Semeaphoros am 13.10.04 - 16:40:28
Bernhard: Verstehe Deinen Einwand jetzt überhaupt nicht. Wenn das Ding keinen Einfluss hätte, bräuchte es den Befehl ja in der Sprachdefinition nicht. Das Ding ist sinnvoll, wenn man es richtig einzusezten versteht, aber enorm gefährlich, wenn man es falsch macht.


Bernd: Und genau das tust Du, es falsch machen. Dieses "resume next" darf absolut nur für eine einzige Zeile aktiviert sein, sonst knallt man früher oder später mit unbehandelten Fehlern gegen die Wand und weiss nicht mehr, wo Fehler suchen.

Schaut doch beide mal diesen Thread an:

Errorhandling (http://www.atnotes.de/index.php?board=27;action=display;threadid=11980)

und sucht dort nach resume next.

Ja, ich weiss, dass ich das Ding für die BPs überarbeiten sollte .... :-X
Titel: Re: Dokumente in Datenbank kopieren
Beitrag von: koehlerbv am 13.10.04 - 16:50:17
@Notestime: Ich schaue Deinen Code asap an.

@Semeaphoros: Du hast mich sicher missverstanden - ich kritisiere nicht Resume Next, sondern den Umstand, dass es eingesetzt wird wegen einer Zeile, die immer einen Fehler bringt und daher von vornherein weggelassen werden kann, da sie nichts bewirkt (ausser 'nen Error zu generieren).

Ich habe aber in nicht einer meiner Routinen irgendwo ein On Error Resume Next. Kommt mir nicht ins Haus. Solange ich nicht weiss, was passiert ist, gibt es bei mir auch kein Resume Next. Ordnung und Sauberkeit im Schlachthof.

Bernhard
Titel: Re: Dokumente in Datenbank kopieren
Beitrag von: Notestime am 13.10.04 - 16:58:40
Mhm, ich verwende das sonst auch nicht. Aber ich habe keine andere Möglichkeit gesehen, es einzusetzen, zumal es ja den Fehler verschwinden läßt, der ja eigentlich kein Fehler sondern eher ein Zustand ist, nämlich der, daß das Dokument nicht da ist.

Euch fällt sicher ein "glücklicherer" Code für mein Problem ein ;-)

Danke schonmal

Gruß
Bernd
Titel: Re: Dokumente in Datenbank kopieren
Beitrag von: Semeaphoros am 13.10.04 - 17:09:35
Bernhard: Diese eine Zeile bringt nur dann einen Fehler, wenn das aufgerufene Dokument nicht existiert. Wie willst Du das vorher wissen, dass es das Dokument nicht gibt? Genau dieser Aufruf, GetDocumentByUNID ist eines der wenigen Beispiele, wo ein Resume Next sinnvoll ist. Man kann dann dahinter darauf testen, ob die Objektvariable gefüllt ist oder nicht, sprich ob das Doc gekommen ist oder eben nicht existiert. Aber danach muss natürlich sofort wieder ein On error goto EHandler oder so kommen.

Man kann es natürlich auch im ErrorHandler selber abfackeln, wird aber komplizierter als das hier beschriebene Verfahren.
Titel: Re: Dokumente in Datenbank kopieren
Beitrag von: koehlerbv am 13.10.04 - 17:30:28
Mir ist natürlich auch schon der Umstand untergekommen, dass eine nicht vorhandene UNID gleich als "Invalid universal ID" abgestempelt wird (Beispiel: Agent trägt genehmigten Urlaub in den Kalender des Antragstellers ein. Dann wird der Urlaub storniert - der Agent muss an Hand der gespeicherten UNID den Eintrag wieder löschen. Frustriert hat das der User aber schon manuell getan ...).

Ich habe das wie folgt gelöst (hier am Beispiel einer Sub von Bernd):
Die Routine "ErrorHandler" ist natürlich selbst zu schreiben, und global muss in das Modul eingebunden werden:
%INCLUDE "lsconst.lss" (hierfür eigentlich unnötig, aber für Massagekisten und so ...)
%INCLUDE "lsxbeerr.lss"


Sub UpdateEntry

   On Error Goto ErrorRoutine

   Set Zieldoc = Nothing
   Set Zieldoc = Zieldb.getdocumentbyunid(Quelldoc.ZielDocUniqID(0))
   If Zieldoc Is Nothing Then  'Stehenlassen wegen Sauberkeit !
      Set Zieldoc = Zieldb.createdocument
   End If
   
   Call Zieldoc.replaceitemvalue("QuellDocUniqID",Quelldoc.universalid)   
   Call Zieldoc.replaceitemvalue("Form","Maske")
   Call Zieldoc.replaceitemvalue("Beruf",Quelldoc.Beruf(0))

   Exit Sub

ErrorRoutine:
    Select Case Err
    Case lsERR_NOTES_BAD_UNID:
       Set Zieldoc = Zieldb.createdocument
       Call Zieldoc.replaceitemvalue("QuellDocUniqID",Quelldoc.universalid)   
       Call Zieldoc.replaceitemvalue("Form","Maske")
       Call Zieldoc.replaceitemvalue("Beruf",Quelldoc.Beruf(0))
     
    Case Else:
       Call ErrorHandler ("UpdateEntry")
    End Select 

Exit Sub 'vernichtet auch den Fehlerstatus !
End Sub



Wobei ich das Ganze in eine Function gelagert hätte und das eigentliche Update des Dokuments in einer weiteren Sub erledigt hätte.

So ist das aber eine saubere Lösung.

In der Routine zum Löschen bietet sich ein On Error lsERR_NOTES_BAD_UNID Gosub XXX an oder auch ein Standardverfahren, das bei lsERR_NOTES_BAD_UNID das Löschen / Update durchführt und dann mit Resume Next oder einem Goto Label weitermacht.

Auch so verliert man nicht die Kontrolle - es wird wirklich nur auf den Error lsERR_NOTES_BAD_UNID mit einer Exception reagiert, ansonsten aber mit dem Standardverfahren.

Bernhard
Titel: Re: Dokumente in Datenbank kopieren
Beitrag von: Semeaphoros am 13.10.04 - 17:52:32
Sag ich ja, dass mans auch so abfackeln kann. Unschön die kopierten Code-Zeilen, da würde ich anders agieren. Und ebenfalls unschön das Aussteigen aus der Errorroutine mit Exit Sub. Stimmt, dass das den Errorstatus zurücksetzt (bzw. im Grunde genommen ist er das schon durch das On Error), da würde ich jetzt trotzdem mit einem Resume blabla rausgehen.
Titel: Re: Dokumente in Datenbank kopieren
Beitrag von: koehlerbv am 13.10.04 - 18:05:23
Sag ich ja, dass mans auch so abfackeln kann. Unschön die kopierten Code-Zeilen, da würde ich anders agieren.
Ich hätte das Konstrukt ganz anders aufgebaut. Angedeutet habe ich es ja schon, aber Bernd kämpft erstmal noch mit den Basics, und da wollte ich den Thread jetzt nicht "überfrachten".

Und ebenfalls unschön das Aussteigen aus der Errorroutine mit Exit Sub. Stimmt, dass das den Errorstatus zurücksetzt (bzw. im Grunde genommen ist er das schon durch das On Error), da würde ich jetzt trotzdem mit einem Resume blabla rausgehen.

On Error setzt nicht zwangsläufig den ErrorCode zurück. Ausserdem sollte - wie von mir angedeutet (Function ...) - der Erfolgsstatus der Routine an die aufrufende zurückgemeldet werden.
Und: Resume wohin ? Wozu ? Der Fehlerzustand wurde bearbeitet - das ist ja die eigentliche Aufgabe des ErrorHandlers. Die aufrufende Routine muss nun mit dem Erfolgsstatus der Unterroutine zurechtkommen und das Ergebnis entsprechend bearbeiten. Im einfachsten Fall ist das eine Erfolgs-/Misserfolgs-Situation, kann aber natürlich auch komplexer sein.

Bernd ist aber gut beraten, wenn er spätestens jetzt den von Dir schon erwähnten ErrorHandling-Beitrag liest, damit er unsere Nebendiskussion auch verstehen kann.

Bernhard
Titel: Re: Dokumente in Datenbank kopieren
Beitrag von: Semeaphoros am 13.10.04 - 18:06:39
Jo, den Beitrag brauchts dazu
Titel: Re: Dokumente in Datenbank kopieren
Beitrag von: TMC am 13.10.04 - 21:18:34
Um eine Errorroutine zu verlassen, gefällt mir persönlich auch Resume XYZ besser als ein Exit Sub/Function - aber das ist wohl auch Geschmackssache (wie z.B. bei Msgbox die einzelnen Nicht-String-Glieder in ein CStr packen oder auch nicht, wie letztens diskutiert  :) - hier bevorzuge ich die Variante ohne CStr [ganz ohne Nachteile]).
Titel: Re: Dokumente in Datenbank kopieren
Beitrag von: koehlerbv am 13.10.04 - 21:50:54
Ich frag' dann halt eben nochmal: Resume WAS ?

Bernhard
Titel: Re: Dokumente in Datenbank kopieren
Beitrag von: Notestime am 13.10.04 - 21:58:40
Jo, danke erstmal!!!!

Ich schau mir die "Abhandlung" über das Errorhandling jetzt mal in Ruhe an.

Viele Grüße
Bernd
Titel: Re: Dokumente in Datenbank kopieren
Beitrag von: Semeaphoros am 13.10.04 - 22:00:48
Bernhard, etwa so (Auszug aus dem Error-Handling Fred):

Code
Sub Demo
 On Error Goto ErrHandler
 ... hier der Code
AfterError:
Exit Sub

ErrHandler:
  Print "Es ist ein Fehler aufgetreten"
  Resume AfterError:
End Sub
Titel: Re: Dokumente in Datenbank kopieren
Beitrag von: Semeaphoros am 13.10.04 - 22:02:26
Und noch etwas: mit dem Exit Sub im Error-Handler wird eines der strengen Gesetze der modularen Entwicklung durchbrochen: dadurch gibt es mehrere Ausstiegspunkte aus dem Modul
Titel: Re: Dokumente in Datenbank kopieren
Beitrag von: TMC am 13.10.04 - 22:24:13
Jo Jens, so hatte ich das auch in etwa gemeint.

Ich bin teilweise in manchen Routinen noch weitergegangen.

Also am Schluss des eigentlichen Codes ein:

UNDWEG:
 Exit Sub
ERRORHANDLER
  ErrorMsg ("Fähler")
  Resume UNDWEG
End Sub

Die UNDWEG-Marke springe ich auch im Code an, wenn ich abbrechen will (z.B. bei einer Msgbox) anstatt eines Exit Sub/Function

Vorteil: Sollte ich mal eine Sub zu einer Function machen, muss ich nur sehr wenige Stellen ändern. Evtl. muss man außerdem noch was vor dem Exit erledigen, was global gilt, dann kann man das auch dort reinpacken.


**EDIT**
Ich finde diese LS-Diskussionen übrigens immer hochinteressant und kann dabei viel lernen.
<scherzmodus>
Wo wir gerade bei Neugliedungsvorschläge des Forums sind: Ich will da einen extra Bereich "LS-Optimierung"  :D
</scherzmodus>
Titel: Re: Dokumente in Datenbank kopieren
Beitrag von: koehlerbv am 13.10.04 - 23:30:47
Wirklich eine interessante Diskussion, die wir aber in einem eigenen Thread fortführen sollten - das hilft ja dem Thread-Originator Bernd gerade überhaupt nicht weiter (momentan zumindest).

Wer also mag: Bitte neuen Thread erstellen. Wenn das Interesse besteht - ich hätte da auch noch ein paar Anmerkungen ... und wie immer den Willen, scheinbar Bewährtes zu überdenken.

Bernhard
Titel: Re: Dokumente in Datenbank kopieren
Beitrag von: Semeaphoros am 13.10.04 - 23:53:31
Matthias hat die Gründe für das Vorgehen präzis genannt, meine Strategie ist praktisch die gleiche wie die von Matthias.

Ein eigener Thread hierfür würde tatsächlich Sinn machen.
Titel: Re: Dokumente in Datenbank kopieren
Beitrag von: koehlerbv am 13.10.04 - 23:58:20
Macht einen neuen Thread auf, wenn Ihr auch Lust habt, das weiter zu diskutieren. Ich finde die Strategie nämlich durchaus nicht stringent (zmindest SO nicht).

Bernhard
Titel: Re: Dokumente in Datenbank kopieren
Beitrag von: TMC am 14.10.04 - 00:18:36
Bevor noch ein paar mehr Postings kommen, ob man vielleicht einen Thread eröffnen sollte oder könnte, hab ich das nun gemacht  ;D

Hier geht's weiter:
http://www.atnotes.de/index.php?topic=18825.0