Das Notes Forum

Domino 9 und frühere Versionen => Entwicklung => Thema gestartet von: Christian97 am 27.07.04 - 21:04:29

Titel: Feld in anderem Dokument setzen
Beitrag von: Christian97 am 27.07.04 - 21:04:29
Hallo,

beim Erstellen eines neuen Dokumentes hole ich mir Kundendaten aus einer anderen Datenbank. Nach der Bearbeitung soll in dem Dokument in der anderen Datenbank, aus der ich die Daten geholt habe, ein Statusfeld gesetzt werden.
Genau dort liegt mein Problem. Ich finde einfach keinen Weg, um das Feld dort zu setzen. @SetDocField klappt ja nur in der gleichen DB. Ich hab auch schon

@Command([FileOpenDatabase]; _Server:_Datei; "Alles"; ID; "1"; "1");
FIELD bearbeitet := bearbeitet;
@SetField("bearbeitet"; "1");

probiert. Bei der Variante wird das Feld aber auch nicht gesetzt.

Vielleicht könnt Ihr mir auf die Sprünge helfen.

Danke
Christian
Titel: Re:Feld in anderem Dokument setzen
Beitrag von: Semeaphoros am 27.07.04 - 21:07:38
Da wirst Du wohl nicht um LotusScript herum kommen. Da wurden aber gerade kürzlich Konzepte dazu diskutiet. Bemühe mal die Suche
Titel: Re:Feld in anderem Dokument setzen
Beitrag von: Christian97 am 27.07.04 - 21:17:14
Die Suche hatte ich schon vor meinem Post bemüht, leider ohne Erfolg. Nach welchem Stichworten sollte ich denn suchen? Bei mehr als 2 Suchbegriffen erhalte ich meist keine Ergebnisse.

Christian
Titel: Re:Feld in anderem Dokument setzen
Beitrag von: Glombi am 27.07.04 - 21:50:12
Wäre Script für Dich machbar? Es ist der einzige (vernünftige) Weg.

Welche Kenntnisse hast Du?

Andreas
Titel: Re:Feld in anderem Dokument setzen
Beitrag von: Christian97 am 27.07.04 - 21:56:07
Bei Script hab ich leider so gut wie gar keine Kenntnisse.  :-[

Christian
Titel: Re:Feld in anderem Dokument setzen
Beitrag von: Glombi am 27.07.04 - 22:05:20
Bei Script hab ich leider so gut wie gar keine Kenntnisse.  :-[

Christian
Das können wir ja ändern  ;)
Bereit, wenn Sie es sind.

@Formel-mäßig bist Du gut drauf, oder?

Andreas
Titel: Re:Feld in anderem Dokument setzen
Beitrag von: Christian97 am 27.07.04 - 22:14:59
Hmm, na dann :-)

Ich denke, daß ich mit der Formel-Lösung schon auf dem richtigen Weg war. Nur, daß die Formel das eigentliche Setzen des Feldes nicht mehr ausführen wollte und deshalb eine Script Lösung her muß.
Was ich machen muß, ist die Datenbank auswählen, dazu habe ich die ReplikID. Dann das Dokument in dieser Datenbank, dazu habe ich die DokID. Anschließend das Feld setzen und speichern.
Bloß wie fang ich das in Script an? Bisher hab ich mir die Designer Hilfe genommen und anhand der Beispiele etwas zusammenkopiert. Hat meistens funktioniert. Diesmal scheint mir das Problem aber umfangreicher.

Christian
Titel: Re:Feld in anderem Dokument setzen
Beitrag von: Glombi am 27.07.04 - 22:22:39
Ok. Um eine Datenbank per Replik-ID zu öffnen, gibt es die Methode
flag  = notesDatabase.OpenByReplicaID( server$, replicaID$ )

In Script wird - im Gegensatz zur Formelsprache - die Replik-ID OHNE Doppelpunkt verwendet.  >:( Blöd, aber nicht zu ändern. Eine kleine Challenge für den Programmierer.

Um ein Notesdokument per DocID zu holen:
Set notesDocument = notesDatabase.GetDocumentByUNID( unid$ )

Für Deinen Fall: Wo steht denn die Replik-ID der Zieldatenbank und die Dok-ID des Zieldokuments? Im aktuell geöffneten Dokument?

Andreas
Titel: Re:Feld in anderem Dokument setzen
Beitrag von: Christian97 am 27.07.04 - 22:28:55
Danke für den Anfang!

Ja, die Replik-ID und Dok-ID stehen im aktuell geöffneten Dokument.
Titel: Re:Feld in anderem Dokument setzen
Beitrag von: Glombi am 27.07.04 - 22:38:07
Das ist gut.
Lotus Script ist Objekt-orientiert, cool   8)
D.h. es gibt Objekte, die Notes-Datenbanken, Notes-Ansichten, Notes-Dokumente (auf der Festplatte), geöffnete Notes-Dokumente, geöffnete Ansichten, geöffnete Datenbanken etc. repräsentieren.
Es gibt also Backend (das was auf der Platte ist) und Frontend (das was der User auf dem Bildschirm "sieht") Klassen.
Das schöne ist, je nachdem wo man den Scriptcode eingibt, werden einem bestimmte Objekte "geschenkt".
Wenn Du bspw. in das Event Postopen gehst, siehst Du dort als Parameter
Source as NotesUIDocument
D.h. Source repräsentiert das aktuell geöffnete Dokument (UI = User Interface, d.h. das was der Anwender sieht).

Was Dir noch helfen würde, ist das Klassenmodell von Notes. Das gibt es als Poster. Ich habe etliche von den Dingern hier, Du auch?

In dem Klassenmodell siehst Du, wie man von einer Klasse zu einer anderen kommt. Wenn Du bspw. eine Notes-Datenbank hast, kannst Du damit zu einem Notes-Dokument und damit zu einem Notes-Feld (sog. Item) kommen.

Klar so weit  ???

Andreas
Titel: Re:Feld in anderem Dokument setzen
Beitrag von: Christian97 am 27.07.04 - 22:50:19
Ich hab zwar kein Poster vom Notes-Klassenmodell da, hab aber schon mal eins gesehen. Auch das Durchhangeln von einer Klasse zur anderen ist mir theoretisch klar.
Es mangelt am Verständnis, wann und wieso ich welches Objekt anlegen muß und wie ich es dann an das nächste übergebe.
Titel: Re:Feld in anderem Dokument setzen
Beitrag von: Glombi am 27.07.04 - 23:04:17
Ich verwende bei der Programmierung immer die Notes Designer Hilfe. Was anderes braucht eigentlich kein Mensch.
Die Bespiele dort sind gut.

Nach einigen Scripts geht es dann in Fleisch und Blut über.

Zurück zu deinem Problem: Du hast im aktuell geöffneten Dokument (NotesUIDocument) die Replik-ID und die Dok-ID stehen. Du willst wenn ein neues Dokument erstellt wird, beim Schliessen im Zieldokument ein Feld setzen. Also brauchst Du

(Declarations)
dim session as NotesSession
dim db as NotesDatabase
dim zieldb as NotesDatabase
dim zieldoc as NotesDocument
dim doc as NotesDocument

dim DocIsNew as Integer
dim zielReplicaID as String
dim zielDocID as String

Im Postopen...
set session = New NotesSession
set db = session.CurrentDatabase
set doc = Source.Document  

zielReplicaID = doc.ReplikID(0)   'das ist Extended Class Syntax : äquivalent zu doc.GetItemValue("ReplikID")(0)

'":" ausschneiden
if Instr(zielReplicaID ;":") > 0 then
 zielReplicaID = Left$(zielReplicaID,8) & Right$(zielReplicaID,8)
end if

zielDocID = doc.DocID(0)

if Source.IsNewDoc then
 DocIsNew = true
else
 DocIsNew = false
end if


Im QueryClose...
if DocIsNew then
 set zieldDB = New NotesDatabase("","")
 call zielDB.Open( db.Server, zielReplicaID )

 if zielDB.IsOpen then
   set zieldoc = zielDB.GetDocumentByUNID( zielDocID )
  if not zieldoc is Nothing then
     zieldoc.bearbeitet = "1"
     call zieldoc.Save(false,true,true)    
  end if
 end if
end if


Das sollte es tun. Wichtig ist, dass Du die einzelnen Schritte verstehst!

Andreas
Titel: Re:Feld in anderem Dokument setzen
Beitrag von: TMC am 27.07.04 - 23:08:03
Ich hab zwar kein Poster vom Notes-Klassenmodell da, hab aber schon mal eins gesehen.

Hier eins vom 6.5er Client. Du hast zwar in R5 nicht alle Klassen, aber zumindest als Überblick vielleicht hilfreich:

(http://www.atnotes.de/attachments/poster6.5.gif)
Titel: Re:Feld in anderem Dokument setzen
Beitrag von: Christian97 am 28.07.04 - 11:40:14
Vielen Dank Andreas für das Script und auch danke für das Klassenmodell!

Ich habe das Script ins (Declarations), PostOpen und QueryClose meiner Maske eingebaut, die beiden eingeschlichenen Tippfehler behoben und probiert. So ganz funktioniert's noch nicht. Ich hab mir dann alles mit dem Debugger anzeigen lassen. Die Variablen werden alle richtig gesetzt, allerdings wird das Feld "bearbeitet" nicht gesetzt, weil die ZielDB nicht geöffnet wird. Du hattest

   Call zielDB.Open(db.Server, zielReplicaID )

geschrieben. Ich habe dann das db.Server weggelassen, weil die ZielDB auf dem gleichen Server liegt. Auch wenn ich anstelle von zielReplicaID den Dateinamen angebe, öffnet's die DB nicht. Der Abschnitt

   If zielDB.IsOpen Then

wird dann übersprungen, zieldoc nicht gesetzt und das Feld demzufolge auch nicht.

Woran kann das liegen?

Christian
Titel: Re:Feld in anderem Dokument setzen
Beitrag von: Glombi am 28.07.04 - 12:17:24
Es muss
set zielDB = New NotesDatabase("","")
call zielDB.Open( db.Server, zielReplicaID )
heissen. Tippfehler entfernt.
Der Server muss angegeben werden.
Was zeigt der Debugger als Wert für zielReplicaID an? Es muss die Replik-ID der Zieldatenbank sein, allerding ohne ":"

Andreas
Titel: Re:Feld in anderem Dokument setzen
Beitrag von: Christian97 am 28.07.04 - 13:07:04
Genau so steht's bei mir da. Bringt denn die ReplikID nicht den Server-Namen mit? In der Hilfe steht:
Zitat
server$
String. The name of the server on which the database resides. Use an empty string ("") to indicate a database on the current computer, or for a NotesDatabase that's already assigned to a database.

Also kann ich doch auch den Server-Namen als Leerstring lassen.

Der Wert für die zielReplicaID ist der von der Ziel-DB, ohne ":".
Auch der Wert für die zielDocID stimmt. Wenn ich ZIELDB im Debugger aufklappe, steht bei FILENAME und FILEPATH die zielReplicaID. Bei ISOPEN steht nach dem Call Aufruf "False".

Christian
Titel: Re:Feld in anderem Dokument setzen
Beitrag von: Axel am 28.07.04 - 13:26:04
Hi,

die Open - Methode aus der NotesDatabase-Klasse funktioniert nicht mit der ReplikID sondern nur mit dem Datenbanknamen.

Wenn du mit der ReplikID arbeiten willst, musst du OpenByReplicaID verwenden.


Axel
Titel: Re:Feld in anderem Dokument setzen
Beitrag von: Glombi am 28.07.04 - 13:26:40
Sorry, mein Fehler. Es muss
set zielDB = New NotesDatabase("","")
call zielDB.OpenByReplicaID( db.Server, zielReplicaID )
heissen.

Andreas
Titel: Re:Feld in anderem Dokument setzen
Beitrag von: Christian97 am 28.07.04 - 14:20:55
Coool :D Es funktioniert! Vielen Dank Andreas und Axel!

Trotzdem bleibt noch eine Frage offen:

Ich würde das Feld doc.DocID nach dem setzen des "bearbeitet"-Feldes wieder löschen. Wenn Ich im QueryClose

doc.DocID = ""

eingebe, kommt eine Fehlermeldung "Invalid Universal ID" bei der Zeile

Set zieldoc = zielDB.GetDocumentByUNID(zielDocID)

im QueryClose. Mir scheint, als ob das zweimal durchlaufen wird, denn das Feld "bearbeitet" ist zu diesem Zeitpunkt schon gesetzt. Wieso das?

Christian

Titel: Re:Feld in anderem Dokument setzen
Beitrag von: Glombi am 28.07.04 - 14:33:46
Bist Du sicher, dass es QueryClose ist? Das sollte nur einmal durchlaufen werden, ausser das Dokument wird nicht geschlossen.

Im QueryClose folgendes:


if DocIsNew and doc.DocID(0) <> "" then
  set zielDB = New NotesDatabase("","")
  call zielDB.OpenByReplicaID( db.Server, zielReplicaID )
... ... ...

 doc.DocID = ""
 call doc.Save(true,true,true)
end if

Andreas
Titel: Re:Feld in anderem Dokument setzen
Beitrag von: Christian97 am 28.07.04 - 14:57:36
Sehr schön! Jetzt funktioniert es so, wie es soll. Vielen Dank nochmals.

Der Lerneffekt war auch da. Mir geht es immer so, daß ich den Code verstehe, wenn ich den irgendwo lese, aber selber nicht die genaue Abfolge der Befehle schreiben kann. Aber, wie Du schon sagtest, ist das eine Frage der Übung und "nach einigen Scripts geht es dann in Fleisch und Blut über".

Ciao,
Christian