Das Notes Forum

Domino 9 und frühere Versionen => ND6: Entwicklung => Thema gestartet von: eknori am 15.08.05 - 17:15:51

Titel: NotesRichtextNavigator und RTRange
Beitrag von: eknori am 15.08.05 - 17:15:51
Hat jemand erfahrung mit diesen beiden Klassen ??

Ich knobele gerade an folgenden Problem:

Ein RichtextItem enthält z.B. folgenden Text:

Sehr geehrter Herr <<RCPT>>,

Ihre Anfrage <<REQNUMBER>> wird von unserem Mitarbeiter <<SUPPORTER>> bearbeitet.

Ich möchte jetzt die <<>> Tags durch Werte aus dem Ticket ersetzen, wobei die Strings innerhalb der <<>> Feldnamen darstellen.

Mittels

   If rtnav.FindFirstString("<<", _
                        RT_FIND_CASEINSENSITIVE) Then
                           Do
                              Call rtrange.SetBegin(rtnav)
                              'Messagebox rtrange.textParagraph,, "<<"
                              ' und wie geht es dann hier weiter ??                     
                              Loop While rtnav.FindNextString("<<", _
                           RT_FIND_CASEINSENSITIVE)
                        Else
                           Messagebox "<<",, "String not found"
                        End If

komme ich auch immer an das nächste <<

Aber wie mache ich jetzt das Replace ?

   If rtnav.FindFirstString("<<", _
                        RT_FIND_CASEINSENSITIVE) Then
                           Do
                              Call rtrange.SetBegin(rtnav)
                              'Messagebox rtrange.textParagraph,, "<<"
                              While rtrange.FindAndReplace _
                              ("<<RCPT>>",_ ' find
                              CommonNameString (Trim(atWord(Cstr(m),"|",1))),_ ' replace
                              RT_FIND_CASEINSENSITIVE) > 0
                                 Call rtItem.Update ' Must update before looping
                              Wend
                              
                              Loop While rtnav.FindNextString("<<", _
                           RT_FIND_CASEINSENSITIVE)
                        Else
                           Messagebox "<<",, "String not found"
                        End If

Dieses Konstrukt funktioniert nicht ( ich weiß, daß hier einiges Hardcodiert ist, aber <<RCPT>> ist der erste Tag im Text.

Im Debugger meckert er immer die Zeile mit dem Wend an.

Jemand schon mal die Kombination der Klassen programmiert ( In der Notes Hilfe ist alles separat beschrieben, aber nicht in der Kombination ) Irgendwie scheinen sich die ursprünglich erzeugten Objecte rtNav und rtRange selber zu "zerstören"
Titel: Re: NotesRichtextNavigator und RTRange
Beitrag von: flaite am 15.08.05 - 17:39:51
Ich habe ein ähnliches "RichText Templating" mit den neuen Klassen vor.
Deshalb hab ich ein deutliches Interesse an deinem Erfolg.

Ich hoffe, ich habe das beim raschen Überfliegen verstanden, aber für mich wirkt es eventuell erfolgversprechender, wenn wir statt eines Replace ein ganz neues RichTextItem mit eigenem RichTextNavigator erzeugen und das dann Stück für Stück aus dem geparsten Zeug erzeugen?

Möglicherweise ist das ein bischen verwirrend und vielleicht auch falsch aber ich bin selbst noob in diesem Thema.

Axel
Titel: Re: NotesRichtextNavigator und RTRange
Beitrag von: eknori am 15.08.05 - 17:53:28
Zitat
wenn wir statt eines Replace ein ganz neues RichTextItem mit eigenem RichTextNavigator erzeugen und das dann Stück für Stück aus dem geparsten Zeug erzeugen

ist zumindest einen Versuch wert.

Habe mir auch schon überlegt, mir erst die <<TAG>> Tags in ein Array zu schreiben und dann in einem zweiten Step mit FindReplace das ursprüngliche RTItem zu bearbeiten. Ich glaube, daß ist einfacher, als sich jedesmal den RTNavigator neu zu erzeugen ...
Titel: Re: NotesRichtextNavigator und RTRange
Beitrag von: eknori am 15.08.05 - 18:13:47
                        strTemp = ""
                        If rtnav.FindFirstString("<<", _
                        RT_FIND_CASEINSENSITIVE) Then
                           Do
                              Call rtrange.SetBegin(rtnav)
                              strTemp = strTemp + "~" + Mid(rtrange.textRun, 3, Instr( rtrange.textRun,">") -3 )
                              Loop While rtnav.FindNextString("<<", _
                           RT_FIND_CASEINSENSITIVE)
                        End If
                        Dim ret As Variant
                        ret = Split ( strTemp, "~" )
                        
                        Msgbox ret(1)

liefert mir in ret alle TAGS des RtItems zurück; der Rest ist dann recht einfach ...
OK, man muß ret jetzt noch unique zu machen.

dann kann man mir

forall x in ret.values

sich jeweils einen Wert nach dem anderen vornehmen, sich den Wert des korrespondierenden Items aus dem Doc in der Collection holen und dann beschwingt mit:

While rtrange.FindAndReplace _
"<<" & CStr(x) & ">>",_ ' find
   <ReplaceWithWertAusDoc>,_ ' replace
   RT_FIND_CASEINSENSITIVE) > 0
   Call rtItem.Update ' Must update before looping
Wend

alle Vorkommen von "<<" & CStr(x) & ">>" zu ersetzen.

ein rtItem.Update hinterhergeschossen und schon ist man fertig, oder ?

Das Drumherum ist dann Fleißarbeit, so mit ERRHANDLE und so ...
Titel: Re: NotesRichtextNavigator und RTRange
Beitrag von: eknori am 15.08.05 - 19:43:49
OK, kurz vor der Tagesschau noch schnell der funktionierende Code ( Ohne grossartiges ERRHANDLE ) für ein dynamisches FindandReplace in einem RT Item

                                                         Set rtnav = rtItem.CreateNavigator
                        Set rtrange = rtItem.CreateRange
                        strTemp = ""
                        If rtnav.FindFirstString ( TAG_PREFIX, _
                        RT_FIND_CASEINSENSITIVE) Then
                           Do   
                              Call rtrange.SetBegin ( rtnav )
                              strTemp = strTemp + TAG_DELIMITER + Mid ( rtrange.textRun, 3, Instr( rtrange.textRun,TAG_SUFFIX ) -3 )
                           Loop While rtnav.FindNextString ( TAG_PREFIX, RT_FIND_CASEINSENSITIVE )
                        End If
                        
                        Dim arrRetFieldNames As Variant
                        Dim ret As Integer
                        arrRetFieldNames = Arrayunique ( Split ( strTemp, TAG_DELIMITER ), 5 )
                        
                        Set rtrange = rtItem.CreateRange
                        Dim strT As String
                        Forall t In arrRetFieldNames
                           strT = Cstr ( t )
                           If ( Not strT = "" ) Then
                              If ( Not ItemTextExists ( TicketDoc, strT ) = False)  Then
                                 ret =  rtrange.FindAndReplace _
                                 ( TAG_PREFIX & strT & TAG_SUFFIX,_ ' find
                                 TicketDoc.GetFirstItem( strT ).Text, _ ' replaceWith
                                 RT_REPL_ALL) > 0
                                 
                                 Call rtItem.Update ' Must update before looping
                                 
                              End If
                           End If
                        End Forall

@Axel: Ist das so i.O. ? Oder hast du noch eine bessere Idee ?

Oder hat sonstwer noch eine zündende IDEE ?? ( viele Kosumenten, wenig Produzenten )
Titel: Re: NotesRichtextNavigator und RTRange
Beitrag von: Manfred Dillmann am 15.08.05 - 20:58:47
Hallo Ulrich,

muss ich nachfragen:
Du "sammelst" zu Beginn Deiner Routine aus dem Richtext-Item die Platzhalter zusammen. Ist es dass, was Du mit "dynamischen FindAndReplace" meinst?

Sind die möglichen Platzhalter nicht schon vorher bekannt?

Gruß
Manfred
Titel: Re: NotesRichtextNavigator und RTRange
Beitrag von: eknori am 15.08.05 - 21:03:02
Zitat
Sind die möglichen Platzhalter nicht schon vorher bekannt?

Wenn du die HelpdeskDB meinst, ja. Aber ich verwende den Code ( und die Designelemente ) auch in anderen DBs. Und da weiß ich nicht, welche Felder angesprochen werden .. Das ganze DIng, soll irgendwann mal so flexibel wie möglich sein ... nach dem Motto : Kopiere dies und das Designelemet in deine bestehende DB rein; konfiguriere dies und das und schon kannst du Benachrichtigungen nach deinen Vorstellungen rausschicken.

Das ist das Ziel, nicht mehr, nicht weniger ...
Titel: Re: NotesRichtextNavigator und RTRange
Beitrag von: Manfred Dillmann am 15.08.05 - 21:11:27
>>Aber ich verwende den Code ( und die Designelemente ) auch in anderen DBs. Und da weiß ich nicht, welche Felder angesprochen werden .. Das ganze DIng, soll irgendwann mal so flexibel wie möglich sein ...<<

OK. Dann ist die Lösung doch schon mal prima so.

Schönen Abend noch...  :)

Manfred
Titel: Re: NotesRichtextNavigator und RTRange
Beitrag von: eknori am 15.08.05 - 21:13:41
Zitat
OK. Dann ist die Lösung doch schon mal prima so.

Also nicht überzeugend ... Irgendwie Bockwurst ohne Senf ( scharf ) ??
Habe zumindest im Web noch keine Lösung gefunden, die meiner auch nur annähernd ähnlich kommt.
Oder es war keiner so d ... seine Lösung zu posten ...

Für meine Belange funktioniert der Code
Titel: Re: NotesRichtextNavigator und RTRange
Beitrag von: Manfred Dillmann am 15.08.05 - 21:23:37
Zitat
Also nicht überzeugend ... Irgendwie Bockwurst ohne Senf ( scharf ) ??

Ach quatsch, das ist klasse.

Du könntest etwas ausprobieren, musste ich im Moment selbst testen, verwende ich so in der madicon easyMail  ;) Anwendung.

Wenn Du ein rtrange festlegst:

Set doc = dc.GetFirstDocument
Set body = doc.GetFirstItem("Body")
Set rtrange = body.CreateRange

umfasst dieser rtrange das gesamte RichtextItem. Daher ist ein einziger Aufruf von:

count& = notesRichTextRange.FindAndReplace( target$ , replacement$ , [ options& ] )

ausreichend, wenn Du den optionalen Parameter "RT_REPL_ALL (16) to replace all occurrences of the search string" verwendest.

Das könnte etwas Performance bringen, da Du dann
- nicht mehr selbst nach dem Vorkommen suchen musst und
- Du nicht selbst von "Treffer" zu "Treffer" iterieren musst.

Gruß
Manfred
Titel: Re: NotesRichtextNavigator und RTRange
Beitrag von: Manfred Dillmann am 15.08.05 - 21:29:05
Ach, da fällt mir noch was ein, kannst Du bitte mal ausprobieren?

Man kann der Methode:

count& = notesRichTextRange.FindAndReplace( target$ , replacement$ , [ options& ] )

leider kein "" (also nix) als replacement$ übergeben. Wenn ich das mache, wird der "Platzhalter" einfach so wie er ist belassen. Minimum ist ein Leerzeichen (" ") erforderlich. Ist das bei Dir auch so?

Es gelingt einem so nicht, den "Platzhalter" komplett aus dem Inhalt des rtitems "rauszuwerfen".

Hast Du da noch eine Idee?

Gruß
Manfred
Titel: Re: NotesRichtextNavigator und RTRange
Beitrag von: flaite am 15.08.05 - 21:29:50
@Axel: Ist das so i.O. ? Oder hast du noch eine bessere Idee ?

Hm. Sieht gut aus. Danke.
Heute ist großer aber fixe-eine-verdammte-Schwäche-im-RDBMS-Design-und-ziehe-das-durch-2-Layer-Abend in einer anderen Anwendung >:(
Ich schau mir das auf jeden Fall mal an. Für mich schreibst du C-code. Ich kann das so nicht lesen. Müsste ich mir im Debugger mal anschauen.  ;D
Was ich möchte ist eine Art Serienbrieffunktionalität, die auf den neuen RichText Funktionalitäten beruht. Meine Kunden haben nicht unbedingt alle MS-Word.
Da drin noch eine Art mini-Datenzugriffssprache, um auf Felder aus Dokumente auf vorher definierten Datenbanken/Ansichten zuzugreifen. Letzteres ist aber nicht so neu, wie die Möglichkeiten, die diese neuen RichText Klassen bieten.
Wichtig ist das die User Fehlermeldungen bekommen, mit denen sie etwas anfangen könnnen.

Die allgemein gebräuchlichen Teile werde ich jedenfalls auch posten.

Gruß Axel
Titel: Re: NotesRichtextNavigator und RTRange
Beitrag von: eknori am 15.08.05 - 21:30:10
Zitat
count& = notesRichTextRange.FindAndReplace( target$ , replacement$ , [ options& ] )

ds ist mir klar; ich hatte das ja schon hier http://www.atnotes.de/index.php?topic=24716.msg158562#msg158562

gepostet.

aber ich kenne ja normalerweise zunächst target$ , replacement$ nicht ...

target$ hole ich mir einmalig, indem ich das Template auslese; Replacement$ hole ich mir aus dem doc in der collection of docs, die irgendwie an den Mann gebracht werden müssen.



Titel: Re: NotesRichtextNavigator und RTRange
Beitrag von: eknori am 15.08.05 - 21:32:31
Zitat
Für mich schreibst du C-code
C-Code = nicht zu gebrauchender Code oder
c-Code = der Sprache C ähnlicher Code ??
Titel: Re: NotesRichtextNavigator und RTRange
Beitrag von: Manfred Dillmann am 15.08.05 - 21:41:51
Zitat
aber ich kenne ja normalerweise zunächst target$ , replacement$ nicht ...

Zu Beginn Deiner Routine holst Du dir die Platzhalter, richtig? Das ist OK, die kennst Du ja nicht.

Weiter unten iterierst Du aber dann von "Fundstelle" zu "Fundstelle". Da könnte ein einziger Aufruf nach der von mir beschriebenen Weise ausreichen - natürlich ein Aufruf pro Platzhalter.

Manfred
Titel: Re: NotesRichtextNavigator und RTRange
Beitrag von: eknori am 15.08.05 - 21:44:22
ok, hab*s kapiert ... DANKE

habe das Posting ( http://www.atnotes.de/index.php?topic=25016.msg159881#msg159881 ) entsprechend ge-updated.
Titel: Re: NotesRichtextNavigator und RTRange
Beitrag von: Manfred Dillmann am 15.08.05 - 21:51:23
>> ok, hab*s kapiert ... DANKE<<

Na, klappt doch...  ;D

BTW:
Liest Du noch mal meinen Post von oben? Von wegen "Platzhalter  komplett rauswerfen"...

Manfred
Titel: Re: NotesRichtextNavigator und RTRange
Beitrag von: eknori am 15.08.05 - 21:59:07
das habe ich so noch nicht getestet´... muss ich mal machen
Titel: Re: NotesRichtextNavigator und RTRange
Beitrag von: Manfred Dillmann am 15.08.05 - 22:04:23
>> das habe ich so noch nicht getestet´... muss ich mal machen<<

Ja, wäre prima. Danke. Ergebnis auch gerne per eMail...

Noch ein Hinweis:
Deine oben geänderte Routine (der Austausch) ist nun nicht mehr "caseINsensitive". Musst Du noch was "dazutun".  :)

Servus
Manfred
Titel: Re: NotesRichtextNavigator und RTRange
Beitrag von: flaite am 15.08.05 - 22:09:18
Zitat
Für mich schreibst du C-code
C-Code = nicht zu gebrauchender Code oder
c-Code = der Sprache C ähnlicher Code ??
Das Zweite.
Wenn ich sage, dass ich das jetzt nicht lesen kann, heisst das überhaupt nicht, dass ich das für schlecht halte.
Ich habe großen Respekt vor dem Code von anderen Leuten. Ok. Sicher nicht alles. Aber das sieht extrem nach der Kategorie "gut, aber ich kapier das nicht direkt" aus. Bin ja mit diesen Klassen auch nicht so vertraut.  ;)
Titel: Re: NotesRichtextNavigator und RTRange
Beitrag von: eknori am 15.08.05 - 22:11:49
Zitat
Bin ja mit diesen Klassen auch nicht so vertraut

Kann ich nachvollziehen; bis vor ein paar Stunden kannte ich auch nur die halbe Whrheit; Dank an Manfred Dillmann für die Nachhilfe   :D

Bemerkenswert finde ich, daß sich offensichtlich nur knapp eine Handvoll für die Anwendung der Klassen interessiert; immerhin aber gute Leute  :D
Titel: Re: NotesRichtextNavigator und RTRange
Beitrag von: heini_schwammerl am 16.08.05 - 01:39:49
Zitat
Bemerkenswert finde ich, daß sich offensichtlich nur knapp eine Handvoll für die Anwendung der Klassen interessiert; immerhin aber gute Leute  :D
Ich kann zu meiner Verteidigung nur vorbringen das in Bayern heute Feiertag ist. Aber der COdeschnipsel ist schon klasse. Danke dafür.
Titel: Re: NotesRichtextNavigator und RTRange
Beitrag von: eknori am 16.08.05 - 06:55:05
Zitat
Noch ein Hinweis:
Deine oben geänderte Routine (der Austausch) ist nun nicht mehr "caseINsensitive". Musst Du noch was "dazutun". 

Ja nee, iss klar  ;D
Titel: Re: NotesRichtextNavigator und RTRange
Beitrag von: Roalf am 16.08.05 - 12:28:33
Noch ein kleiner Hinweis zu der Ersetztengeschichte:

die funktion notesRichTextRange.FindAndReplace kann nicht nur keine "", sondern (und das finde ich schlimmer)  auch keine mehrzeiligen Strings. Sprich: an eine gefundene Position einen String, der u.a. einem Zeilenumbruch CHR(13) enthält, zu setzen.

Und auch dein Codeschnispel kann das nicht...denn, sobald du an eine Stelle einen Text mit mehr als einer Zeile einfügst, verweigert FindNextString die Arbeit. Auch das rtitem.Update hilft da nicht.
Und das ist wohl der Grund warum FindAndReplace keine Umbrüche verarbeitet. Intern wird diese Funktion wohl auch mit einer Schleife FindFirst/FindNext arbeiten....und deshalb entfernt FindAndReplace kurzerhand alle CR/LF aus dem zweiten Parameter....

Wenn also die gefundene Stelle durch mehrzeilige Teile ersetzt werden soll, muss etwas mehr passieren....bei Interesse poste ich hier gerne den Code.
Titel: Re: NotesRichtextNavigator und RTRange
Beitrag von: eknori am 16.08.05 - 12:35:13
dann lass mal sehen ...
Titel: Re: NotesRichtextNavigator und RTRange
Beitrag von: Roalf am 16.08.05 - 12:58:16
ich traue mich fast nicht diese Code zu Posten....so schwachsinnig und umständlich mutet er an. Aber er ist der einzige der zu dem von mir gewünschten Ergebniss führte:


also, erste Schleife:
.
.
.
   Set rtnav = body.CreateNavigator
   crlfcount = 0
   pos = 0
   If rtnav.FindFirstString(CRLF , RT_FIND_CASEINSENSITIVE) Then
      Do
         crlfcount = crlfcount + 1
      Loop   While rtnav.FindNextString(CRLF , RT_FIND_CASEINSENSITIVE)
   End If
.
.
.

diese holt nur die anzahl der stellen die es zu ersetzten gilt.
das eigendliche ersetzen erfolgt dann über eine doppelte schleife (da es kein FindNthString gibt) :
.
.


   For i = 0 To crlfcount -1
      If rtnav.FindFirstString(CRLF , RT_FIND_CASEINSENSITIVE) Then
         While pos < i
            Call rtnav.FindNextString(CRLF , RT_FIND_CASEINSENSITIVE)
            pos = pos + 1
         Wend
      End If
      Call body.BeginInsert( rtnav,True)
      Call body.APpendText(param)
      Call body.EndInsert   
   Next
.
.
.


----
da ich diese Teile aus einem größeren Zusammenhang kopiert habe ,sind sie in dieser Form nicht getestet. Ich hoffe aber das sie das Prinzip zeigen.
Nämlich das es für jede Position immer wieder mit einem FindFirstString beginnt...und dann mit FindNextString zum Punkt gehangelt wird. (da ja, wie ich oben anmerkte, FindNextString nur noch "habe fertig" zurückliefert wenn vorher ein CHR(13) eingefügt wurde, obwohl es ggf. noch mehr zu finden gäbe,
Titel: Re: NotesRichtextNavigator und RTRange
Beitrag von: Thomas Schulte am 16.08.05 - 13:22:33
Wobei man damit jetzt wieder beim manuellen Hangeln angelangt wäre. Das hatten wir doch schon.
Hmm, wenn man die beiden Methoden kombinieren könnte. So nach dem Motto alles was einfach ist mit FindAndReplace und den Rest dann mit der Methode von Roalf.
Titel: Re: NotesRichtextNavigator und RTRange
Beitrag von: eknori am 16.08.05 - 17:56:58
@Roalf:

Danke für die Code Snippets; werde ich testen und sehen, wie ich das in den bestehenden Code zu integrieren.

Habe mir überlegt, beim Stamp Documents Feld noch ein paar Varianten einzubauen:

test0 | Hallo Welt  ( auch multiValue möglich mit Hallo;Welt;Tolles;Wetter;heute )
+test1 | Hallo Welt
#test2 | 1
test3 | <<FieldName>>


test0 | Hallo Welt:

wie ReplaceItemValue; erstellt das Feld, wenn es noch nicht vorhanden ist und fügt den String "Hallo Welt" in das Feld ein.


+test1 | Hallo Welt

Hängt den String "Hallo Welt" an das bestehende Feld an


#test2 | 1

addiert den Wert 1 zu dem bestehenden Wert in Feld test2


test3 | <<FieldName>>

Hole einen Wert auf dem Feld FIELDNAME und schreibt diesen in Feld test3

wobei auch Kombinationen möglich sind; wie z.B.

#test3 | <<FIELDNAME>>

addiere den Wert aus FIELDNAME zu Feld test3

Keine Ahnung, ob man so etwas braucht, aber besser man hat, als man hätte  ;D