Das Notes Forum
Domino 9 und frühere Versionen => ND7: Entwicklung => Thema gestartet von: Demian am 04.10.10 - 18:22:38
-
Moin,moin,
ich musste heute feststellen, dass ich bei der Überprüfung auf Zahleneingabe in Script mit IsNumeric etwas auf die ... gefallen bin, weil ich die Eingabe von Hexzahlen nicht berücksichtigt habe (worauf die User auch manchmal kommen ;D ).
Vorerst werde ich das Problem mit einer kleinen Schleife lösen:
Dim intChar As Integer
Dim strTest As String
strTest = Ucase("6699e33")
If Isnumeric(strTest) Then
For intChar = 65 To 90
Print "prüfe " & Chr(intChar)
If Instr(strTest,Chr(intChar)) > 0 Then
Msgbox Chr(intChar) & " enthalten"
Exit Sub
End If ' Instr(strTest,Chr(intChar)) > 0
Next intChar
End If 'Isnumeric(strTest)
Da ich aber nicht so der Anhänger von Schleifen bin (wenn es sich vermeiden lässt), würde ich gern wissen ob es es elegantere Methoden gibt und wäre für Anhaltspunkte sehr dankbar.
Gruß
Demian
-
Hallo Demian,
zwei Fragen meinerseits:
1) Warum verwendest Du überhaupt ein Textfeld und kein numerisches?
2) Was machst Du, wenn mit 1E2 nicht eine Hexadezimalzahl = dez482 gemeint war, sondern die "Engineering-Darstellung", also 1*102 = 100? Oder doch ein Tippfehler durch Wurstfinger?
Ich befürchte, Du programmierst hier um des Pudels Kern herum :)
Bernhard
-
Moin Bernhard,
also etwas mehr zum Hintergrund.
Ein Textfeld deswegen, weil abhängig von dem gewählten "Dokument-Typ" (Optionsschaltfläche) , auch die Eingabe von Buchstabenfolgen möglich sein muss. Ich hätte es von vornherein auch über 2 oder mehr Felder, lösen können, habe mich jedoch dagegen entschieden, weil es sich hier um ein "Schnittstellenfeld" zu unserer Zeiterfassung handelt und ich mich so im Export-Agenten nur um ein Feld kümmern muss.
Wenn der betroffene Dokumenttyp gewählt ist, können nur 2-stellige, 5-stellige oder 7-stellige Nummern eingegeben werden.
Betroffen ist der 7er Teil deswegen, weil in der Datenbank auch sogenannte Chip-Zuordnungen (extra Maske) zu den Kostenträgern eingegeben werden können. Es handelt sich hier um "Buttons" mit denen auf den Baustellen die Zeit erfasst und nach dem Auslesen entsprechend dem Kostenträger zugeordnet wird. Diese Buttons haben eine Hardwareseitige Kennung, die immer 7-stellig (mit 5 führenden Nullen) aufgebaut ist (siehe Screenshot).
Manch einer verwechselt leider diese Chip-Zuordnung und gibt diese in der Maske Kostenträger als 7-stellige Kostenträgernummer ein... ::)
PS: Der Vollständigkeit halber noch ein Screenshot der Kostenträger.
-
Ich befürchte, Du programmierst hier um des Pudels Kern herum :)
Da muss ich Bernhard zu 100% recht geben.
...habe mich jedoch dagegen entschieden, weil es sich hier um ein "Schnittstellenfeld" zu unserer Zeiterfassung handelt und ich mich so im Export-Agenten nur um ein Feld kümmern muss.
Es ist aber wesentlich einfacher und auch noch für die gesamte Anwendung performater und weniger fehlerträchtig im Export-Agent das, dem Dokumenttyp entsprechende Feld zu bearbeiten. Das ist nur eine IF oder SELECT CASE Anweisung.
So programmierst du dir einen Wolf und hast immer noch nicht alle Eventualitäten abgefangen. Und glaube mir, User können in Falscheingaben unheimlich kreativ sein.
Axel
-
Es ist aber wesentlich einfacher und auch noch für die gesamte Anwendung performater und weniger fehlerträchtig im Export-Agent das, dem Dokumenttyp entsprechende Feld zu bearbeiten. Das ist nur eine IF oder SELECT CASE Anweisung
Das habe ich so im Prinzip auch, halt nur abhängig von der Optionsschaltfläche. Außerdem wäre es vielleicht eher verwirrend, da in der Schnittstellendatei, der Kostenträger auch immer an derselben Stelle steht ob jetzt Zahlen oder Buchstaben, und so der Aufbau in beiden Anwendungen gleich ist.
Es würde aber auch nichts an der Problematik ändern, wenn ich ein zusätzliches Zahlenfeld verwende, weil hier Werte wie 6699E33 eben auch eingegeben werden können und nur umgewandelt (ohne Kommas zu 6699000000000003396394276933278888463) werden, was wiederum die User nur schwer irritieren würde.
So programmierst du dir einen Wolf und hast immer noch nicht alle Eventualitäten abgefangen. Und glaube mir, User können in Falscheingaben unheimlich kreativ sein.
Das müsste eigentlich die Letzte Eventualität gewesen sein. Auch beim Zahlenfeld muss ich meine restlichen Überprüfungen drin lassen.
Und bei der DB will ich Schnittstellentechnisch nichts bis in letzte Detail programmieren, weil ich hoffe, dass diese Problematik (das Programm Zeiterfassung) vielleicht ein Ende hat (zu Bernhard zwinker).
-
Hinzu kommt, dass die betroffene Maske eine Größe von knapp 150.000 Byte hat und bereits von Teamstudio Best Practice Filter bemängelt wird (Notes Form Must Not Be Greater than 76,000 Bytes), da möchte ich ungern noch 3 Felder mit Hide-When Formeln usw. dazu nehmen.
Hat das eigentlich irgendwelche fatalen Auswirkungen, wenn Masken doch größer sind? Bis jetzt funktioniert noch alles.
-
der Vollständigkeithalber noch die entsprechende Stelle aus dem Exportagenten:
Function DataSetKOSTT(docCO As NotesDocument,strClient As String) As String
'*********************************************************************************************************************************
'create data set for each line in file to return it as string
'*********************************************************************************************************************************
'Parameters: docCO = CostObject to transfer
' strClient = Client of time management to which costobject must transfered
'*********************************************************************************************************************************
On Error Goto ErrHandle
'*********************************************************************************************************************************
Const EventName = "DataSetKOSTT" 'for reports
'*********************************************************************************************************************************
Call ReportWrite(Eventname & " - erstelle Datensatz für Nummer " & docCO.ID(0) &" für Mandant " & strClient)
NewDataSetKOSTT.TransferType = docCO.InterfaceIndicator(0)
NewDataSetKOSTT.ID = Cstr(docCO.ID(0))
NewDataSetKOSTT.ShortProject = docCO.ShortProject(0)
'Status
If docCO.Status(0) = "0" Then
NewDataSetKOSTT.Status = "no"
Else
NewDataSetKOSTT.Status = "yes"
End If
NewDataSetKOSTT.Client = strClient
NewDataSetKOSTT.Trade = ""
NewDataSetKOSTT.CostCenter = ""
NewDataSetKOSTT.Project = ""
NewDataSetKOSTT.Allowance = ""
NewDataSetKOSTT.Vehicle = ""
'CostObjectType
If docCO.CostObjectType(0) = "1" Then
'CostObjectType = "Firmenfahrzeug"
If docCO.TimeRating(0) = "0" Then
'TimeRating = "Fahrer"
NewDataSetKOSTT.CostObjectType = "F"
NewDataSetKOSTT.StandardTime = SalaryType("F","N")
NewDataSetKOSTT.ExtraWork = SalaryType("F","M")
NewDataSetKOSTT.ExtraHours = SalaryType("F","UE")
Else
'TimeRating = "Beifahrer"
NewDataSetKOSTT.CostObjectType = "B"
NewDataSetKOSTT.StandardTime = SalaryType("B","N")
NewDataSetKOSTT.ExtraWork = SalaryType("B","M")
NewDataSetKOSTT.ExtraHours = SalaryType("B","UE")
End If
'Commision not needed if CostObjectType = "Firmenfahrzeug"
NewDataSetKOSTT.Commission = ""
NewDataSetKOSTT.MinDrivingTime = "no"
NewDataSetKOSTT.Description = docCO.Project(0)
Elseif docCO.CostObjectType(0) = "0" Then
'CostObjectType = Standard
If Len(NewDataSetKOSTT.ID) = 7 Then
'Commission only must be edited if Cost Objects has seven digits
NewDataSetKOSTT.Commission = Left(NewDataSetKOSTT.ID,5)
Else
'Commission only needed if Cost Objects seven digit
NewDataSetKOSTT.Commission = NewDataSetKOSTT.ID
End If
NewDataSetKOSTT.Description = Left$(docCO.City(0),20) 'not docCO.Project, because Perso needs the city for tax certificate
NewDataSetKOSTT.CostObjectType = "N"
NewDataSetKOSTT.StandardTime = ""
NewDataSetKOSTT.ExtraWork = ""
NewDataSetKOSTT.ExtraHours = ""
NewDataSetKOSTT.MinDrivingTime = "yes"
Elseif docCO.CostObjectType(0) = "2" Then
'CostObjectType = "Tätigkeit"
NewDataSetKOSTT.Description = docCO.Project(0)
NewDataSetKOSTT.CostObjectType = "T"
NewDataSetKOSTT.Commission = NewDataSetKOSTT.ID
NewDataSetKOSTT.MinDrivingTime = "no"
Elseif docCO.CostObjectType(0) = "3" Then
'CostObjectType = "Sonstiges"
NewDataSetKOSTT.Description = docCO.Project(0)
NewDataSetKOSTT.CostObjectType = "N"
NewDataSetKOSTT.MinDrivingTime = "yes"
End If
NewDataSetKOSTT.TimeFunction = "O"
NewDataSetKOSTT.Modus = ""
NewDataSetKOSTT.AllocatedTime = "000000"
DataSetKOSTT = Cstr(NewDataSetKOSTT.TransferType) & ";" & Cstr(NewDataSetKOSTT.ID) & ";" & Cstr(NewDataSetKOSTT.ShortProject) & ";" & _
Cstr(NewDataSetKOSTT.Status) & ";" & Cstr(NewDataSetKOSTT.Client) & ";" & Cstr(NewDataSetKOSTT.Description) & ";" & _
Cstr(NewDataSetKOSTT.Trade) & ";" & Cstr(NewDataSetKOSTT.CostCenter) & ";" & Cstr(NewDataSetKOSTT.Project) & ";" & _
Cstr(NewDataSetKOSTT.Commission) & ";" & Cstr(NewDataSetKOSTT.Allowance) & ";" & Cstr(NewDataSetKOSTT.Vehicle) & ";" & _
Cstr(NewDataSetKOSTT.CostObjectType) & ";" & Cstr(NewDataSetKOSTT.TimeFunction) & ";" & Cstr(NewDataSetKOSTT.Modus) & ";" & _
Cstr(NewDataSetKOSTT.StandardTime) & ";" & Cstr(NewDataSetKOSTT.ExtraWork) & ";" & Cstr(NewDataSetKOSTT.ExtraHours) & ";" & _
Cstr(NewDataSetKOSTT.AllocatedTime & ";" & NewDataSetKOSTT.MinDrivingTime)
Call ReportWrite(Eventname & " - Datensatz: " & DataSetKOSTT)
Leave:
Exit Function
ErrHandle:
Call ReportWriteError(EventName & " - Error" & Str(Err) & ": " & Error$ & " in Zeile " & Erl)
Resume Leave
End Function
Wenn ich jetzt mit 4 Feldern arbeite muss ich das für die Zeile NewDataSetKOSTT.ID = Cstr(docCO.ID(0)) ja entsprechend bei If docCO.CostObjectType(0) = "1" Then.... umsetzen, was den Code noch unübersichtlicher macht.
-
Ein sachdienlicher Hinweis: Man kann einfach mit @Matches(<Feld>;"+{0-9}") abfragen, ob ein Textfeld nur Zahlen beinhaltet.
Bsp:
@If(
@Matches(Feld;"+{0-9}");
@Success;
@Failure("Bitte nur Zahlen eingeben.")
)
Und ja, es gibt Fälle, wo man ein Textfeld braucht - bspw. für Postleitzahlen. Es soll ja welche mit führenden Nullen geben und in einem Zahlfeld werden die armen Dinger einfach von Notes gekillt.
Edit: In Script gibts dazu die Like Funktion.
Andreas
-
Edit: In Script gibts dazu die Like Funktion.
Genau das meinte ich mit "elegantere" Methoden. Like kannte ich bisher nicht, habe es aber gerade getestet stellt einen optimalen Schleifenersatz dar. Werde es später entsprechend ändern. Vielen, vielen Dank.
Gruß
Demian
-
so wird letzlich aus:
...
If Not Isnumeric(strCO_ID) Then
boolNotNumeric = true
Else
'be sure ID is not hexadecimal
For intChar = 65 To 90
If Instr(Ucase(strCO_ID),Chr(intChar)) > 0 Then
boolNotNumeric = true
End If ' Instr(strTest,Chr(intChar)) > 0
Next intChar
End If 'Not Isnumeric(strCO_ID)
...
jenes:
...
If Not (Isnumeric(strCO_ID)) Then
boolNotNumeric = True
Else
'be sure ID is not hexadecimal
If strCO_ID Like "*[a-z,A-Z]*" Then boolNotNumeric = True
End If 'Not (Isnumeric(strCO_ID))
...
Damit sollte es doch eigentlich nicht mehr dazu kommen, dass was anderes außer Zahlen eingegeben wird, oder?
-
Demian, warum prüfst Du denn nicht auf "*[0-9]*"?
Derzeit können doch Deine findigen User (die es überall gibt und die meinen es auch fast immer auch wirklich nicht böse!) alles ausser Buchstaben eingeben.
Noch zur Maskengrösse: Könnte das durch eine überdimensionale, platzfressende Grafik kommen? Oder konntest Du anderes ermitteln?
Bernhard
-
Naja die Sonderzeichen usw. sollten doch mit Isnumeric abgefangen werden, oder täusche ich mich da?
Den Gedanken mit [0-9] hatte ich auch, nur hätte das den gegenteiligen Effekt, dass eben auch Buchstaben eingeben werden können. Es muss dann nur mindestens 1 Zahl vorhanden sein, damit strCO_ID like "*[0-9]*" mir "true" zurückliefert.
Was die Größe betrifft, Grafiken verwende ich nicht, aber die Maske hat 3 Aktionen mit ein paar Zeilen Code (nein, mit gemeinsamen Aktionen steh ich auf Kriegsfuß), sowie einige verwendete Ereignisse. Denke es rührt daher. Viele Felder usw hat die Maske eigentlich nicht. Also in den Maskeneigenschaften zeigt er mir für $Actions allein 33.000 Byte. $ScriptObj_0-2 sind auch jeweils 15.000 Byte.
Habe mir da noch nicht so Gedanken gemacht. Die Maske Memo hat ja auch mehr als 200.000 Byte.
Aber welche Auswirkungen kann die Größe denn haben?