I'm trying to make a random band name generator in vb.net but whenever i randomly generate it shows a number rather than a word from my combo boxes
Public Class Form1
Private Sub btnMake_Click(sender As Object, e As EventArgs) Handles btnMake.Click
Randomize()
ComboBox1.Text = Int(Rnd() * ComboBox1.Items.Count)
ComboBox2.Text = Int(Rnd() * ComboBox2.Items.Count)
txtResult.Text = ComboBox1.Text + " " + ComboBox2.Text
End Sub
Private Sub btnFavourite_Click(sender As Object, e As EventArgs) Handles btnFavourite.Click
ListBox1.Items.Add(txtResult.Text)
End Sub
End Class
it should print one of the names that I've put into the combo box at random but it gives me random numbers instead
Set the SelectedIndex property instead of Text
ComboBox1.SelectedIndex = Int(Rnd() * ComboBox1.Items.Count)
Put Option Strict On at the top of your code file. You will see the compile error
Option Strict On disallows implicit conversions from 'Single' to 'String'.
on this line
ComboBox1.Text = Int(Rnd() * ComboBox1.Items.Count)
because Int() returns the integer portion of a number in the same type it was passed. So pass it a single, and it returns a single.
From Microsoft.VisualBasic metadata:
' Summary:
' Return the integer portion of a number.
' ...
Public Function Int(Number As Single) As Single
But you don't want to set the ComboBox.Text equal to a number anyway. You may want to set the ComboBox.SelectedIndex. You can try
ComboBox1.SelectedIndex = Int(Rnd() * ComboBox1.Items.Count)
but with Option Strict On, you still have type mismatch because you're trying to set an integer to a single. You could wrap Int in a CInt conversion
ComboBox1.SelectedIndex = CInt(Int(Rnd() * ComboBox1.Items.Count))
but now it's getting out of hand...
Here's the issue: you're using outdated functions, Int and Rnd. These were brought over from VB6 days and if you use VB.NET functions, it's a whole lot easier. See the Random class. Using Random, you have access to Random.Next, which actually returns an integer. Great!
Dim r As New Random()
ComboBox1.SelectedIndex = r.Next(ComboBox1.Items.Count)
ComboBox2.SelectedIndex = r.Next(ComboBox2.Items.Count)
Here is the complete code (with an added event handler to update txtResult whenever the indices are changed i.e. when the user manually changes one)
Private Sub btnMake_Click(sender As Object, e As EventArgs) Handles btnMake.Click
Dim r As New Random()
ComboBox1.SelectedIndex = r.Next(ComboBox1.Items.Count)
ComboBox2.SelectedIndex = r.Next(ComboBox2.Items.Count)
End Sub
Private Sub ComboBox_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged, ComboBox2.SelectedIndexChanged
txtResult.Text = ComboBox1.Text & " " & ComboBox2.Text
End Sub
Private Sub btnFavourite_Click(sender As Object, e As EventArgs) Handles btnFavourite.Click
ListBox1.Items.Add(txtResult.Text)
End Sub
Related
I'm trying to fill two arrays with the content of two columns of a Datagridview. I wrote this:
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim t As Integer = (DataGridView1.Rows.Count - 1)
For i = 0 To t
avx(i) = DataGridView1.Rows(i).Cells("Av").Value
hi(i) = DataGridView1.Rows(i).Cells("h").Value
avsum = Val(avsum + avx(i))
Next
Label2.Text = Val(avsum)
End Sub
When I start debugging, I receive this error at the fourth line of the reported code.
System.NullReferenceException: 'Object reference not set to an instance of an object.'
Does someone know how to solve this issue? How could I initialise Datagridview1? It has been already initialised in Designer section so, if I try to initialise it again, I receive obviously a conflict.
Based on my test, I can not reproduce your problem.
However, I make a sample code that may be similar to your question.
Form_Load event
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim table As New DataTable
table = New DataTable()
table.Columns.Add("Av")
table.Columns.Add("h")
table.Rows.Add("test1", "1001")
table.Rows.Add("test2", "1002")
table.Rows.Add("test3", "1003")
DataGridView1.DataSource = table
DataGridView1.AllowUserToAddRows = False
End Sub
Note: The AllowUserToAddRows property will reduce an extra row.
Button_Click event:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim t As Integer = (DataGridView1.Rows.Count - 1)
Dim array1(t) As String
Dim array2(t) As String
For i = 0 To t
array1(i) = DataGridView1.Rows(i).Cells("Av").Value
array2(i) = DataGridView1.Rows(i).Cells("h").Value
Next
For index = 0 To t
RichTextBox1.AppendText(array1(index) + Environment.NewLine)
RichTextBox2.AppendText(array2(index) + Environment.NewLine)
Next
End Sub
Final result:
Can you describe about variable avx() and hi()
This error occur maybe datagridview row count greater than Array bound
Please consider adding a description to this question to attract more helpful responses.
Public Class Form1
Private Sub BtnCalculateRevenue_Click(sender As Object, e As EventArgs) Handles BtnCalculateRevenue.Click
Dim intvalue As Integer = CInt(TxtInputClassA.Text)
Dim intvalue2 As Integer = CInt(TxtInputClassB.Text)
Dim intvalue3 As Integer = CInt(TxtinputClassC.Text)
Dim total As Double
Try
LblStatus.Text = String.Empty
LblClassAResult.Text = (intvalue * 15).ToString("c")
LblClassBResult.Text = (intvalue2 * 12).ToString("c")
LblClassCResult.Text = (intvalue3 * 9).ToString("c")
total = CDbl((intvalue * 15) + (intvalue2 * 12) + (intvalue3 * 9))
LblTotal.Text = total.ToString("c")
Catch
LblStatus.Text = "Please Enter a Number"
End Try
End Sub
Private Sub BtnExit_Click(sender As Object, e As EventArgs) Handles BtnExit.Click
Me.Close()
End Sub
Private Sub BtnClear_Click(sender As Object, e As EventArgs) Handles BtnClear.Click
TxtInputClassA.Clear()
TxtInputClassB.Clear()
TxtinputClassC.Clear()
LblClassAResult.Text = String.Empty
LblClassBResult.Text = String.Empty
LblClassCResult.Text = String.Empty
LblTotal.Text = String.Empty
End Sub
End Class
VB Entering a Non_Numeric value crashes the program
Validation is built right into Windows Forms so you should make use of it. If you want to force the user to enter numbers in each of three TextBoxes then you can do this:
Private Sub TextBoxes_Validating(sender As Object, e As ComponentModel.CancelEventArgs) Handles TextBox3.Validating, TextBox2.Validating, TextBox1.Validating
Dim tb = DirectCast(sender, TextBox)
If Not Integer.TryParse(tb.Text, Nothing) Then
'Select all the invalid text and highlight it.
tb.SelectAll()
tb.HideSelection = False
MessageBox.Show("Please enter a whole number",
"Invalid Input",
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation)
'Remove highlight when TextBox is not focused.
tb.HideSelection = True
'Don't let the control lose focus while data is invalid.
e.Cancel = True
End If
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If ValidateChildren() Then
'All data is valid so proceed.
Dim n1 = CInt(TextBox1.Text)
Dim n2 = CInt(TextBox2.Text)
Dim n3 = CInt(TextBox3.Text)
'...
End If
End Sub
The ValidateChildren method will raise the Validating event for every control on the form and return False if any fail validation, i.e. e.Cancel is set to True in any event handlers, so that ensures that even controls that never received focus will be validated before the data is used.
Its bombing out on your cast "CInt(*value*)" so you can fix the code a couple ways. You can move your try above the casts like...
Try
Dim intvalue As Integer = CInt(TxtInputClassA.Text)
Dim intvalue2 As Integer = CInt(TxtInputClassB.Text)
Dim intvalue3 As Integer = CInt(TxtinputClassC.Text)
Dim total As Double
LblStatus.Text = String.Empty
You can do a data validation on your inputs and exit if they aren't all numeric (put this above your Dim intvalue code)
For Each value As String In {TxtInputClassA.Text, TxtInputClassA.Text, TxtInputClassA.Text}
If Not IsNumeric(TxtInputClassA.Text) Then
LblStatus.Text = "Please Enter a Number"
Exit Sub
End If
Next
Instead of casting as an int, use the tryparse method on Int32...
Dim intvalue As Integer
If Not Int32.TryParse(TxtInputClassA.Text, intvalue) Then
Exit Sub
End If
Or you could intercept the keypresses on each text box so that only numbers can be entered
Private Sub TxtInputClassA_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TxtInputClassA.KeyPress
If Not Char.IsDigit(e.KeyChar) Then
e.Handled = True
End If
End Sub
You can make that routine universal and append the event handler for all three text boxes like...
Private Sub EnforceOnlyNumericKeyPresses(sender As Object, e As KeyPressEventArgs) Handles TxtInputClassA.KeyPress, TxtInputClassB.KeyPress, TxtInputClassC.KeyPress
If Not Char.IsDigit(e.KeyChar) Then
e.Handled = True
End If
End Sub
Choose your favorite or do all of them, lots of choices.
Replace your textboxes with NumericUpDown controls and retrieve their .Value for your calculation. NUDs don't allow non numeric input and can have a fixed number of decimal places which may also be useful in a financial context
sorry I'm a newbie and I'm trying to write a program to get ten integers from user with a an Inputbox or Textbox and displays the biggest and lowest one in a label with visual basic. I'll be appreciated if you help me out with this.
Thank you. this is my solution. I don't know how to compare these ten numbers with each other.
Private Sub btnShow_Click(sender As Object, e As EventArgs) Handles btnShow.Click
Dim i, Container, Max, Numbers
Max = 0
i = 1
While (i <= 10)
Numbers = InputBox("please enter a number", "Enter a number")
Max = Numbers
Container = Container & " " & Numbers
i = i + 1
End While
lblresult.Text = Container
End Sub
conceptually speaking you should use a List(Of Integer) or List(Of Double), perform the loop 10 times adding the value into the list.
Suppose this is our list
Dim container As New List(Of Integer)
To get input
Dim userInput = ""
Dim input As Integer
userInput = InputBox("please enter a number", "Enter a number")
If Integer.TryParse(userInput, input) Then
container.Add(input)
End If
After the loop
Console.WriteLine($"Min: {container.Min()} Max: {container.Max()}")
Does this make sense to you ?
Edit, based on asking for Windows Forms example.
You could do the following instead of a InputBox, requires a label, a button and a TextBox.
Public Class MainForm
Private container As New List(Of Integer)
Private Sub CurrentInputTextBox_KeyPress(sender As Object, e As KeyPressEventArgs) _
Handles CurrentInputTextBox.KeyPress
If Asc(e.KeyChar) <> 8 Then
If Asc(e.KeyChar) < 48 Or Asc(e.KeyChar) > 57 Then
e.Handled = True
End If
End If
End Sub
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
CurrentLabel.Text = "Enter number 1"
End Sub
Private Sub ContinueButton_Click(sender As Object, e As EventArgs) _
Handles ContinueButton.Click
If Not String.IsNullOrWhiteSpace(CurrentInputTextBox.Text) Then
container.Add(CInt(CurrentInputTextBox.Text))
CurrentLabel.Text = $"Enter number {container.Count + 1}"
If container.Count = 10 Then
ContinueButton.Enabled = False
CurrentLabel.Text =
$"Count: {container.Count} " &
$"Max: {container.Max()} " &
$"Min: {container.Min()}"
Else
ActiveControl = CurrentInputTextBox
CurrentInputTextBox.Text = ""
End If
End If
End Sub
End Class
I really didn't want to do your homework for you but I was afraid you might be hopelesly confused.
First let's go over your code. See comments
Private Sub btnShow_Click(sender As Object, e As EventArgs) Handles btnShow.Click
Dim i, Container, Max, Numbers 'Don't declare variables without an As clause
Max = 0 'Max is an object
i = 1 'i is and object
While i <= 10 'the parenthesis are unnecessary. You can't use <= 2 with an object
Numbers = InputBox("please enter a number", "Enter a number")
Max = Numbers
Container = Container & " " & Numbers 'Container is an object; you can't use & with an object
i = i + 1 'Again with the object i can't use +
End While
lblresult.Text = Container
End Sub
Now my approach.
I created a List(Of T) at the Form level so it can be seen from different procedures. The T stands for type. I could be a built in type or type you create by creating a Class.
The first click event fills the list with the inputted numbers. I used .TryParse to test if the input is a correct value. The first parameter is a string; the input from the user. The second parameter is a variable to hold the converted string. .TryParse is very clever. It returns True or False base on whether the input string can be converted to the correct type and it fills the second parameter with the converted value.
The second click event loops through the list building a string to display in Label1. Then we use methods available to List(Of T) to get the numbers you desire.
Private NumbersList As New List(Of Integer)
Private Sub FillNumberList_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim i As Integer
While i < 10
Dim input = InputBox("Please enter a whole number")
Dim inputInt As Integer
If Integer.TryParse(input, inputInt) Then
NumbersList.Add(inputInt)
i += 1 'We only increment i if the parse is succesful
End If
End While
MessageBox.Show("Finished Input")
End Sub
Private Sub DisplayResults_Click(sender As Object, e As EventArgs) Handles Button2.Click
Label1.Text = "You input these numbers "
For Each num In NumbersList
Label1.Text &= $"{num}, "
Next
Label2.Text = $"The largest number is {NumbersList.Max}"
Label3.Text = $"The smallest number is {NumbersList.Min}"
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim linenumber0 As Integer
linenumber0 = 0
Dim mass As Double
mass = (File.ReadAllLines("225.txt").ElementAt(linenumber0).ToString)
If (Math.Abs((cDbl(TextBox1.Text) - mass < 0.5) Then
TextBox1.BackColor = Color.Green
End If
Im getting an error conversing from string to double is not valid. It is probably a simple solution but i cant see it right now
Your error occurs because the data read from the file is a String, however you are attempting to assign it to a variable declared as Double.
You can use TryParse to convert the String to Double, avoid errors and provide appropriate feedback.
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim lineNumber0 As Integer
Dim mass As Double
Dim input As Double
If Double.TryParse(File.ReadAllLines("225.txt").ElementAt(linenumber0), mass) Then
If Double.TryParse(TextBox1.Text, input) AndAlso Math.Abs(input - mass) < 0.5 Then
TextBox1.BackColor = Color.Green
End If
Else
'Bad file input
End If
'...
End Sub
I think that when you set the value to mass is catching a String, so parse it with a simple CDbl, like this
mass = cDbl(File.ReadAllLines("225.txt").ElementAt(linenumber0).ToString)
I supose that with this fix it will works.
Just in case, surround it with a TRY CATCH in case what it reads is not valid
I was wondering if you could help me? My question is that, is there a way of changing the value in my.Settings in a form if you enter a number/decimal in a textbox and click a button and then update in the settings to be then changed in another from which is linked to my.Settings in a variable?!
Form 1:
Public Class frmConverter
Dim input As String
Dim result As Decimal
Dim EUR_Rate As Decimal = My.Settings.EUR_Rates
Dim USD_Rate As Decimal = 1.6
Dim JYP_Rate As Decimal = 179.65
Private Sub btnCalc_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCalc.Click
input = txtInput.Text
Try
If ComboBox1.Text = "£" Then
Pounds()
ElseIf ComboBox1.Text = "€" Then
Euros()
ElseIf ComboBox1.Text = "$" Then
Dollars()
ElseIf ComboBox1.Text = "¥" Then
Yen()
End If
Catch es As Exception
MsgBox("Error!")
End Try
End Sub
Private Sub btnSettings_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSettings.Click
Me.Hide()
frmExchange.Show()
End Sub
Private Sub btnReset_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnReset.Click
txtInput.Text = ""
lblResult.Text = ""
End Sub
Function Pounds()
If ComboBox1.Text = "£" And ComboBox2.Text = "€" Then
result = (input * EUR_Rate)
lblResult.Text = FormatNumber(result, 2) & " " & ComboBox2.Text
ElseIf ComboBox1.Text = "£" And ComboBox2.Text = "$" Then
result = (input * USD_Rate)
lblResult.Text = FormatNumber(result, 2) & " " & ComboBox2.Text
ElseIf ComboBox1.Text = "£" And ComboBox2.Text = "¥" Then
result = (input * JYP_Rate)
lblResult.Text = FormatNumber(result, 2) & " " & ComboBox2.Text
End If
Return 0
End Function
Form 2:
Public Class frmExchange
Private Sub frmExchange_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
My.Settings.EUR_Rates = (txtinput.Text)
My.Settings.Save()
My.Settings.Reload()
End Sub
Public Sub SetNewRate(ByVal rate As Decimal)
txtinput.Text = rate.ToString
End Sub
Private Sub btnchange_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnchange.Click
If ComboBox1.Text = "€" Then
My.Settings.USD_Rates = (txtinput.Text)
frmConverter.SetNewRate(txtinput.Text)
End If
End Sub
End class
It sounds like you are trying to use My.Settings as some sort of set of global reference variables. Thats not what they are for, not how they work and not what they are.
First, turn on Option Strict as it looks like it may be Off. This will store the decimal value of a textbox to a Settings variable which is defined as a Decimal:
My.Settings.USD_Rates = CDec(SomeTextBox.Text)
Thats all it will do. It wont save the value and it wont pass it around or share it with other forms and variables.
My.Settings.Save 'saves current settings to disk for next time
My.Settings.Reload 'Load settings from last time
This is all covered on MSDN. There is no linkage anywhere. If you have code in another form like this:
txtRate.Text = My.Settings.USD_Rates.ToString
txtRate will not automatically update when you post a new value to Settings. There are just values not Objects (see Value Types and Reference Types). To pass the new value to another form:
' in other form:
Public Sub SetNewRate(rate As Decimal)
' use the new value:
soemTextBox.Text = rate.ToString
End Sub
in form which gets the change:
Private Sub btnchangeRate(....
' save to settings which has nothing to do with passing the data
My.Settings.USD_Rates = CDec(RateTextBox.Text)
otherForm.SetNewRate(CDec(RateTextBox.Text))
End Sub
You may run into problems if you are using the default form instance, but that is a different problem.
You botched the instructions. The 2 procedures are supposed to go in 2 different forms - one to SEND the new value, one to RECEIVE the new value. With the edit and more complete picture, there is an easier way.
Private Sub btnSettings_Click(...) Handles btnSettings.Click
' rather than EMULATE a dialog, lets DO a dialog:
'Me.Hide()
'frmExchange.Show()
Using frm As New frmExchange ' the proper way to use a form
frm.ShowDialog
' Im guessing 'result' is the xchg rate var
result = CDec(frm.txtInput.Text)
End Using ' dispose of form, release resources
End Sub
In the other form
Private Sub btnchange_Click(....)
' do the normal stuff with Settings, if needed then:
Me.Hide
End Sub