Das Notes Forum

Domino 9 und frühere Versionen => ND6: Entwicklung => Thema gestartet von: CLI_Andreas_Schmidt am 28.02.07 - 14:38:01

Titel: Typisch Notes
Beitrag von: CLI_Andreas_Schmidt am 28.02.07 - 14:38:01
Hi @all,

stehe gerade vor einem Notes Feature. Folgendes.

Neues Dokument wird mit Maske 1  ( @command([compose.... erstellt ) geöffnet. Während der Eingabe entscheidet sich der User aber noch ein Dokument mit Maske zwei (aus Maske 1) zu erstellen. Inhalte soll natürlich von Maske 1 in Maske 2 (Formeln übernehmen Daten aus gewähltem Dokument) übernommen werden. Und was passiert ? Es werden tatsächlich Inhalte übernommen, nur nicht aus dem geöffnetem Dokument (Maske 1) sondern aus dem markiertem Dokument aus der darunterliegenden Ansicht.

: )
Titel: Re: Typisch Notes
Beitrag von: w3dev am 28.02.07 - 14:50:49
Gehört ja auch so. Steht in den Eigenschaften der Maske: Formeln übernehmen Werte aus markiertem Dokument

Titel: Re: Typisch Notes
Beitrag von: w3dev am 28.02.07 - 14:52:09
du solltest die Werte per LS in die neue Maske übertragen.

Gruß Ronny
Titel: Re: Typisch Notes
Beitrag von: Glombi am 28.02.07 - 14:55:00
Und wenn dann noch der User die <Strg> Taste gedrückt hält ist das Chaos perfekt. So kann man nämlich "Werte übernehmen aus gewähltem Dokument" ausschalten, egal was der Programmierer eingestellt hat  ;)

Andreas
Titel: Re: Typisch Notes
Beitrag von: w3dev am 28.02.07 - 14:55:50
Hö, das kannte ich auch nicht. Man lernt nie aus  ;D
Titel: Re: Typisch Notes
Beitrag von: w3dev am 28.02.07 - 14:58:16
Aber zurück zum Thema:

Setz einfach einen Aktion Button ind Maske, mit dem du ein neues Dokument öffnst und alle Werte aus dem aktuellen Dokument (notesUIWorkspace.CurrenDocument.Document) im Backend in das neue Überträgst und es dann zur bearbeitung öffnest.


Gruß Ronny
Titel: Re: Typisch Notes
Beitrag von: DerAndre am 28.02.07 - 14:59:06
Ja, und wenn er STRG + Q drückt sagt er mein Notes geht immer zu wenn ich das @ einfügen will
Titel: Re: Typisch Notes
Beitrag von: CLI_Andreas_Schmidt am 28.02.07 - 15:03:35
Das im Backend zu erledigen, scheint hier die einzige Möglichkeit. Leider muss man dann auch alle wichtigen versteckten Felder setzen.  Bei Drei Felden wäre das ja kein Problem. Aber in diesem Fall könnten das mal locker 30 Felder sein. : ) Hier wird Notes zur Fleissarbeit.

Ein Compose auf ein selbst gewähltes doc wäre hier genau das richtige. Ein Backend-Dokument Stück für Stück zusammenzubauen ist doch super lästig.
Titel: Re: Typisch Notes
Beitrag von: w3dev am 28.02.07 - 15:17:03
Nimm doch einfach doc.CopyAllItems(docNew)
Titel: Re: Typisch Notes
Beitrag von: CLI_Andreas_Schmidt am 28.02.07 - 15:21:06
Sind unterschiedliche Masken mit unterschiedlichen Feldern und unterschiedlicher Anzahl von Feldern. So gehts nicht.
Titel: Re: Typisch Notes
Beitrag von: Thomator am 28.02.07 - 15:34:38
Wie wärs mit einer Liste der zu übernehmenden Felder und einer superkleinen Schleife, die eben diese Felder kopiert?
Titel: Re: Typisch Notes
Beitrag von: CLI_Andreas_Schmidt am 28.02.07 - 15:46:00
Die Idee ist nicht schlecht. vielleicht kann man das so dynamisch bauen, dass der Code wiederverwendbar wird.

Ich probiere das mal aus.
Titel: Re: Typisch Notes
Beitrag von: koehlerbv am 28.02.07 - 15:50:32
Gerade der wiederverwendbare Teil ist das kleinste Element - das lohnt also nicht.

Und die List erfordert kaum mehr Schreibarbeit als in der Maske Feld X der Maske A Feld Y der Maske B zuzuordnen - wobei genau dies für die spätere Entwicklung grosse Gefahren birgt, die man mit dem Verfahren wie von Thomas beschrieben umgeht.

Bernhard
Titel: Re: Typisch Notes
Beitrag von: MadMetzger am 28.02.07 - 16:17:53
Also ich finde schon, dass sich das lohnt, die Sache so zu gestalten, dass es wiederverwendbar ist. Ich bin der Meinung, dass sobald man etwas zwei mal schreibt, man versuchen sollte, diese Sache so zu gestalten, dass es wiederverwendbar ist. Und ich glaube nicht, dass das wiederverwendbar Gestalten hier extrem aufwendig ist.

So weit ich das verstanden habe geht es doch rein um ein rüberkopieren und evtl umbenennen von Feldern. Und das geht wunderbar mit einer List zu lösen:
Verpackt man dieses in einer Klasse, die eben diese List dann abarbeitet für ein Quell- und ein Zieldokument(sind dann Attribute der Klasse und werden über den Konstruktor zusammen mit der List gesetzt), so ist das eigentlich relativ schnell geschrieben. Ich habe was ähnliches mal für das kopieren und umsetzen zwischen zwei Datenbanken gemacht.
Titel: Re: Typisch Notes
Beitrag von: koehlerbv am 28.02.07 - 16:26:58
Ich bin ein wirklicher Fan von wiederverwendbaren Code (und habe deswegen schon einige Prügel eingesteckt, wenn die Erstentwicklung "zu lange" dauerte - weil ich eben die Wiederverwertbarkeit gleich berücksichtigt habe - und niemals Lob, als es später dann um so schneller ging).

Hier meine ich aber - an "Lotus-Schmidts" Beispiel  - dass hier der Aufwand nicht so richtig lohnt:
List-Variable füllen = 30 Zeilen
Werte übertragen: 3 Zeilen

Mehr wollte ich mit meiner Kritik nicht sagen.

Bernhard
Titel: Re: Typisch Notes
Beitrag von: MadMetzger am 28.02.07 - 16:31:27
Dann habe ich das eben ein bißchen falsch aufgefasst und wir sind eigentlich der gleichen Meinung.

Aber diese Feldübernahme ist ja eine Sache die durchaus öfter vorkommen kann und man diese eben in einen "Werkzeugkasten" übernehmen könnte und dann bei Bedarf aus der Tasche ziehen kann... Daher kam mir die Aussage komisch vor. Das Verhältnis hier zwischen Code für Iteration und Code für Aufbau der Zuordnung war mir klar, aber ich sehe hier durchaus Nutzen, das so anzugehen.
Titel: Re: Typisch Notes
Beitrag von: flaite am 01.03.07 - 01:43:53
Als Klasse mit zugegebenermassen zu wenig errorhandling

Code
Public Class DocCopyFactory
	Private db As NotesDatabase
	Private fieldNames As Variant
	
	Sub New (fieldNamesIn As String)
		' first get the names of the fields which should be copied. 
		
' if (fieldNamesIn == null) throw new ilegalArgumentException (no idea how to code that in LS)
'		extracted as tokens separated by ~ (by convention) 		
		fieldNames = Split(fieldNamesIn, "~")
		
		Dim s As New NotesSession
		Set db = s.CurrentDatabase
	End Sub
	
	Public Function copyDocument(docToCopy As NotesDocument, formCopyDocument As String) As NotesDocument
		
		' document to return
		Set copyDocument = db.createDocument ' return value
		copyDocument.form=formCopyDocument
		
		' copy the items
		Dim itemDocToCopy As NotesItem
		Forall fieldName In fieldNames
			Set itemDocToCopy = docToCopy.GetFirstItem(fieldName)
			If Not itemDocToCopy Is Nothing Then
				Call itemDocToCopy.CopyItemToDocument(copyDocument, fieldName)
			Else 
				' do some better errorhandling or logging than this. 
				Print "NO GOOD. The item " + fieldName + " does not exist in the document to be copied."
			End If
		End Forall	
	End Function
	
End Class

wird so angesprochen:
(Client code für Klasse)
Code
Dim s As New NotesSession
	Dim docOriginal As NotesDocument
	Dim docNochneKopie As NotesDocument
	Dim aDocCopyFactory As New DocCopyFactory("item1~item2~item3")
	
	Set docOriginal = s.DocumentContext	
	Set docKopie = aDocCopyFactory.copyDocument(docOriginal, "Kopie von original")  
	docKopie.save True, False
	
	Set docNochneKopie = aDocCopyFactory.copyDocument(docOriginal, "Kopie von original")  
	docNochneKopie.save True, False
	

In der Beispiel DB in Agenten DocCopyFactory.

In BeispielDB sich in der Ansicht "Alle" auf das einzige Dokument stellen und dann den einzigen button mit der Beschriftung "push the button" drücken. Der startet den Client code für die Klasse (im Agenten DocCopyFactory).
Titel: Re: Typisch Notes
Beitrag von: Axel am 01.03.07 - 08:54:16

' if (fieldNamesIn == null) throw new ilegalArgumentException (no idea how to code that in LS)
 
      

Kein Wunder, dass Notes dich hier anmeckert. Diese Art von Codierung erinnert mich an C(++ oder #).

In Notes kann das so ausehen:

   Sub New (fieldNamesIn As String)
      ' first get the names of the fields which should be copied.
      
                                if fieldNamesIn = "" Then Exit Sub

'      extracted as tokens separated by ~ (by convention)       
      fieldNames = Split(fieldNamesIn, "~")
      
      Dim s As New NotesSession
      Set db = s.CurrentDatabase
   End Sub


Das wäre die einfachste Form und ist mit Sicherheit ausbaufähig.


Axel
Titel: Re: Typisch Notes
Beitrag von: flaite am 01.03.07 - 10:09:37
Hallo Axel,

ich wusste, dass das kein LS ist. Hab das nur zur Markierung dagelassen, weil mir um 1:45 Uhr nachts das nicht einfiehl.

Gruß Axel
Titel: Re: Typisch Notes
Beitrag von: koehlerbv am 01.03.07 - 11:02:15
Der Code kopiert aber nicht den Inhalt von Feld A (in Doc X) nach Feld B (in Doc Y), sondern schaufelt "nur" die Items einfach so rüber.

Bernhard
Titel: Re: Typisch Notes
Beitrag von: flaite am 01.03.07 - 11:38:16
Man kann ja noch eine weitere Methode hinzufügen, die auch das mapping
original.feldname1 -> kopie.feldnameAnders
anbietet.
Ich weiss auch nicht ob klassische Funktionen in Scriptlibraries hier nicht die bessere Lösung darstellen.
Da ich seit gestern dynamic languages Programmierer bin (hab mein erstes Groovy script geschrieben), seh ich das sowieso nicht mehr so ideologisch.  ;D . (What joker needs curly braced language. My tackle is much lighter than this crap)
Die Klasse führt da auf jedenfall eine gewisse Rigidität ein.
Vielleicht ist es besser das als Funktion zu programmieren:

Code
public Function copyDocument(docToCopy As NotesDocument, formCopyDocument As String, fieldNamesIn As String) As NotesDocument

Dim fieldNames As Variant



Dim db as notesDabase
Set db = docToCopy.CurrentDatabase


fieldNames = Split(fieldNamesIn, "~")
' document to return
Set copyDocument = db.createDocument ' return value
copyDocument.form=formCopyDocument

' copy the items
Dim itemDocToCopy As NotesItem
Forall fieldName In fieldNames
Set itemDocToCopy = docToCopy.GetFirstItem(fieldName)
If Not itemDocToCopy Is Nothing Then
Call itemDocToCopy.CopyItemToDocument(copyDocument, fieldName)
Else
' do some better errorhandling or logging than this.
Print "NO GOOD. The item " + fieldName + " does not exist in the document to be copied."
End If
End Forall
End Function
Titel: Re: Typisch Notes
Beitrag von: MadMetzger am 04.03.07 - 20:15:03
Hier eine Variante meinerseits...

Code
Public Class DocumentCopierFactory
	Private source As NotesDocument
	Private fieldMap List As String
	Private form As String
	Public Sub new(source As NotesDocument, formName As String, fields List As String)
		If formName = "" Or source Is Nothing Or Isempty(fields)Then
			Exit Sub
		End If
		Set Me.source = source
		Me.form = formName
		Forall entry In fields
			Me.fieldMap(Listtag(entry)) = entry
		End Forall
	End Sub
	Public Function copyDocument(targetDb As NotesDatabase) As NotesDocument
		Dim session As New Notessession
		Dim newDoc As Notesdocument
		Dim db As NotesDatabase
		If Not targetDb Is Nothing Then
			Set db = targetDb
		Else
			Set db = session.CurrentDatabase
		End If
		Set newDoc = db.CreateDocument
		newDoc.Form = form
		Forall entry In Me.fieldMap
			Call newDoc.ReplaceItemValue(entry, source.GetItemValue(Listtag(entry)))
		End Forall
		Set copyDocument = newDoc
	End Function
End Class
Titel: Re: Typisch Notes
Beitrag von: koehlerbv am 04.03.07 - 21:18:41
Aber auch hier wird nicht berücksichtigt, dass Andreas unterschiedliche Item-Namen im Quell- und im Zieldokument verwendet.

Bernhard
Titel: Re: Typisch Notes
Beitrag von: LN4ever am 04.03.07 - 21:57:24
Immer, wenn ich beim Kopieren irgendwo "GETFIRSTITEM" lese, denke ich mir, daß die Methode nicht umsonst so heißt - daß es also mehrere gleichnamige Feld(Teile) geben kann.

Und da sind wir mitten im Schlamassel. Die Klassenmethode muß also letztlich mehr leisten, z.B. das Dokument erst einmal in ein neues virtuelles Dokument kopieren und in dem die ITEMS durchorgeln. Bei einem Kopierkandidaten dann das gefundene GETFIRSTITEM removen und nach einem weiteren GETFIRSTITEM des gleichen Namens suchen usw. Ggf. sind auch weitere Objekte eines RT-Feldes zu berücksichtigen wie Attachments, OLE-Einbettungen, Bilder, Objekte.

Und wenn man das zusammenfaßt - dann lohnt es sich, daraus eine Klasse zu machen, mit der man auch Vorlagen ordentlich kopieren kann, in denen es beliebigen Inhalt gibt.

Was bisher hier steht, funktioniert für kleine Testdokumente mit kleinen Feldinhalten und ohne Besonderheiten. Und nur dafür.

Gruß

Norbert
Titel: Re: Typisch Notes
Beitrag von: MadMetzger am 04.03.07 - 22:53:26
@Bernhard: Das kann diese Klasse doch leisten. Die List enthält als Tag den Namen des Quellfeldes und der Eintrag zu dem Tag ist der des Zielfeldes.

@Norbert: Das wiederum alles zu beachten, ist eine interessante Sache... Wenn ich wieder Zeit habe versuche ich einiges davon noch einzubauen und kann wenn gewünscht das Ergebnis hier zur Verfügung stellen.
Titel: Re: Typisch Notes
Beitrag von: koehlerbv am 04.03.07 - 23:43:47
@Bernhard: Das kann diese Klasse doch leisten. Die List enthält als Tag den Namen des Quellfeldes und der Eintrag zu dem Tag ist der des Zielfeldes.

Sorry, Markus, Du hast natürlich vollkommen Recht! Ich hätte schon genauer den Code lesen sollen ...

Norbert: Jo, die Sache ist nicht so einfach  ;)

Bernhard
Titel: Re: Typisch Notes
Beitrag von: Tode am 05.03.07 - 16:41:05
so, nachdem jetzt seitenlang dirskutiert wurde, wie man sowas in Script löst, nur eine kleine Bemerkung zur Lösung der Eingangsfrage:
Das neue Dokument übernimmt so lange die Werte vom "gewählten" Dokument aus der Ansicht, so lange das neu erstellte Dokument nicht gespeichert wurde.

Wenn man also so vorgeht:

Dok 1 erstellen, wenn Dok 2 erstellt werden soll, dann vorher Dok 1 speichern, dann klappts IMHO auch mit der Feld- Übernahme.

So 100% sicher bin ich mir dabei zwar nicht, aber mir wäre schon viel häufiger was in die Hose gegangen, wenn dem nicht so wäre...

Tode
Titel: Re: Typisch Notes
Beitrag von: flaite am 05.03.07 - 20:41:44
@Tode,

redest du nicht ein wenig am Thema vorbei?
Worum geht es hier?
Aus meiner Sicht darum, dass nur die Werte von bestimmten Feldern übernommen werden. Andere dagegen nicht. Und für flexible Lösungen hab ich bestimmte Probleme nachzuvollziehen, warum die hier vorgestellten Script Lösungen nicht effizient sein sollten.

Wenns in dieser Branche keine seitenlangen Diskussionen gäbe...
Wir hätten kein Springframework, kein Jboss, kein Hibernate, kein Groovy, kein Seams, kein .NET Forms, kein ASP.NET, kein Axis2. Kein better swing. Kein Eclipse. Kein Ajax. Kein Dojo, kein EJB3.

For a complex problem there is allways a solution which is neat, simple and plain wrong.

peace Axel
Titel: Re: Typisch Notes
Beitrag von: koehlerbv am 06.03.07 - 01:24:07
Torsten hat schon Recht - aber eigentlich sollte das auch klar sein. Ich bin bei einem CLI zumindest von dieser Kenntnis ausgegangen: In diesem Zusammenhang kommt ein ungespeichertes Dokument nicht in den unmittelbaren Fokus, ergo ... Ich bin daher auch erst an einem ganz anderen Punkt in die Diskussion eingestiegen (ich gehe bei sowas auch immer davon aus - wenn es denn abwendbar ist und nicht wie bei einem DocLink nun zwingend Speicherung erfordert - eine Speicherung auch vermieden werden kann).

Bernhard
Titel: Re: Typisch Notes
Beitrag von: flaite am 06.03.07 - 07:16:58
Eine Speicherung ist aber nicht immer zu jedem Zeitpunkt erwünscht.
Wenn z.B. Validierungsformeln gegen das geöffnete Dokument laufen.
Oder meinetwegen aus dem QuerySave eine Mail verschickt wird. Und für diese Geschäftslogik werden Daten aus dem anderen Dokument benötigt, das aus diesem Dokument heraus erzeugt wurde. In Anwendungen für den Browser ist zum Beispiel sogar sehr oft ein Speichern ziemlich problematisch.
Natürlich sollte man die Features, die die Plattform anbietet a) kennen und b) möglichst immer nutzen.
Es gibt manchmal Fälle, in denen die Geschäftslogik eben mit diesen Features nicht gut abbildbar ist.
Da ist es für einen Anwendungsentwickler immer gut, andere Wege zu kennen. Und die hier gemachten Vorschläge stellen aus meiner Sicht saubere Alternativen dar.
Wenn man auf Grund von technischen Details einer Plattform zu stark die Anwendungslogik unbiegen muß, spricht man von "intrusiveness of the platform".
Zugegebenermassen ist das nicht so einfach und da geb ich Tode mehr Recht als gestern abend. Klar gibts Fälle, in denen Leute ein in der Zukunft schwer wartbares Programmierfeuerwerk abfeuern, obwohl das gar nicht nötig ist. Oft führt das zu Kosten, die erst in der Zukunft aufschlagen. Besonders ärgerlich ist, wenn Leute das machen, weil das in irgendeiner Vorgängerversion mal nötig war und sich dann auch noch für Programmiergurus halten.
Manchmal muß oder sollte ich sogar auf jeder Plattform von den angebotenen eingebauten Features abweichen. Und da ist es immer gut, die Alternativen zu kennen. Und selbstverständlich auch die Kosten, die das möglicherweise in t1...tn erzeugt.
Intrusiveness of a platform ist natürlich nicht "Typisch Lotus Notes". Das gibts auch in Spring, Hibernate, EJB3, SOA, gute objekt-orientierte Praktiken or whatever. Nur macht mich auch dort die Kenntnis von Alternativen (und einer realistischen Einschätzung der daraus resultierenden Kosten) zu einem effektiveren Programmierer.

Gruß Axel
Titel: Re: Typisch Notes
Beitrag von: Tode am 06.03.07 - 12:05:39
diese ganze Diskussion ist ja wirklich schön und gut, und alles was Du sagst ist richtig @Axel.

Trotz allem müssen wir in diesem Forum nicht aus jeder Frage eine Grundsatzdiskussion machen.
Du hast recht: Als ich in die Diskussion eingestiegen bin, habe ich mit meiner Antwort das Thema verfehlt..

Das einzige, worauf ich mit meinem Post hinweisen wollte, war, dass dem Fragesteller höchst- wahrscheinlich mit dieser kurzen Information schon geholfen gewesen wäre, ohne dass er gleich zum Script- Experten werden muss...

Und jetzt könnt Ihr ja gerne in dieser -durchaus interessanten- Diskussion fortfahren.

Gruß
Tode
Titel: Re: Typisch Notes
Beitrag von: MadMetzger am 06.03.07 - 20:31:26
Ich habe mich meiner Klasse nochmal angenommen und einen Hinweis von Norbert einzubauen:
Immer, wenn ich beim Kopieren irgendwo "GETFIRSTITEM" lese, denke ich mir, daß die Methode nicht umsonst so heißt - daß es also mehrere gleichnamige Feld(Teile) geben kann.
Und da sind wir mitten im Schlamassel. Die Klassenmethode muß also letztlich mehr leisten, z.B. das Dokument erst einmal in ein neues virtuelles Dokument kopieren und in dem die ITEMS durchorgeln. Bei einem Kopierkandidaten dann das gefundene GETFIRSTITEM removen und nach einem weiteren GETFIRSTITEM des gleichen Namens suchen usw.
Jedoch frage ich mich gerade, wann ein Item mehrmals vorhanden sein soll und woran man das erkennen kann. Intuitiv dachte ich zuerst, dass man das an den Dokumenteigenschaften erkennen kann (siehe Screenshot im Anhang), wenn ein Feldname mehrmals auftaucht. Scheinbar ist das aber so nicht korrekt, denn wenn ich meine modifizierte Klassse in der ich mit dem virtuellen Dokument arbeite auf diesem Dokument aufrufe, durchläuft er mir meine Schleife, die so lange Items entfernen und kopieren soll, nur ein einziges mal. Kurioserweise taucht das Item im Debugger aber auch nur ein einziges mal auf.

Hier die Schleife:
Code
'iterate over the map of field names
		Forall entry In Me.fieldMap
			Dim item As NotesItem
			
			'get item the first time
			Set item = virtual.GetFirstItem(Listtag(entry))
			
			Do
				'copy item to new document, as long as there are items with the same name
				Call item.CopyItemToDocument(newDoc,entry)
				Call item.Remove()
				'Set item = Nothing
				Set item = virtual.GetFirstItem(Listtag(entry))
			Loop Until item Is Nothing
		End Forall
Ich frage mich gerade ob ich jetzt falsch denke oder ob LS vielleicht mehrere gleichnamige Items zu einem wieder zusammensetzt...  ???
Titel: Re: Typisch Notes
Beitrag von: Glombi am 06.03.07 - 20:36:34
Ein Item kann mehrfach vorkommen, wenn

1. man es mit doc.AppendItemValue erzeugt. Bei jedem Aufruf wird ein neues Item geschrieben, auch wenn es bereits ein Feld mit dem gleichen Namen gibt.
Wer sich das wieder bei IBM ausgedacht hat  ::)

Immerhin stehts ja deutlich in der Hilfe:
Zitat
Hinweis  In general, ReplaceItemValue is favored over AppendItemValue. If an item of the same name already exists in a document, AppendItemValue creates a second item of the same name, and the duplicate items are not accessible except through a work-around. If you are creating a new document, AppendItemValue is safe.

2. es sich um ein Rich Text Feld handelt. Ich vermute mal, das Notes die Dinger jeweils nach 64 K stückelt.

Andreas
Titel: Re: Typisch Notes
Beitrag von: Glombi am 06.03.07 - 20:39:04
und dann noch den:

LotusScript Code Produces Two Rich Text Fields of the Same Name in Notes
Product:
Lotus Notes  >  Lotus Notes  >  Versions 6.0, 5.0, 4.6, 4.5, 6.5
Platform(s):
Platform Independent
Doc Number:
1097725

   Lotus Domino  >  Lotus Domino Designer  >  6.x, 5.x
Platform Independent


Published   09.12.2004
Technote

Problem

The Document Properties on a Notes document shows two entries for the same Rich Text field (RTF).



Solution
This issue occurs on documents that use LotusScript to create or update the Rich Text field.  Two or more Rich Text fields will appear in the Document Properties until the document is edited and saved in the front-end or user interface.  This issue was reported to Quality Engineering and it was determined that Notes is working as designed.

This issue has been observed with the following methods under Notes 4.5x/4.6x/5.x/6.x (with the exception noted):

CreateRichTextItem -    Note: This method does not cause the issue under Notes R5. 
AddNewLine
AppendText
EmbedObject

CreateRichTextItem example:

Call doc.RemoveItem("RTF")
Set rtitem = doc.CreateRichTextItem("RTF")
Call rtitem.AppendText(value)

AddNewLine example:

Set rtitem=doc.getfirstitem("RTF")
Call rtitem.addnewline(1)

AppendText example:

Set rtitem=doc.getfirstitem("RTF")
Call rtitem.appendtext("add some text")


EmbedObject example:

     Set rtitem = New NotesRichTextItem( doc, "Body" )
     Set object = rtitem.EmbedObject ( EMBED_ATTACHMENT, "", "d:\work\test.txt")


Note:  You may observe that using the New method with the NotesRichTextItem class will produce only one field entry.  This is actually undesirable as the Item is not properly added to the Document object.  See the related document noted below.

Example:

Call doc.RemoveItem("RTF")
Dim rtitem as New NotesRichTextItem(doc, "RTF")
Call rtitem.AppendText(value)

Supporting Information:

IMPORTANT NOTE:  The above is a sample script, provided only to illustrate one way to approach this issue.  Notes Support will not be able to customize this script for a customer's own configuration.

Workaround:

WARNING:  This workaround below should not be used with Notes Release R5.  Under Notes R5 the code below will delete the RTF field completely and data will be lost.   The workaround below is applicable only to 4.5x/4.6x.   The workaround should not be applied to documents which have been saved in the user interface (UI); this is because saving the document in the user interface clears the second unwanted RTF field.   It is recommended that the workaround (that is, using the NotesItem Remove method) be applied in only the same agent that creates the Rich Text field.   

Example:

Set rtitem = doc.CreateRichTextItem("RTF")
Call rtitem.AppendText(value)
' We have now 2 Body fields
Set rtitem = doc.GetFirstItem( "RTF" ) ' we return to the first body field
Call rtitem.Remove                                     ' we remove it

Related Documents:

In The Document Properties a Field Has Entries For Text and Rich Text
Document #:  1103415   (180058)   
Titel: Re: Typisch Notes
Beitrag von: MadMetzger am 06.03.07 - 20:48:33
Hm... irgendwie helfen mir diese Sachen nichts.

Ich sehe bei sowohl bei altem Dokument (s. früheres Posting der Screenshot) als auch beim neuen Dokument (s. hier der Screenshot) das Item mehrfach, aber bei  Betrachtung im Debugger ist es nur einmal da. Das ist es was mich wundert... Von mir aus können die Items ja mehrfach vorkommen, das soll ja gerade dieses Script mit abdecken... Nur erscheint mir das gerade nicht wirklich erforderlich, wenn das Item ja eh nur einmal im Debuger beim Dokument unter Items auftaucht.
Titel: Re: Typisch Notes
Beitrag von: flaite am 06.03.07 - 22:46:54
Ich glaub das sich das mit den RichTextItems anders verhält als mit dem von Andreas geschilderten appendItem Feature.
Reine Hypothese: Ein RT-Item wird zwar zerstückelt in 64k Einheiten, aber für die Script-API ist das logisch immer nur ein RichTextItem, obwohl es physisch anders ist. (und die Eigenschaftsbox ist die physische Sicht). Kann aber sein, dass das überhaupt nicht so ist.
Titel: Re: Typisch Notes
Beitrag von: MadMetzger am 06.03.07 - 22:55:13
Wahrscheinlich ist das so bei RT-Items, wie du es beschreibst, Axel... Mit TextItems habe ich noch nicht experimentiert. Werde ich noch tun, aber nicht mehr heute...
Titel: Re: Typisch Notes
Beitrag von: MadMetzger am 13.03.07 - 18:58:31
Also ich habe jetzt mal mit TextItems herumexperimentiert. Ich habe über Doc.appendItemValue(x) einem Item Werte hinzugefügt und danach war in den Dokumenteigenschaften auch das Item mehrfach vorhanden. Nur verhielt es sich in dem Script wieder so wie mit den RT-Items, das heißt jedes Item mit mehrfach vorhandenem Namen wurde nur einmal gefunden trotz Würgaround mit temporärem Dokument, in das per copyAllItems die Items kopiert wurden. Möglich ist natürlich, dass copyAllItems auch nur die "GetFirstItem"s erreicht.

Vielleicht hat ja jemand anderes die Muße sich diese Sache mal anzuschauen. Ich würde dann meinen bisher vorhandenen Quellcocde zum Ausprobieren zur Verfügung stellen.
Titel: Re: Typisch Notes
Beitrag von: koehlerbv am 13.03.07 - 22:24:32
Notes teilt Items immer in Portionen kleiner als 64 KB auf - hier liegt innerhalb der ODS die "magische Grenze".

NotesDocument.GetFirstItem greift sich jedoch immer nur das erste Item mit gleichem Namen. Es gibt jedoch Workarounds dafür, siehe
Soweit mir bekannt geht das nur mit einem Trick: Erstelle ein neues temporäres Dokument und kopiere alle Items. Wenn das Item "Received" heisst, nenne es um in Received_<i>. Und das solange es ein Item namens "Received" gibt.

Hier der Code:
Dim session As New NotesSession
   Dim db As NotesDatabase
   Dim dc As NotesDocumentCollection
   Dim doc As NotesDocument
   Dim tempdoc As NotesDocument
   Dim item As NotesItem
   Dim i As Integer
   
   Set db = session.CurrentDatabase
   Set dc = db.UnprocessedDocuments
   Set doc = dc.GetFirstDocument
   
   Set tempdoc = db.CreateDocument
   Call doc.CopyAllItems(tempdoc,False)
   i = 1
   Forall feld In doc.Items
      If feld.Name = "Received" Then
         Call tempdoc.ReplaceItemValue("Received_" & Cstr(i), tempdoc.Received(0))
         Set item = tempdoc.GetFirstItem("Received")
         Call item.Remove
         i = i + 1
      End If
   End Forall
   
   For i = 1 To i - 1
      Print tempdoc.GetItemValue("Received_" & Cstr(i))(0)
   Next

Andreas

NotesItem.CopyToDocument nimmt jedoch immer alle Items gleichen Namens mit. Gleiches gilt auch für NotesDocument.CopyAllItems.

NotesDocument.AppendItemValue ist daher durchaus gefährlich, wenn man das "einfach so" einsetzt. .ReplaceItemValue tut in der Regel das, was man eigentlich will.

Bernhard