Das Notes Forum
Domino 9 und frühere Versionen => ND6: Entwicklung => Thema gestartet von: baces am 23.05.05 - 14:44:41
-
Hallo,
wenn wir einen Call "in Mail umwandeln" wollen,
bekommen wir einen Fehler im Notes "Spoolmessage: 13 on line 57: Type mismatch" - und der Call wird restlos aus der DB gelöscht. Das ist bestimmt nicht so beabsichtigt, oder? :P
-
Passiert das bei Calls, die schon mit der Version 1.0.8 erzeugt wurden oder sind das Dokumente, die mit einer früheren Version erzeugt wurden ?
-
Bei Calls die direkt mit 1.08 erstellt worden sind.
-
dann hab ich noch ne Frage:
Wenn ich aus einem Call heraus eine Mail schreibe wird diese als Teilaufgabe gespeichert - Gut so. Auch kann der Anwender auf diese Mail antworten und die Mail wird dem Call zugeordnet - auch Klasse.
Nur, wie bekommt der Supporter mit, daß eine Mailantwort vom Anwender vorliegt ???
-
gucke mal in der Konfiguration nach, ob die die folgenden schlüssel hast. Darüber wird das Versenden der Mails gesteuert.
-
der Wurm steckt in der function SPOOFMESSAGEWITHITEM in der lib.appl.functions.
Fälschlicherweise wird in der Fehlermeldung "SpoofMessage" als Thread ausgegeben ( Thomas hatte das im ERRHANDLE hardcoded )
Ich habe das ERRHANDLE jetzt mal ein wenig umgeschrieben
EXITPOINT:
Exit Function
ERRHANDLE:
SpoofMessagewithitem = False
If UseOpenLog Then
Call LogError
End If
Print Getthreadinfo(LSI_THREAD_PROC) & ": " &Trim$(Str$(Err)) & " on line " & Cstr(Erl) & ": " & Error$
Resume EXITPOINT
Die Funktion GetThreadInfo() sollte man sich mal in der Designer Hilfe ansehen; außerdem habe ich den Support für Julian Robichaux's OpenLog eingebaut. (http://www.openntf.org/Projects/pmt.nsf/ProjectHome?ReadForm&Query=OpenLog )
Wenn du Lust hast, kannst du ja mal die besagte Funktion debuggen; ich habe heute irgendwie keine grosse Lust dazu; muss wohl am Wetter liegen ;D
-
ersetze mal die Funktion SPOOFMESSAGEWITHITEM durch folgeneden Code ( experimentell)
Function SpoofMessagewithitem( sendas As String, sendto As Variant, CopyTo As Variant, subject As String, message As String , itembody As notesrichtextitem) As Integer
On Error Goto ERRHANDLE
Dim session As New NotesSession
Dim item As NotesItem
Dim mailbox As New NotesDatabase("","")
Dim current As NotesDatabase
Dim maildoc As NotesDocument
Dim rtitem As NotesRichTextItem
Dim me_item As NotesItem
Dim ok As Integer
SpoofMessagewithitem = True
Set current = session.CurrentDatabase
Call mailbox.Open( current.server, "mail.box" )
Set maildoc = mailbox.CreateDocument
Set item = maildoc.ReplaceItemValue("Form","Memo")
Set item = maildoc.ReplaceItemValue("From", sendas)
Set item = maildoc.ReplaceItemValue("Subject", subject)
Set item = maildoc.ReplaceItemValue("SendFrom", sendas)
Set item = maildoc.ReplaceItemValue("SendTo", sendto)
Set item = maildoc.ReplaceItemValue("CopyTo", copyto)
Set item = maildoc.ReplaceItemValue("Recipients", sendto)
Set rtitem = maildoc.CreateRichTextItem( "Body" )
If message <> "" Then
Call rtitem.AppendText( message )
End If
Call rtitem.appendrtitem(itembody)
Set item = maildoc.ReplaceItemValue("PostedDate", Now())
Set item = maildoc.ReplaceItemValue("ComposedDate", Now())
Set item = maildoc.ReplaceItemValue("DeliveredDate", Now())
Set item = maildoc.ReplaceItemValue("Principal", sendas) '
'maildoc.EncryptOnSend = False
Call maildoc.Save( True, False )
EXITPOINT:
Exit Function
ERRHANDLE:
SpoofMessagewithitem = False
'If UseOpenLog Then
'Call LogError
'End If
Print Getthreadinfo(LSI_THREAD_PROC) & ": " &Trim$(Str$(Err)) & " on line " & Cstr(Erl) & ": " & Error$
Resume EXITPOINT
End Function
´
ich weiss, der doclink zur Antwort fehlt noch ... liefere ich nach sobald die Sonne weg ist ;D
oh, dumme Frage, hast du eigentlich Designer Rechte ??
-
Hi Ulrich, Hi Thomas,
das Exportieren der Sprachen funktioniert nicht. Hier kommt die Meldung "Ungültiger Funktionsaufruf". Ist aber nur ein kleiner Bug.
Im Script "lib.appl.functions" steht "Const maxlength = 50" eingetragen, jedoch verwendet ihr im Dokument "SCRIPTMESSAGES" mehr als 50 Zeichen, daher die Fehlermeldung.
-
Danke für den Hinweis; da bin ich schon einmal drüber gestolpert. Hmm, da muss ich mir mal was anderes einfallen lassen
-
Habe dir Routine noch einmal überarbeitet und ein Errorhandling eingefügt; jetzt ist sie zumindest ein wenig geschwätziger ...
Sub ExportLanguageFile
%REM
###################################################################################
Goal:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Arguments: Description:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Return:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Example:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
VERSION / WHEN / WHO / CHANGES
'###################################################################################
%END REM
On Error Goto ERRHANDLE
Dim s As New NotesSession
Dim key As String
Dim fg As New FileGuard
Dim fn As String
Dim outfile As Integer
Set db = s.CurrentDatabase
key = Ucase(Inputbox$("Enter Language"))
If key ="" Then Exit Sub
Set v = db.GetView("LanguageDocs")
Set col = v.GetAllDocumentsByKey(key)
If col.Count = 0 Then
Msgbox "Language not available"
Exit Sub
End If
fn = GetPath +"\Language_"+ key +".lng"
outfile = fg.handle
Open fn For Output As outfile
Dim pb As New LNProgressBar(False) ' // init progressbar
Call pb.SetText("Exporting ...","")
Call pb.SetProgressRange(col.Count)
Call pb.SetProgressPos(1)
For i = 1 To col.Count
Call pb.SetProgressPos( Clng( i ) )
Set doc = col.GetNthDocument(i)
Set item = doc.GetFirstItem("Type")
Print #outfile, ";" + Ucase(item.Text)
Set item = doc.GetFirstItem("Typestring")
Forall x In item.Values
If Not x = "" Then
key = atword(Cstr(x),cSep,1)
Print #outfile, key + cSep + Space(maxlength - Len(key)) + Trim(atword(Cstr(x),cSep,2))
End If
End Forall
Print #outfile, " "
Next
Close outfile
Delete pb
EXITPOINT:
Exit Sub
ERRHANDLE:
If UseOpenLog Then
Call LogError
End If
Print Getthreadinfo(LSI_THREAD_PROC) & ": " &Trim$(Str$(Err)) & " on line " & Cstr(Erl) & ": " & Error$ & " Key: " & key & " exceeds maxlength " & maxlength &" / " & Len(key)
Resume EXITPOINT
End Sub
Wenn du jetzt noch maxlength auf 60 setzt, ist erst einmal Ruhe
-
Die Sommerpause bis zum Release 1.0.9 habe ich heute genutzt, einmal ( fast ) alle Designelemente zu sichten und an den Stellen, woe es "knallen" könnte mit einem verbesserten ErrorHandling zu versehen.
Es ist jetzt möglich, die Datenbank gänzlich ohne Sprachdokumente zu betreiben, ohne daß es zu einem Absturz oder einer Fehlermeldung kommt.
Statt der sprachabhängigen Beschriftungen werden jetzt die fehlenden Keys angezeigt. Alle Labels werden also in jedem Fall beschriftet, ohne daß es zu unschönen Lücken kommt.
Es wird in den berechneten Feldern nun folgender Code verwendet:
key := "lblTicketNumber";
_label:=@Trim(@Middle(FIELDLABELS; key + "=" ;";"));
@If(_label="";"(?)"+key;_label)
In gemeinsamen Aktionen verwenden wir ein anderes Konstrukt; da heißt es am Anfang des Formelcodes
key:="actTransferToMail";
_default:="Transfer Document";
Damit wird sichergestellt, daß alle gemeinsamen Aktionen auf jeden Fall eine Beschriftung mit einem DefaultText haben.
Das wäre zwar auch bei den berechneten Texten möglich, erforderte aber einen erhöhten Pflegeaufwand.
key := "lblTicketNumber";
_label:=@Trim(@Middle(FIELDLABELS; key + "=" ;";"));
@If(_label="";"(?)"+key;_label)
stellt im Gegensatz zu den gemeinsamen Aktionen die Maiorität dar; hier muss dann lediglich der KEY entsprechend ausgetauscht werden und nicht zusätzlich auch noch ein _default Wert gepflegt werden.
Die Durchsicht scheint auch noch einen anderen Effekt gehabt zu haben; der Red Screen, der bei vielen Nutzern aufgetaucht ist, hat sich heute nicht mehr blicken lassen.
Sollten nach einem Update irgendwelche SprachSchluessel fehlen, macht sich das dann folgendermaßen bemerkbar
-
ich weiss, der doclink zur Antwort fehlt noch ... liefere ich nach sobald die Sonne weg ist
ich glaube, ich muss da warten, bis Thomas aus dem Urlaub zurück ist; so ganz blicke ich nicht durch, was Thomas da programmiert hat :-[ Sieht logisch aus, funzt aber nicht
durch die neuen Fehlerbehandlungsroutinen in der 1.0.9 treten da einige Fehler zutage, die bisher nicht gesehen wurden
on error resume next ist echt eine böse Geschichte ;D
-
on error resume next ist echt eine böse Geschichte ;D
Aber aber, das predigen wir doch schon die ganze Zeit ... :-:
;D ;D
-
gucke mal in der Konfiguration nach, ob die die folgenden schlüssel hast. Darüber wird das Versenden der Mails gesteuert.
Yep - MailIfNewMailResponse steht eindeutig aus YES, bekomme aber definitiv keine Mail den der User auf meine Mail aus dem Call heraus antwortet - Agent läuft aber und stellt auch neue Calls ohne Fehler in Notes hinein. :-:
Ideen ? - Gruß baces
-
Thomas ist heute wieder aus dem Urlaub zurück; er arbeitet am Problem ...
-
... und in 1.0.9 werden Fehler in Agenten und LS Proceduren nicht nur in OpenLOG sondern auch in einer abgespeckten Version in !!HELP!! selbst geloggt.
-
und um das jetzt konfigurierbar hinzubekommen, muss das ERRHANDLE in einem Agenten folgendermassen aussehen:
EXITPOINT:
Exit Sub
ERRHANDLE:
Dim TheError As String
Dim TheProc As String
'TheProc = Getthreadinfo(LSI_THREAD_PROC)
TheError = Getthreadinfo(LSI_THREAD_PROC) & ": " &Trim$(Str$(Err)) & " on line " & Cstr(Erl) & ": " & Error$
If UseOpenLog Then
Call LogError
Elseif LogScriptErrors Then
Dim agent As NotesAgent
Set agent = s.CurrentAgent
TheProc = agent.Name
Dim L As New LogProfile ( s.CurrentDatabase, TheProc,LOG_NORMAL, s.CurrentDatabase.Server)
Call L.LogAction( TheError ,LOG_NORMAL)
End If
'In all cases
Print TheError
If ResumeMethodNext Then
Resume Next
Else
Resume EXITPOINT
End If
Im "INITIALIZE" Event der ScriptLib "lib.appl.functions" sieht das dann folgendermassen aus
Sub Initialize
' if configured, use OpenLog for error logging ( 25.05.2005, Ulrich Krause )
On Error Goto ERRHANDLE
If Ucase(GetConfigDocByKey ("OpenLogEnabled")) = "YES" Then
UseOpenLog = True
End If
If Ucase(GetConfigDocByKey ("LogScriptErrors")) = "YES" Then
LogScriptErrors = True
End If
If Ucase(GetConfigDocByKey ("ResumeMethod")) = "NEXT" Then
ResumeMethodNext = True
End If
EXITPOINT:
Exit Sub
ERRHANDLE:
UseOpenLog = False
Resume EXITPOINT
End Sub
Dazu gibt es dann eben die entsprechenden Konfigurationsdokumente.
Damit das Ganze auch funktioniert, gibt es eine neue ScriptLib "lib.appl.log". Die Lib enthält eine Klasse:
'lib.appl.log:
Option Public
Const TASKLENGTH = 15
Const LOG_NONE = 00
Const LOG_ERROR = 01
Const LOG_NORMAL = 02
Const LOG_EXTENDED = 03
Const LOG_DEBUG = 99
Const NORMALLOG = 1
Const ERRORLOG = 2
Dim logview As NotesView
Dim logdc As NotesDocumentCollection
Public Class LOGProfile
Public LogLevel As Integer
Public logdoc As NotesDocument
Public logerrordoc As NotesDocument
Public Subtask As String * TASKLENGTH ' used to display the task for all messages
Public AgentName As String * TASKLENGTH
Public Oldtask As String
Sub New(db As NotesDatabase,scriptname As String,niveau As Integer,username As String)
Dim special_item As NotesItem
Dim agent As NotesAgent
Dim serverdoc As NotesDocument
Dim serverprofile As NotesDocument
Dim onserver As String
Dim currentservername As String
Subtask = ""
Me.loglevel = niveau
Me.AgentName = scriptname ' truncated if to long
Set logview = db.GetView("Log")
If logview Is Nothing Then
Error 1000,"View for logging not existing"
End If
Call logview.Refresh 'added to avoid that a new log is created but not seen by this routine
Set logdc = logview.GetAllDocumentsByKey(Date$ & username & scriptname) ' changed 23/3/99 added
scriptname
Select Case logdc.Count
Case 0:
Set logdoc = CreateNewLog(db,username, scriptname,NORMALLOG) ' changed 23/3/99 added
scriptname
Call logview.Refresh
Case 1:
Set logdoc = logdc.GetFirstDocument
Case Else: 'close them all off and create a new log
For i = 1 To logdc.Count
Set logdoc = logdc.GetNthDocument(i)
logdoc.LogEnd = Format$(logdoc.LASTMODIFIED,"hh:mm:ss")
Call logdoc.Save(True,True)
Set logdoc = CreateNewLog(db,username, scriptname,NORMALLOG) ' changed 23/3/99
added scriptname
Call logview.Refresh
Next
End Select
Set logdc = logview.GetAllDocumentsByKey(Date$ & "ERROR" & username & scriptname) ' changed
23/3/99 added scriptname
Select Case logdc.Count
Case 0:
Set logerrordoc = CreateNewLog(db,username, scriptname,ERRORLOG) ' changed 23/3/99 added
scriptname
Call logview.Refresh
Case 1:
Set logerrordoc = logdc.GetFirstDocument
Case Else: 'close them all off and create a new log
For i = 1 To logdc.Count
Set logerrordoc = logdc.GetNthDocument(i)
logerrordoc.LogEnd = Format$(logerrordoc.LASTMODIFIED,"hh:mm:ss")
Call logerrordoc .Save(True,True)
Set logerrordoc = CreateNewLog(db,username, scriptname,ERRORLOG) ' changed
23/3/99 added scriptname
Call logview.Refresh
Next
End Select
End Sub
Sub LogAction(message As String,level As Integer)
Dim item As NotesItem
Dim db As NotesDatabase
Dim size As Long
If Me.LogLevel >= level Then
If Me.LogLevel = LOG_DEBUG Then
If level = LOG_DEBUG Then
levelstr$ = " ( " & Trim(Str$(level)) & ") " & Subtask
Else
levelstr$ = " ( " & Trim(Str$(level)) & ") " & Subtask
End If
Else
levelstr$ = ""
End If
Set item = logdoc.Getfirstitem("Log")
If Not item Is Nothing Then 'check if the document does not get to large
size = item.VALUELENGTH
Else
Set item = New NotesItem(logdoc,"Log","") ' if there is no logitem create a new
one and the size will then not be to large so we can presume 0
size = 0
End If
If size + Len(message) > 32000 Then 'create a new logdoc if the old one becomes to large
Set db = logdoc.ParentDatabase
logdoc.LogEnd = Now()
Call logdoc.Save(True,True)
Set logdoc = CreateNewLog(db,logdoc.LogUser(0),logdoc.Agentname(0),NORMALLOG) '
changed 23/3/99 added scriptname
Set item = New NotesItem(logdoc,"Log","")
End If
If message = "" Then
Call item.AppendToTextList("")
Else
Call item.AppendToTextList( Now() & " : " & message )
End If
logdoc.LastAction = Date$ & " " & Time$
Call logdoc.ComputeWithForm(True,True)
Call logdoc.Save(True,True)
End If
End Sub
Sub LogError(errorcode As Integer,message As String,level As Integer)
Dim item As NotesItem
Dim db As NotesDatabase
Dim size As Long
If Me.LogLevel >= level Then
If Me.LogLevel = LOG_DEBUG Then
If level = LOG_DEBUG Then
levelstr$ = " ( " & Trim(Str$(level)) & ") " & Subtask
Else
levelstr$ = " ( " & Trim(Str$(level)) & ") " & Subtask
End If
Else
levelstr$ = ""
End If
Set item = logdoc.Getfirstitem("Log")
If Not item Is Nothing Then 'check if the document does not get to large
size = item.VALUELENGTH
Else
Set item = New NotesItem(logdoc,"Log","") ' if there is no logitem create a new
one and the size will then not be to large so we can presume 0
size = 0
End If
If size + Len(message) > 32000 Then 'create a new logdoc if the old one becomes to large
Set db = logdoc.ParentDatabase
logdoc.LogEnd = Now()
Call logdoc.Save(True,True)
Set logdoc = CreateNewLog(db,logdoc.LogUser(0),logdoc.Agentname(0),NORMALLOG) '
changed 23/3/99 added scriptname
Set item = New NotesItem(logdoc,"Log","")
End If
If message = "" Then
Call item.AppendToTextList("")
Else
Call item.AppendToTextList(Now() & " " & Me.AgentName & " " & levelstr$ & " ***
Error *** :" & Str(errorcode) & " : " & message )
End If
logdoc.LastAction = Date$ & " " & Time$
Call logdoc.Save(True,True)
If level = LOG_ERROR Then ' error messages are logged seperate
Set item = logerrordoc.Getfirstitem("Log")
If Not item Is Nothing Then 'check if the document does not get to large
size = item.VALUELENGTH
Else
Set item = New NotesItem(logerrordoc,"Log","") ' if there is no logitem
create a new one and the size will then not be to large so we can presume 0
size = 0
End If
If size + Len(message) > 32000 Then 'create a new logdoc if the old one becomes
to large
Set db = logerrordoc.ParentDatabase
logerrordoc.LogEnd = Now()
Call logerrordoc.Save(True,True)
Set logerrordoc =
CreateNewLog(db,logdoc.LogUser(0),logdoc.Agentname(0),ERRORLOG)
Set item = New NotesItem(logerrordoc,"Log","")
End If
If message = "" Then
Call item.AppendToTextList("")
Else
Call item.AppendToTextList(Now() & " " & Me.AgentName & " " & levelstr$ &
" *** Error *** :" & Str(errorcode) & " : " & message )
End If
logdoc.LastAction = Date$ & " " & Time$
Call logerrordoc.Save(True,True)
End If
End If
End Sub
Sub DefineTask(task As String)
Subtask = task ' save TASKLENGTH characters
Oldtask = Subtask & Oldtask
Call Me.LogAction(">> " & Subtask,99)
End Sub
Sub ResetTask()
Dim taskname As String * TASKLENGTH
If Len(Oldtask) < TASKLENGTH Then
Oldtask = ""
Else
Call Me.LogAction("<< " & Left(Oldtask,TASKLENGTH ),99)
Oldtask = Right(Oldtask,Len(Oldtask) - TASKLENGTH )
End If
Subtask = Oldtask
End Sub
End Class
Function CreateNewLog(LogDb As NotesDatabase,username As String, scriptname As String,logtype As Integer) As
NotesDocument ' changed 23/3/99 added scriptname
Dim s As New NotesSession
Set logdoc = New NotesDocument(Logdb)
logdoc.Form = "Log"
logdoc.Type = logtype
logdoc.AgentName = scriptname
logdoc.LogUser = s.CurrentDatabase.Server
logdoc.LogDate = Date$ & " " & Time$
logdoc.LastAction = Date$ & " " & Time$
Set notesItem = New NotesItem( logdoc, "author", username, AUTHORS)
Set CreateNewLog = logdoc
End Function
-
Thomas ist heute wieder aus dem Urlaub zurück; er arbeitet am Problem ...
Ich hab dran gearbeitet und festgestellt das ich einen schweren Denkfehler im Dispatcher drinhatte. :'(
Im Initialize müssen ein paar Zeilen ausgetauscht werden:
Zum einen das hier:
' check if there is already an entry in the userdocumentlist
If Iselement(userdclist(strusername)) = True Then
userdclist(strusername) = userdclist(strusername) + "~" + founddoc.UniversalID
Else
userdclist(strusername) = founddoc.UniversalID
End If
Ersetzen durch das hier:
' check if there is already an entry in the userdocumentlist
If Iselement(userdclist(strusername)) = True Then
userdclist(strusername) = userdclist(strusername) + "~" + newdoc.universalid
Else
userdclist(strusername) = newdoc.UniversalID
End If
Und das hier:
Set currentnote = db.GetDocumentByUNID(Documentslist(i).UniversalID)
Ersetzen durch das hier:
Set currentnote = db.GetDocumentByUNID(Documentslist(i))
Jetzt schäm ich mich aber richtig. weil das hatte ich nämlich schon mal erledigt. >:(
und danach sollte die Benachrichtigung auch mit der Version 1.08 inklusive der Doclinks und einem "vernünftigen" Text im Mail funktionieren.
-
Leider gibt es noch ein Problem wenn "MailIfNewMailResponseCheckNames" auf YES gesetzt wird.
Dann schickt der Dispatcher immer an den DEFAULT Supporter.
Ich habe den Fehler aber gefunden; hier der BugFix ( oder wie es im SAP heißt: bauen sie bitte diesen Hinweis ein )
Das Adressbuch wird sauber durchforstet und die Liste mit den Namen aufgebaut; offenbar vergleicht der Dispatcher dann aber den Namen in canonical Form.
Ich habe daher v nach StringCast in die canonical form umgewandelt ( in lib.appl.functions)
Function CanonicalNameString (strName As String) As String
Set nn = New NotesName( strName )
strPersonName = nn.Canonical
CanonicalNameString = strPersonName
End Function
dann den Code im Dispatcher entsprechend angepasst
'get all the values of this item if it is a multivalue field
Set founditem = founddoc.GetFirstItem("supporter")
Forall v In founditem.Values
If Not(Trim(v)="") Then
strusername = CanonicalNameString (Cstr(v))
und schon funzt es ;D