VB.Net Converting from string to double - vb.net

I have a bad bug in my program where if a user presses the check(calculate) button when there is no input in the textbox the program displays this error: "Conversion from string "" to type 'Double' is not valid." I would like to resolve this but I am not sure how to do the conversion. I was thinking possibly CType but I am hearing talk of parsing. How do I go about this? the textbox is called mskTxtInput and the button object is called btnCheck which does all the calculation and processing.
Update: This is my code except the parsing method so hope this helps a little!
Private Sub btnCheck_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCheck.Click
pic1.Visible = False 'hide picture
pic1.Image = My.Resources.A
pic2.Image = My.Resources.F
Dim value As Double
If Double.TryParse(mskTxtInput.Text, value) = Then
MsgBox("parsing success") ' parsing worked, so use the value in here
Else
MsgBox("parsing failed") ' parsing failed, so alert the user to that fact
End If
If radAdd.Checked = True Then
totalNum = num1 + num2
End If
If radSub.Checked = True Then
totalNum = num1 - num2
End If
If radMulti.Checked = True Then
totalNum = num1 * num2
End If
If mskTxtInput.Text = totalNum Then
lblAns.Text = ("Correct!")
lblAns2.Text = ("Answer is " & totalNum)
pic1.Visible = True
wins = wins + 1
nScore = wins
Else
lblAns.Text = ("Incorrect")
lblAns2.Text = ("Answer should be " & totalNum)
pic2.Visible = True
End If
attempts = attempts + 1
If attempts = 5 Then
MessageBox.Show("Game Finished! ", "End Of Game", _
MessageBoxButtons.OK, _
MessageBoxIcon.Exclamation)
lblAns.Text = ("You scored " & wins & " Out of 5")
btnSpin.Enabled = False
pic1.Visible = False
pic2.Visible = False
lblAns2.Text = ""
lblAns2.Text = "Play again?"
btnCheck.Enabled = False
btnNew.Enabled = True
attempts = 0
wins = 0
End If
mskTxtInput.Clear()
mskTxtInput.Focus()
End Sub

Try using Double.TryParse Method (String, Double) rather
Something like
Dim s As String
Dim result As Double
Dim returnValue As Boolean
returnValue = Double.TryParse(s, result)

Use the TryParse method to do the parsing to avoid getting an exception if the parsing fails:
Dim value As Double
If Double.TryParse(mskTxtInput.Text, value) Then
' parsing worked, so use the value in here
Else
' parsing failed, so alert the user to that fact
End If

dim iVar as integer
dim sStr as string
sstr=""
ivar = val(sstr)

Use the static method Double.TryParse(). If it returns true then parsing was successful, and you can proceed with the operation. If it returns false then parsing was not successful, and you should show an error message (using MessageBox if you desire) and abort the operation.

Related

Is there something wrong with my coding? I am still new

I try to run this program but an error always appears:
Conversion from the string "LBLBuku" to type' Double 'is not valid.
If LBLBuku.Text >= 5 Or Val(LBLBuku.Text) + Val(TextBox1.Text) > 5 Then
MsgBox("Peminjaman Melebihi")
Else
If lbljudul.Text = "" Or TextBox1.Text = "" Then
MsgBox("Silahkan isi Kode Buku")
Else
DataGridView1.Rows.Add(New String() {TextBox2.Text, lbljudul.Text, LBLPengarang.Text, LBLTahun.Text, TextBox2.Text})
TextBox1.Text = ""
TextBox2.Text = ""
lbljudul.Text = ""
TextBox2.Text = ""
LBLPengarang.Text = ""
LBLTahun.Text = ""
Call rumustotalbuku()
End If
End If
Notice on your code the line
LBLBuku.Text >= 5
The property Text is of type String, you would have to convert the text to an integer type first before you can use ">=".
First I declare a variable to hold the integer value in the Text Box. Integer.TryParse will return true if it can convert the string in the text box to an integer. It will also fill the variable intTB1 with the number.
I am assuming that LBLBuku is a label so the .Text property has been set from code. We can depend on this being a number so all we need to do is the conversion with CInt(). We can use the variable we got from the .TryParse in the Or CInt(LBLBuku.Text) + intTB1 > 5 instead of referring to the text box again.
We don't need to check if TextBox1 is empty because it wouldn't have passed the .TryParse if it was.
Last and probably least, you don't need the Call keyword in most situations.
You do realize that you have added TextBox2 twice to the new DataRow.
Private Sub OPCode()
Dim intTB1 As Integer
If Not Integer.TryParse(TextBox1.Text, intTB1) Then
MessageBox.Show("Please enter a number in TextBox1.")
Return
End If
If CInt(LBLBuku.Text) >= 5 Or CInt(LBLBuku.Text) + intTB1 > 5 Then
MsgBox("Peminjaman Melebihi Maksimal")
Else
If lbljudul.Text = "" Then
MsgBox("Silahkan isi Kode Buku")
Else
DataGridView1.Rows.Add(New String() {TextBox2.Text, lbljudul.Text, LBLPengarang.Text, LBLTahun.Text, TextBox2.Text})
TextBox1.Text = ""
TextBox2.Text = ""
bljudul.Text = ""
TextBox2.Text = ""
LBLPengarang.Text = ""
LBLTahun.Text = ""
rumustotalbuku()
End If
End If
End Sub

If third character Not IsNumeric

I'm working on a project that displays text on a monitor as a reference but running into some logic trouble. Someone clicks a button which prompts an InputBox into which they insert a bar code with a scanner.
I have 2 types of part numbers, one is like this "11n11110mch" the other is something like this "12311110mch". I need code that tests whether the 3rd character is a number. The end goal is to display the number as "11.(some letter)111.10 MCH" and "123.111.10 MCH" in a TextBox. If I try "11n22210mch", I get an error that says
Conversion from string "n" to type 'Double' is not valid.
at
thirdChara = Mid$(VisPartID, 3, 1)
I am not sure how to correct this or accomplish what I am trying to do.
The code I have:
Public Sub btnScan_Click(sender As Object, e As EventArgs) Handles btnScan.Click
Dim ScanIDRaw As Object
'Clear Scan Value
ScanIDRaw = Nothing
'Display message, title, And default value.
ScanIDRaw = InputBox("Scan CDI", "InputBox")
Do Until ScanIDRaw IsNot ""
ScanIDRaw = InputBox("Part Number Needed, Scan CDI", "InputBox")
Loop
lblCDIPart.Text = ScanIDRaw
HUD.ReferenceCardDataPull()
End Sub
Public Async Sub ReferenceCardDataPull()
Dim PartID As String
Dim VisPartID As String
Dim thirdChara As String
'Other Code
'Something
'Something
VisPartID = Main.lblCDIPart.Text
thirdChara = Mid$(VisPartID, 3, 1)
If thirdChara = Not IsNumeric(thirdChara) Then
VisPartID = VisPartID.Insert(2, ".")
VisPartID = VisPartID.Insert(7, ".")
VisPartID = VisPartID.Insert(10, " ")
VisPartID = VisPartID.ToUpper
lblPart.Text = VisPartID
Else
VisPartID = VisPartID.Insert(3, ".")
VisPartID = VisPartID.Insert(8, ".")
VisPartID = VisPartID.Insert(11, " ")
VisPartID = VisPartID.ToUpper
lblPart.Text = VisPartID
End If
End Sub
If Not isNumeric(thirdChara) Then
But you really should be using VB.Net methods instead of the old VB6 style
dim position3 as integer
thirdChara = VisPartID.SubString(2,1) ' 2 because we're 0 based
if not integer.tryparse(thirdChara, position3) then
'do stuff if not a number
else
'it's a number
end if
The tryparse will return a boolean based upon the parse result. Upon successful parse, it will store the parsed value into the variable (in this case Position3)
I would also recommend turning on Option Strict as that would have informed you right away that you cannot implicitly convert a string to a boolean.
Meaning: The string thirdChara is being tested for equality against as Not (True|False) result from the IsNumeric method.

VB.Net issues calling a validation function

i have written code to save data to a database, this code works fine. However, when it comes to validating the code, i have been encountering some issues despite the validation code working in console mode. The issue is that when i call the functions (seen below in the code) CheckValidPassword() etc. they dont seem to return the correct value and when it comes to the If statement in the savebutton click event, the code kind of skips it and just saves the data to the database via a datagridview.
Here is the code.
Private Sub btnsave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnsave.Click
Dim ValidUserName, ValidPassword, ValidTeacherUsername As Boolean
Dim Username, Password, TeacherUsername As String
Username = txtStudentID.Text
Password = txtStudentPassword.Text
TeacherUsername = txtTeacherID.Text
ValidUsernameCheck(ValidUserName, Username)
ValidPasswordCheck(ValidPassword, Password)
ValidTeacherUsernameCheck(ValidTeacherUsername, TeacherUsername)
If ValidUsernameCheck(ValidUserName, Username) <> True Or ValidPasswordCheck(ValidPassword, Password) <> True Or ValidTeacherUsernameCheck(ValidTeacherUsername, TeacherUsername) <> True Then
MsgBox("Saving failed", MsgBoxStyle.OkOnly)
'Exit Sub
Else
Try
Dim dataAdapter As New OleDbDataAdapter
Dim DataTable As New DataTable
Dim DataSet As New DataSet
Connection.Open() ' the following decleration are used to save content to the table.
DataSet.Tables.Add(DataTable)
Dim SQLQuery As String = (<sql>SELECT * FROM Students</sql>)
dataAdapter = New OleDbDataAdapter(SQLQuery, Connection)
dataAdapter.Fill(DataTable)
Dim newRow As DataRow = DataTable.NewRow
With newRow ' the with statement allows you do repeatedly apply a property to a certain object
.Item("StudentID") = txtStudentID.Text ' these statements add the content of the text boxes to these respective fields in the database
.Item("TeacherID") = txtTeacherID.Text
.Item("StudentFirstName") = txtStudentFirstname.Text
.Item("StudentSurname") = txtStudentSurname.Text
.Item("StudentPassword") = txtStudentPassword.Text
.Item("StudentGroup") = cbxStudentGroup.Text
End With
DataTable.Rows.Add(newRow)
Dim Command As New OleDbCommandBuilder(dataAdapter)
dataAdapter.Update(DataTable) 'updates the table
Connection.Close()
ShowItems() ' displays the table
Catch ex As Exception
MessageBox.Show(ex.Message)
Connection.Close()
End Try
End If
End Sub
Here are the three functions used to validate the three critical bits of data.
Function ValidUsernameCheck(ByRef ValidUserName As Boolean, ByVal Username As String) As Boolean
Dim Valid1, Valid2 As Boolean
If Char.IsLetter(Mid(Username, 1, 3)) Then ' takes the first 3 characters of a user name to see if they are
' letters
Valid1 = True
Else
Valid1 = False
End If
If Char.IsNumber(Mid(Username, 4, 8)) Then 'does the same with numbers, starting at char(4) and taking 8.
Valid2 = True
Else
Valid2 = False
End If
If Valid1 = True And Valid2 = True Then
ValidUsernameCheck = True
Else
ValidUsernameCheck = False
End If
Return ValidUsernameCheck
End Function
Function ValidTeacherUsernameCheck(ByRef ValidTeacherUsername As Boolean, ByVal TeacherUsername As String) As Boolean
Dim Valid1, Valid2 As Boolean
If Char.IsLetter(Mid(TeacherUsername, 1, 3)) Then ' takes the first 3 characters of a user name to see if they are
' letters
Valid1 = True
Else
Valid1 = False
End If
If Char.IsNumber(Mid(TeacherUsername, 4, 8)) Then 'does the same with numbers, starting at char(4) and taking 8.
Valid2 = True
Else
Valid2 = False
End If
If Valid1 = True And Valid2 = True Then
ValidTeacherUsernameCheck = True
Else
ValidTeacherUsernameCheck = False
End If
Return ValidTeacherUsernameCheck
End Function
Function ValidPasswordCheck(ByRef ValidPassword As Boolean, ByVal Password As String) As Boolean
If System.Text.RegularExpressions.Regex.Match(Password, "\d").Success Then
ValidPasswordCheck = True
Else
ValidPasswordCheck = False
End If
Return ValidPasswordCheck
End Function
Any help will be appreciated.
Your code appears to be a bit too complicated. You can return from a function at any point with a Return statement - as soon as you detect an input value is incorrect, you can Return False because any further validation checks are usually not needed.
It looks like you have at least some familiarity with regexes, so you could use one to check the usernames as well as the password.
The code appears to be setting credentials for a student, so there is no harm in letting the user know which entry had a problem, if any. Also, it is a good idea to tell the user what format the entry should be in.
You are checking the IDs, not the names - you should name the functions appropriately.
So, your code could look like this:
Private Function IsIdFormatCorrect(ID As String) As Boolean
If String.IsNullOrEmpty(ID) OrElse ID.Length <> 11 Then
Return False
End If
' require name to be exactly (three letters followed by eight digits)
Return Regex.IsMatch(ID, "^[A-Za-z]{3}[0-9]{8}$")
End Function
Private Function IsPasswordFormatCorrect(password As String) As Boolean
If String.IsNullOrEmpty(password) Then
Return False
End If
' require password to be only digits and at least four of them
Return Regex.IsMatch(password, "^[0-9]{4,}$")
End Function
Private Sub bnSave_Click(sender As Object, e As EventArgs) Handles bnSave.Click
Dim errorText As String = ""
If Not IsIdFormatCorrect(txtStudentID.Text) Then
errorText = "Student ID not in correct format (""ABC12345678"")." & vbCrLf
End If
If Not IsIdFormatCorrect(txtTeacherID.Text) Then
errorText &= "Teacher ID not in correct format (""ABC12345678"")." & vbCrLf
End If
If Not IsPasswordFormatCorrect(txtStudentPassword.Text) Then
errorText &= "Student password not in correct format (at least four digits)."
End If
If errorText.Length > 0 Then
MessageBox.Show(errorText, "Data entry problem", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Else
' save to database
End If
End Sub

How to show all validation errors as a list in my messagebox

I am having a problem with my code. I am trying to show all the validation errors in a message box. Can anyone tell me why only one of my errors is showing up in the box? I tried a couple more solutions and looked around but I need a little help please.
Public Class Form1
Private Sub btnCalculate_Click(sender As Object, e As EventArgs) Handles btnCalculate.Click
If Data_Validated_ok() = False Then Exit Sub
End Sub
Private Function Data_Validated_ok() As Boolean
Dim intErrCount As Integer
Dim strErrMessage As String = String.Empty
Dim ctrlError As New Collection
' make sure Premium channel is selected
If Me.lstPremium.SelectedIndex < 0 Then
intErrCount = intErrCount + 1
strErrMessage = intErrCount & ". Premium Channels is a required field." _
& vbCrLf
ctrlError.Add(lstPremium.SelectedIndex)
End If
' make sure a customer type is selected in the Radioboxes
If radBusiness.Checked = False And
radResidential.Checked = False Then
intErrCount = intErrCount + 1
strErrMessage = intErrCount & ".Customer Type is a required field." _
& vbCrLf
ctrlError.Add(radBusiness.Checked, radResidential.Checked)
End If
' make sure a business customer checks at least one option in the listbox
If radBusiness.Checked = True And Me.lstConnections.SelectedIndex < 0 Then
intErrCount = intErrCount + 1
strErrMessage = intErrCount & ". Business Customers must select 1 or more Connection." _
& vbCrLf
ctrlError.Add(lstConnections.SelectedIndex)
End If
' show all errors in a messagebox
If intErrCount > 0 Then
MessageBox.Show(strErrMessage, "Validation Rule(s)", MessageBoxButtons.OK, MessageBoxIcon.Information)
Dim ctrl As Control
ctrl = ctrlError.Item(1)
ctrl.Focus()
Return False
Else
Return True
End If
End Function
How about storing each error in a List(Of String)? Your variable ctrlError is not storing controls, but integers and booleans - you should have casting errors there.
Private Function Data_Validated_ok() As Boolean
Dim errorMsgs As New List(Of String)
' make sure Premium channel is selected
If Me.lstPremium.SelectedIndex < 0 Then
errorMsgs.Add("Premium Channels is a required field.")
End If
' make sure a customer type is selected in the Radioboxes
If radBusiness.Checked = False AndAlso
radResidential.Checked = False Then
errorMsgs.Add("Customer Type is a required field.")
End If
' make sure a business customer checks at least one option in the listbox
If radBusiness.Checked = True And Me.lstConnections.SelectedIndex < 0 Then
errorMsgs.Add("Business Customers must select 1 or more Connection.")
End If
' show all errors in a messagebox
If errorMsgs.Count > 0 Then
MessageBox.Show(String.Join(Environment.Newline, errorMsgs.ToArray), "Validation Rule(s)", MessageBoxButtons.OK, MessageBoxIcon.Information)
Return False
Else
Return True
End If
End Function

The error is Conversion from string "" to type 'Double' is not valid

Private Sub btntambah_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btntambah.Click
Dim n As Integer
For n = 0 To lv1.Items.Count - 1
If lv1.Items(n).Text = txtkdbrng.Text Then
MsgBox("Data Buku Sudah Ada Dalam List")
Exit Sub
End If
Next
lv1.Items.Add(txtkdbrng.Text)
lv1.Items(n).SubItems.Add(txtnmbrng.Text)
lv1.Items(n).SubItems.Add(txtharga.Text)
lv1.Items(n).SubItems.Add(txtjmlhhrg.Text)
lv1.Items(n).SubItems.Add(txttotal.Text)
lv1.Items(n).SubItems.Add(txtjmlpsn.Text)
lv1.Items(n).SubItems.Add(txtspesifikasi.Text)
txttotal.Text = Format(CDbl(Total()), "###, ###, ###")
ClearBarang()
txtkdbrng.Focus()
End Sub
Function Total() As Double
Dim ttl As Double = 0
If Not Double.TryParse(txttotal.Text, Total) Then
Total = 0
End If
End Function
Private Sub btncetak_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btncetak.Click
If txtnosph.Text = "" Or lv1.Items.Count = 0 Then
MsgBox("Data Belum Lengkap", MsgBoxStyle.Information, "INFORMASI")
Else
Dim nilaikembali1, nilaikembali2 As Integer
objsph.PNoSph = txtnosph.Text
objsph.PTglSph = Format(dtpsph.Value, "yyy-MM-dd")
objsph.PKdCs = txtkdcstmr.Text
nilaikembali1 = objsph.Simpan()
'menyimpan ke tabel Ada menggunakan perulangan
For x As Integer = 0 To lv1.Items.Count - 1
objada.PNoSph = txtnosph.Text
objada.PKdBrg = lv1.Items(x).SubItems(1).Text
objada.PKdBrg = CDbl(lv1.Items(x).SubItems(2).Text)
objada.PKdBrg = CDbl(lv1.Items(x).SubItems(3).Text)
nilaikembali2 = objada.Simpan()
Dim objbarang As New ClsBarang
objbarang.PKdBrg = lv1.Items(x).SubItems(0).Text
Next
If nilaikembali1 = 1 And nilaikembali2 = 1 Then
MsgBox("Data Berhasil Disimpan", MsgBoxStyle.Information, "INFORMASI")
End If
ClearForm()
ClearBarang()
ClearCustomer()
txtnosph.Text = objsph.AutoNumber
End If
End Sub
The problem is with this code:
Function Total() As Double
Dim ttl As Double = 0
If Not Double.TryParse(txttotal.Text, Total) Then
Total = 0
End If
End Function
First off you are using the less well known VB6 style implicit return variable that matches the name of the function, instead use the declared Double in your code named ttl and return the value, like this:
Function Total() As Double
Dim ttl As Double = 0
If Double.TryParse(txttotal.Text, ttl) Then
Return ttl
Else
' Attempted conversion of text to Double type failed
' Do something here, raise error, alert user, etc.
' Returning zero may or may not be acceptable, if it is return zero
Return 0
End If
End Function
Using the Return syntax produces much clearer code, in that it does not assume the reader of your code knows the implicit variable that matches the name of the function concept. Always use Return in a Function.
Note: If a total value of zero is not indicative of a problem, then you will need to alter your function to return Nullable(Of Double) instead of just Double and then you can alter the Else portion of the TryParse() result to this:
Function Total() As Nullable(Of Double)
Dim ttl As Double = 0
If Double.TryParse(txttotal.Text, ttl) Then
Return ttl
Else
' Attempted conversion of text to Double type failed
' So return null
Return Nothing
End If
End Function
Now the caller of your Total function will need to account for Nothing being returned and react accordingly.
This means the variable being explicitly or implicitly casted/converted to double is actually an empty string and cannot be proceed.