Domino 9 und frühere Versionen > ND9: Entwicklung

Prüfen mit HasItem und IsNumeric

(1/1)

aoibhneach:
Hallo Forum,

Wenn ich sicher sein möchte, dass ein Agent nicht in einen Fehler läuft, gibt es eine Alternative zum Anwenden der Methode
doc.Hasitem("myItem") und - wenn ein Wert ausgelesen werden konnte -  der funktion IsNumeric(wert)?

Ich möchte beim Lesen verschiedenster Dokumente mit vielen verschiedenen Werten sicher gehen, dass der Agent nicht in einen Fehler läuft. Auf die Fehler reagiert der Code zwar, ohne Abbruch. Ich würde aber solche "Auslese"-Fehler, weil ein Feld nicht das liefert, was eine Formatierungsfunktion erwartet, gerne ausschließen. Dafür fallen mir nur die genannte Methode und Funktion ein. Für sehr viele Felder bläht es den Code ziemlich auf.

Gibt es einen direkteren Weg mit gleichem Ziel?

Vielen Dank und Grüße,

Nils

Tode:
Dafür gibt es Funktionen. Ich habe z.B. in meiner "allgemeinen Basislibrary" eine Funktion GetItemValueNumber, die so aussieht:

--- Code: --- '===================================================================================================================================
' Function: GetItemValueNumberAdvanced
' Purpose: Returns the value of an item as number. mimics the fact, that in Formula the empty string equals 0
'-----------------------------------------------------------------------------------------------------------------------------------
' Arguments:
' docSource - document or documentEnhanced to get the value from
' itemName - Name of item to return
' varFallback - Value to give back, if not a number
' useTextToNumber - Is advanced TextToNumber conversion needed (e.g. text from import)
'-----------------------------------------------------------------------------------------------------------------------------------
' Returns: Variant
'-----------------------------------------------------------------------------------------------------------------------------------
' Created by: Torsten Link on 23.04.2013 Modified by: Torsten Link on 24.02.2016
'-----------------------------------------------------------------------------------------------------------------------------------
' Changes: TLi on 01.12.2015 - If varFallback is given, then return it for empty fields as well...
' TLi on 01.02.2016 - Add conversion with @TextToNumber to get numbers from Strings like 50,00 €
' TLi on 24.02.2016 - Accept NotesDocumentEnhanced as Parameter
' TLi on 29.02.2016 - Use new parameter useTextToNumber
' TLi on 18.03.2016 - Always return Double values
'===================================================================================================================================
Function GetItemValueNumberAdvanced( docSource As Variant, itemName As String, varFallback As Variant, useTextToNumber As Boolean ) As Variant
On Error GoTo ErrorRoutine
'===================================================================================================================================
Dim varValue As Variant
Dim varConvertedValue As Variant
Dim arrTmp() As Double
Dim varReturn As Variant
Dim i As Integer

ReDim arrTmp(0)
arrTmp(0) = 0
varValue = docSource.Getitemvalue(itemName)
If IsNumeric(varValue(0)) Then
varReturn = varValue
Else
If useTextToNumber Then
varConvertedValue = GetNumericalValue( varValue )
Else
varConvertedValue = g_varEmpty
End If
If IsEmpty( varConvertedValue ) Then
If IsNumericalValue(varFallback) Then
If IsScalar( varFallback ) Then
arrTmp(0) = varFallback
varReturn = arrTmp
Else
varReturn = varFallback
End If
Else
varReturn = arrTmp
End If
Else
varReturn = varConvertedValue
End If
End If
If TypeName( varReturn(0) ) <> "DOUBLE" Then
ReDim arrTmp(UBound( varReturn ))
For i = 0 To UBound( varReturn )
arrTmp(i) = CDbl( varReturn(i) )
Next
varReturn = arrTmp
End If
GetItemValueNumberAdvanced = varReturn
'===================================================================================================================================
EndOfRoutine:
Exit Function
ErrorRoutine:
If ErrorHandler (GetThreadInfo (LSI_THREAD_PROC), GetThreadInfo (LSI_THREAD_CALLPROC)) = ERRORHANDLER_TOP_OF_STACK Then
Resume EndOfRoutine
End If
End Function
--- Ende Code ---

Wann immer ich ein Zahlenfeld erwarte und nicht will, dass ein Fehler geworfen wird, dann ersetze ich:

zahl = doc.GetItemValue( "Zahlenfeld" )(0)

durch

zahl = GetItemValueNumberAdvanced( doc, "Zahlenfeld", 0, False )

Der Code ist jetzt natürlich komplizierter als für Dich notwendig und enthält z.B. auch kein Logging von "Fallbacks", aber er sollte Dir als Anhaltspunkt dienen.
Du solltest natürlich meinen ErrorHandler durch Deinen eigenen ersetzen, und brauchst auch kein "NotesDocumentEnhanced" (eigene Klasse), kannst also den doc- Parameter als "NotesDocument" deklarieren, aber sonst sollte es so funktionieren.

Ach, grade gesehen: Das verwendet eine weiter Funktion aus der Library:
--- Code: ---'===================================================================================================================================
' Function: GetNumericalValue
' Purpose: Given a value tries to convert it to a number using @TextToNumber
'-----------------------------------------------------------------------------------------------------------------------------------
' Arguments: varValue - value to try to convert to number
'
'
'-----------------------------------------------------------------------------------------------------------------------------------
' Returns: Variant
'-----------------------------------------------------------------------------------------------------------------------------------
' Created by: Torsten Link on 01.02.2016 Modified by:
'-----------------------------------------------------------------------------------------------------------------------------------
' Changes:
'===================================================================================================================================
Function GetNumericalValue( varValue As Variant ) As Variant
On Error GoTo ErrorRoutine
'===================================================================================================================================
Dim strEval As String
Dim varResult As Variant
If IsScalar( varValue ) Then
strEval = {"} & CStr( varValue ) & {"}
Else
ForAll varVal In varValue
If strEval = "" Then
strEval = {"} & CStr( varVal ) & {"}
Else
strEval = strEval & " : " & {"} & CStr( varVal ) & {"}
End If
End ForAll
End If
varResult = Evaluate( {_res := @TextToNumber( } & strEval & {);@If( @IsError( _res ); "ERROR"; _res )} )
If CStr( varResult(0) ) = "ERROR" Then
varResult = g_varEmpty
End If
'===================================================================================================================================
EndOfRoutine:
GetNumericalValue = varResult
Exit Function
ErrorRoutine:
varResult = g_varEmpty
Resume EndOfRoutine
End Function
--- Ende Code ---

aoibhneach:
Hallo Torsten,

Vielen Dank für Deine Hilfe und Mühe. Ich bin erst heute Abend wieder am Rechner. Ich scheu mir Deine Lösung gleich an.

Viele Grüße,

Nils

aoibhneach:
Hallo Torsten

Nochmals vielen Dank. Ich habe mir alles angesehen und lerne. Am sehr sauber aufgebauten Code des Beispiels können sich viele ein Beispiel nehmen. Die Suche nach dem oder den Aufrufen gewisser Subs verschlingt einiges an Zeit, wenn nicht wenigstens anfangs ein Kommentar dazu steht.
Glücklicherweise läuft mein Agent jetzt für tausende Dokumente und baut daraus Excel-Dateien.
Ich hatte noch das Problem, dass zu meinem Erstaunen vor vielen Jahren einige Felder in manchen Masken von Text auf RichText geändert wurden.
Aber mittels
--- Code: ---If myItem.type = 1 Then
--- Ende Code ---
konnte ich das schnell beheben.
Der Rest sind Schreibfehler. Hatte einmal statt "doc.Ort" --> "doc.0rt", mit einer "0" getippt. Lotus Script meckert nicht und lässt dann in der Zieldatei die Stelle leer. Ich hatte Glück und habe es rechtzeitig gesehen.  :)

Viele Grüße,

Nils

Navigation

[0] Themen-Index

Zur normalen Ansicht wechseln