User Tools

Site Tools


k16:k16.6:k16.6.2:start

16.6.2 Valid data

Data is processed in all computer programs. Data is to be seen as information bound to characters. These statements make it clear once again that we are still dealing with electronic data processing (EDP) at present! Today, this is done at a high level in terms of the algorithms, programming languages and computers used. No comparison to the beginnings in computer science, which the author experienced in the computer center at the TH Magdeburg and in the computer science lectures of Dr. Stuchlik from 1967-1971.

The data to be processed

  • are either read in via (external) data memory or are read in via (external) data memory.
  • provided in real-time by sensors via suitable interfaces or
  • are created as (temporary) data - for example as a result of calculations - at runtime of the program or
  • they are read, converted and checked as a character string in text input components such as TextBox or ValueBox via a (real or virtual) keyboard.

This chapter focuses on the component 'Textbox'. Note that a text box in the TextBox.Text property returns a string (data type String) when you read input from a TextBox. You must decide whether you want to remove the text from a text box or not.

  • as normal text (name, place, description,…)
  • as formatted text (money value, date, MAC address, order number, color values,…) or
  • as number for counting (Number with z ∈ N; z ≥ 0 oder z ≥ 1) or
  • as a number for calculating (measurement value, parameter, function value,…)

for further use.

Irrespective of your decision for the specific application, you as a program developer should ensure that only valid character strings are forwarded to the program as (valid) data from a TextBox in order to prevent runtime errors! A runtime error in the program flow occurs, for example, if a string is entered in a TextBox that cannot be converted into a natural number, which is expected there, or a file that does not exist in the specified directory is accessed in a procedure. A large number of such errors can be intercepted, displayed or processed in appropriate error handling routines by defensive programming. In all cases, protection of the programme has priority!

Before embarking on the rather arduous path of validating entries from a text box, you should check whether there are alternatives to the TextBox and its specializations in order to be able to make secure entries!

These alternatives - in the context of the tasks to be solved - include the following components:

  • ComboBox, if their ReadOnly property has been set to True
  • List box
  • SpinBox
  • Slider
  • Dial
  • ColorButton
  • All Chooser (color, date, directory, files, font)

The following components are not alternatives because you must always check the entries before you can continue to process valid data:

  • InputBox
  • MaskBox
  • ValueBox
  • ButtonBox
  • DateBox.

If none of the above-mentioned alternative components are considered for your Gambas project, you must design, implement and test your own concepts for validating entries from a TextBox (InputBox, MaskBox, ValueBox, HistoryBox and ButtonBox). A tried and tested approach consists of

  1. immediately after each character has been entered, to test whether or not the character entered is included in the set of permitted characters - the input alphabet and
  2. at the end of the input, to check whether the character string entered is a word from the (formal) language of the permitted entries.

Often the character scanner is omitted as a pre-check and only the return value from the text box or its specializations is examined. Note that the return value is from a TextBox, MaskBox or HistoryBox of type String and from type Date from a DateBox.

16.6.2.1 Tasks

The following tasks are to be processed to check entries from a TextBox or its specializations in order to provide valid data:

(A1) Save that in a program only valid date values in the (English) format tt.mm.jjjj can be processed further! (A2) Develop suitable procedures to check entries from the following components:

  • Date in a special format? TextBox. It has to be checked whether a date in the special (German) format: tt.<empty sign>Monthname<empty sign>jjjj stands?
  • MAC address → MaskBox
  • Date → DateBox
  • IP address? ValueBox (type IPAddress)

Solution to task A1:

Public dDatum As Date
...
Public Sub DateChooser1_Activate()
  dDatum = DateChooser1.Value  
  DateBox1.Value = dDatum
End ' DateChooser1_Activate()

Solution to task A2:

If you are using a MaskBox or DateBox or ValueBox (Date type), you must check the entries yourself before you can save an entered date in the variable dDate and process it further or display an error message:

ValideDaten

Figure 16.6.2.1.1: Secure entries from a TextBox or its specializations

Solution subtask A.2.1:

In the Date-TextBox the function IsDate () is used for checking the date in the German format dd. mm.yyyyy. However, this function includes the current system language in its test. Therefore, a date in the German format can only be recognized as such if the system language is set to German, otherwise the program will always return an input error in spite of correct date input.

The used solution idea consists of

first save the character string from the TextBox in the local variable sEnter (line 24), remove all blanks at the beginning and end of the string (line 25) and reduce all duplicate blanks in the character string to a single space if they exist (lines 27 to 29); and then split the character string with the split function into 3 parts (line 32), using the space character as a separator. All 3 parts are stored as elements in a string array aMatrix.

This idea can be adapted for many tasks with other separators. The source code for all four partial solutions is completely specified and commented on:

[1] Public dDatum As Date
[2] Public sMAC As String
[3] Public sMessage As String
[4] Public sIPAdresse As String
[5] 
[6] Public Sub Form_Open()
[7]   FMain.Center()
[8]   FMain.Resizable = False
[9] ' Mode constants are in the DateChooser class and not in DateBox class!  
[10]   DateBox1.Mode = DateChooser.DateOnly 
[11] ' DateBox1.Value = Now ' Then no data check would be necessary!
[12]   DateBox1.ReadOnly = True 
[13]   ValueBoxIP.Type = ValueBoxIP.IPAddress
[14]   MaskBoxMAC.Mask = "[a-fA-F0-9][a-fA-F0-9]:[a-fA-F0-9][a-fA-F0-9]:[a-fA-F0-9] \
       [a-fA-F0-9]:[a-fA-F0-9][a-fA-F0-9]:[a-fA-F0-9][a-fA-F0-9]:[a-fA-F0-9][a-fA-F0-9]"
[15] End ' Form_Open()
[16] 
[17] Public Sub txtDate_Activate()
[18]   Dim aMatrix As String[]
[19]   Dim aMonate As String[]
[20]   Dim sMonat, sEingabe, sDatum As String
[21]   
[22]   aMonate = ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", \
           "September", "Oktober", "November", "Dezember"]
[23]   
[24]   sEingabe = txtDate.Text
[25]   sEingabe = Trim(sEingabe)
[26]   
[27]   While InStr(sEingabe, "  ")
[28]     sEingabe = Replace$(sEingabe, "  ", " ")
[29]   Wend
[30]   txtDate.Text = sEingabe    
[31]  
[32]   aMatrix = Split(sEingabe, " ")  
[33]   
[34]   If aMatrix.Count <> 3 Then 
[35]      Message.Error("Input error")
[36]      Return
[37]   Endif ' aMatrix.Count <> 3 ?
[38]   
[39]   If aMonate.Exist(aMatrix[1]) Then 
[40]      sMonat = Str(aMonate.Find(aMatrix[1]) + 1)  
[41]   Else
[42]      Message.Error("Input error")
[43]      Return
[44]   Endif ' aMonate.Exist(aMatrix[1]) ?
[45]   
[46]   sDatum = aMatrix[0] & sMonat & "." & aMatrix[2]
[47]   
[48]   If IsDate(sDatum) Then 
[49]      dDatum = Val(sDatum)
[50]      DateBox1.Value = dDatum ' For control only
[51]   Else
[52]      Message.Error("Input error")
[53]      Return
[54]   Endif ' IsDate(sDatum)
[55] End ' txtDate_Activate()

Comment:

Lines 34-37 check whether exactly 3 elements were stored in array aMatrix. In the event of an error, an error message is output, and the system checks whether the month name was written correctly in lines 39-44; if an error occurs, a corresponding message is output. If the test is positive, the variable sMonth in line 46 is used to specify a date string in the format tt.mm.jjjj. Finally, the function IsDate(…) checks whether the character string sDate can be interpreted as a valid German date - otherwise there is a suitable message.

Solution subtask A. 2.2.2

“The MAC address (Media Access Control Address) is the hardware address of each individual network adapter that serves as the unique identifier of the device in a computer network.” can be found under the link: http://de.wikipedia.org/wiki/MAC-Adresse. A MAC address is a 48-bit data word or a 6-byte data word. The 6 bytes are hexadecimal and are separated by 5 colons. An adapted solution idea is implemented as in the subtask A. 2.1. By using the set MAC mask it is guaranteed that only allowed characters[0-9a-fA-F] are accepted by the MaskBox. All other characters are ignored. Therefore, lines 10 to 13 and a character scanner in lines 15 to 20 could also be omitted here. The mask with spaces and colons will not be displayed until you activate the box with a single click. The source code in line 22 only ensures that the entered letters are displayed in the MAC address as uppercase letters - pure display cosmetics.

[1] Public Sub MaskBoxMAC_Activate()
[2] ' Datentyp von MaskBoxMAC.Text ist String
[3]   Dim aMatrix As String[]
[4]   Dim sEingabe, sElement As String
[5]   
[6]   sEingabe = MaskBoxMAC.Text
[7]   sEingabe = Trim(sEingabe)  
[8]   aMatrix = Split(sEingabe, ":")  
[9]   
[10]   If aMatrix.Count <> 6 Then 
[11]      Message.Error("Input error_1")
[12]      Return
[13]   Endif ' aMatrix.Count <> 6 ? ' Can be omitted here because a mask is used
[14]   
[15]   For Each sElement In aMatrix
[16]       If Left(sElement) Not Like "[abcdefABCDEF0123456789]" Or   \ 
       Right(sElement) Not Like "[abcdefABCDEF0123456789]" Then
[17]  'If Left(sElement) Not Like "[a-fA-F0-9]" Or Right(sElement) Not Like "[a-fA-F0-9]" Then
[18]          Message.Error("Input error_2")
[19]          Return
[20]       Endif ' Character not in input alphabet?
[21]   Next ' sElement  
[22]   sMAC = Upper(sEingabe)
[23]   MaskBoxMAC.Text = sMAC  
[24] End ' MaskBoxDate_Activate()

Solution subtask A. 2.3

A DateBox is a specialized MaskBox. By specifying the property DateBox. Mode you can select either a date (Mode = 0) or a time (Mode = 2) or a timestamp with date and time (Mode = 1). The mode constants are currently only available in the DateChooser class and not in the DateBox class - what to expect. You must set the mode so:

DateBox1.Mode = 0
DateBox1.Mode = DateChooser.DateOnly ' Alternative

A click on the small button on the right opens a date selection dialog, from which you can select a valid date that is then displayed with the corresponding date mask. If you set the DateBox. readonly property to True, you can no longer change this displayed date.

If you do not initialize the DateBox with a (valid) date, you must check the entries in the DateBox in this way:

Public Sub DateBox1_Activate()
' TypeOf(DateBox1.Value) = 8 => Data type: Date  
 
  If Not IsDate(Str(DateBox1.Value)) Then
     sMessage = "The entry is not a correct date!" ' DateBox1.Value is NULL!
     Message.Error(sMessage)
     Return
  Else
     dDatum = DateBox1.Value
  Endif ' Not IsDate(Str(DateBox1.Value)) ?
 
End ' DateBox1_Activate()
 
Public Sub DateBox1_DblClick()
  DateBox1_Activate()
End ' DateBox1_DblClick()

With the following lines in the procedure Form_Open() a check is omitted. However, you can then no longer enter a date yourself and must use the date selection dialog box - but you will then receive valid date data:

DateBox1.Mode = DateChooser.DateOnly 
DateBox1.Value = Now 
DateBox1.ReadOnly = True 

Solution subtask A. 2.4

The entry of IP addresses into a Value-Box as a specialized MaskBox works without any problems with the specification of the type in the procedure Form_Open():

  ValueBoxIP.Type = ValueBoxIP.IPAddress

However, you have to check the IP address you have entered, because the default mask only allows digits at the allowed places in the 4 digit blocks as input characters - but these can only be used at any position in the range from 0 to 9. 192.189.100.1 as well as 192.189.245.202 are accepted as inputs! The validation of valid data is based on proven approaches:

Public Sub ValueBoxIP_DblClick()
' Datentyp von ValueBoxIP.Value ist String
  Dim aMatrix As String[]
  Dim iCount As Integer
 
  aMatrix = Split(ValueBoxIP.Value, ".")
  For iCount = 0 To aMatrix.Max
    If Val(aMatrix[iCount]) < 0 Or Val(aMatrix[iCount]) > 255 Then
       sMessage = "Die IP-Adresse ist im " & (icount + 1) & ". Block fehlerhaft (" & aMatrix[iCount] & ") !"
       Message.Error(sMessage)
       Return
    Endif
  Next ' iCount  
  sIPAdresse = ValueBoxIP.Value
End ' ValueBoxIP_DblClick()

After entering an IP address, the check is carried out by double-clicking on the ValueBox. Note that you can change the cursor position in the ValueBox with the arrow keys < or >!

Note:
Please note the explanations in chapter → 19.6.5 Checking the syntax of character strings, because the new MATCH operator (from Gambas 3.4.2) in the component gb.pcre (Perl Compatible Regular Expression) simplifies the checking of character strings considerably.

Download

The website uses a temporary session cookie. This technically necessary cookie is deleted when the browser is closed. You can find information on cookies in our privacy policy.
k16/k16.6/k16.6.2/start.txt · Last modified: 29.09.2023 by emma

Page Tools