Autor Thema: Prüfen mit HasItem und IsNumeric  (Gelesen 1176 mal)

Offline aoibhneach

  • Aktives Mitglied
  • ***
  • Beiträge: 141
  • Geschlecht: Männlich
Prüfen mit HasItem und IsNumeric
« am: 20.01.23 - 11:46:45 »
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
"Der verlorenste aller Tage ist der, an dem man nicht gelacht hat."

Sébastien-Roch Nicolas de Chamfort

Offline Tode

  • Moderatoren
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 6.877
  • Geschlecht: Männlich
  • Geht nicht, gibt's (fast) nicht... *g*
Antw:Prüfen mit HasItem und IsNumeric
« Antwort #1 am: 20.01.23 - 16:07:32 »
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

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
« Letzte Änderung: 20.01.23 - 16:10:26 von Tode »
Gruss
Torsten (Tode)

P.S.: Da mein Nickname immer mal wieder für Verwirrung sorgt: Tode hat NICHTS mit Tod zu tun. So klingt es einfach, wenn ein 2- Jähriger versucht "Torsten" zu sagen... das klingt dann so: "Tooode" (langes O, das r, s und n werden verschluckt, das t wird zum badischen d)

Offline aoibhneach

  • Aktives Mitglied
  • ***
  • Beiträge: 141
  • Geschlecht: Männlich
Antw:Prüfen mit HasItem und IsNumeric
« Antwort #2 am: 24.01.23 - 16:52:18 »
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
"Der verlorenste aller Tage ist der, an dem man nicht gelacht hat."

Sébastien-Roch Nicolas de Chamfort

Offline aoibhneach

  • Aktives Mitglied
  • ***
  • Beiträge: 141
  • Geschlecht: Männlich
Antw:Prüfen mit HasItem und IsNumeric
« Antwort #3 am: 03.02.23 - 10:07:58 »
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
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
"Der verlorenste aller Tage ist der, an dem man nicht gelacht hat."

Sébastien-Roch Nicolas de Chamfort

 

Impressum Atnotes.de  -  Powered by Syslords Solutions  -  Datenschutz