How to set maximum of two numericupdown control - vb.net

I was making a cinema booking software where after I choose the seats, it stores the number of seats I selected in an integer counter.
I have two NumericUpDown controls: nudAdult & nudKids
My problem is I have to make sure the maximum value of both NumericUpDown controls can't exceed the seatNum counter.
For eg: If the number of seats I chose is 3, both values of nudAdult & nudKids cannot exceed 3 when added together. So nudAdult can be 2 and nudKids can be 1 and I can't increase anymore than that.
I would appreciate if anyone could help me or give me some pointers to solve this problem.
Thank you for any help.
Edit: This might have been a wrong approach but it worked to an extend
Private Sub nudAdult_ValueChanged(sender As Object, e As EventArgs) Handles nudAdult.ValueChanged
totalCount = Convert.ToInt32(nudAdult.Value) + Convert.ToInt32(nudKids.Value)
Call CheckIfExceed(nudAdult)
End Sub
Private Sub nudKids_ValueChanged(sender As Object, e As EventArgs) Handles nudKids.ValueChanged
totalCount = Convert.ToInt32(nudAdult.Value) + Convert.ToInt32(nudKids.Value)
Call CheckIfExceed(nudKids)
End Sub
Private Sub CheckIfExceed(c As NumericUpDown)
Dim left As Integer
If totalCount <= seatCounter Then
left = seatCounter - totalCount
c.Maximum = totalCount + left
Else
c.Maximum = c.Value - 1
End If
End Sub

You don't have to check anything. As I said, think about a physical problem. Let's say that you have 10 balls and two bags and you can put the balls into the bags. The maximum number of balls you can put in either bag is obviously the number of balls in that bag plus the number of balls not yet in either bag. That means that, when you start and both bags are empty, then maximum for each bag is the total number of balls. BOOM! You now know that you need to set the Maximum of each NumericUpDown to the total number of seats at the start.
Now, when you place a ball in a bag, the maximum number of balls that can be placed in the other bag obviously decrements by one. BOOM! You now know that when the Value of one of your NumericUpDown controls changes, you need to change the Maximum of the other the same amount in the opposite direction.
Look at that! Problem solved with less than a minute considering an analogous physical problem.
Private total As Integer 'Set total here.
Private Sub Start()
NumericUpDown1.Maximum = total
NumericUpDown2.Maximum = total
End Sub
Private Sub NumericUpDown1_ValueChanged(sender As Object, e As EventArgs) Handles NumericUpDown1.ValueChanged
NumericUpDown2.Maximum = total - NumericUpDown1.Value
End Sub
Private Sub NumericUpDown2_ValueChanged(sender As Object, e As EventArgs) Handles NumericUpDown2.ValueChanged
NumericUpDown1.Maximum = total - NumericUpDown2.Value
End Sub

Related

Make a score counter in vb.net

I want to make a score counter but when I use the timer, it's way too slow to get to the high value and it's max interval is 1. Refer code:
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
y = y + 2
ShowScore()
If y = Game2048.ScoreLabel.Text Then
Label18.Hide()
Label19.Show()
Timer1.Stop()
Timer2.Start()
End If
End Sub
As you can see that if the value Game2048.ScoreLabel.Text is 60,000 and Timer1 Interval is 1 then it will take more than 10 minutes to get to 60,000. So I was wondering if there is a way to reduce the time it reaches to 60,000 when counting up score, it is the same like in several games that have the ability to counting up score in just 10 seconds and when the score is higher, the amount it pluses will bigger. Anyone can help me out? Thanks!
*the 60,000 value may change!
You're already ticking faster than the user interface can update, which is already way faster than the human eye can follow. You'll also end up devoting a lot of cpu cycles to meaningless udpates at this rate.
What you want to do is set the tick rate to something reasonably fast from the perspective a human watching the counter. A tick rate of 250ms (4 times per second) ought to be plenty fast, and anything faster than about 100ms (10 times per second) is just wasteful.
Now you can adjust the code to calculate where you want the update to be at that point. If you want to count to 60,000 in 10 seconds, at 4 updates per second, then you have 40 updates, so just set your y value to 1500 instead of 2. Or, even better, calculate the rate on the fly:
'Set tick rate to 250
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
y += CInt(Game2048.ScoreLabel.Text) / timer1.Interval / 6
ShowScore()
If y >= Game2048.ScoreLabel.Text Then
Label18.Hide()
Label19.Show()
Timer1.Stop()
Timer2.Start()
End If
End Sub

Visual Basic For Loop how to compare listbox to another listbox?

So im suppose to make a program on VB that records numbers into a list box and find the average, and then i am suppose to compare the previous list box numbers and transfer any number that are above average into the other list-box.
Here is my code so far. I am stuck on the part where I have to transfer the numbers that are above average to another list box.
My logic is [show the count of the numbers, then compare the count of numbers to the average, and any numbers that are greater than the average, ill added onto the new list box] but i dont know how to write the syntax.
Option Strict On
Public Class frmAverageOfScore
Private Sub btnRecord_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRecord.Click
Dim lblscore As Double
lblscore = CDbl(txtScore.Text)
lstListofScores.Items.Add(lblscore)
End Sub
Private Sub btnAverage_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAverage.Click
Dim listScores As Integer = lstListofScores.Items.Count
Dim sum As Double = 0
For average As Integer = 0 To (listScores - 1)
sum += CDbl(lstListofScores.Items(average))
Next
txtAverage.Text = (sum / listScores).ToString("N")
End Sub
End Class
Your existing two routines already provide the foundation for what you need to do. For example, you're already looping through the items in the first list in your averaging routine. Now, just compare each to your average, and populate the second list if they are greater, similar to how you populate the first list.
For i As Integer = 0 To (listScores - 1)
If (CDbl(lstListofScores.Items(i)) > CDbl(txtAverage.Text)) Then
lstListofScores2.Items.Add(lstListofScores.Items(i))
End If
Next
Something to note: There are far more efficient, and readable ways to do this, but I wanted to use code similar to what you've already written. You already know the functionality, you just have to apply it in a slightly different way. Some simple suggestions: store a variable for the average (probably as a Double) so you aren't recalculating it every iteration; use a For Each loop to iterate the Items in the ListBox instead of a For..Next loop, etcetera.

I am trying to populate drop boxes

Here is what I have so far to populate a couple drop down boxes in visual basic.
I may need global variables but I am not sure how to do that. I have been told to use Dim and the variable names of the drop boxes but I keep getting errors saying they are already friends within the form.
*This is a homework assignment, however I am not asking you to do the assignment but simply asking help with the problem I am having within the drop boxes. I don't expect you wonderful people to earn my grades for me! Thank you for any help!
Public Class Form1
'// Mortgage Calculator Assignment 1.
'// Can calculate payments on a given loan at a given rate for a given term.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
'// Inputs rate starting at 3.25% through 6.75% at steps of 0.25% into the drop down box.
Private Sub cbRate_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cbRate.SelectedIndexChanged
For i As Decimal = 3.25 To 6.75 Step 0.25
cbRate.Items.Add(i & "%")
Next
End Sub
'// Inputs term in years from 10 through 40 at steps of 5 year intervals into the drop down box.
Private Sub cbTerm_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cbTerm.SelectedIndexChanged
For i As Integer = 10 To 40 Step 5
cbTerm.Items.Add(i)
Next
End Sub
End Class
You do not need global variables.
Try just populating the combo boxes in the form load:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'// Inputs rate starting at 3.25% through 6.75% at steps of 0.25%
' into the drop down
For i As Decimal = 3.25 To 6.75 Step 0.25
cbRate.Items.Add(i & "%")
Next
'// Inputs term in years from 10 through 40 at steps of 5 year intervals
' into the drop down box.
For i As Integer = 10 To 40 Step 5
cbTerm.Items.Add(i)
Next
End Sub
Edit: the combo boxes were declared (probably) for you when you added them to the form in the designer.

AddYear does not work when day value is <10

I'm having problems with the following: I have 2 textboxes masked to ShortDate. When I insert a date into the 1st textbox I need the 2nd textbox to display a date 2 years later.
For example, if I put 10/08/2013 the 2nd box should show 10/08/2014.
Here is the code:
Private Sub txtAcquired_LostFocus(sender As Object, e As EventArgs) Handles txtAcquired.LostFocus
Dim Acquired As Date
Acquired = txtAcquired.Text
txtDisposal.Text = Acquired.AddYears(2)
End Sub
It works fine when the day value of the date is > 9 but when I put a date with day value between 1 and 9 it does not work, e.g. if I put 04/04/2011 the 2nd box shows 40/42/013_.
If someone can help on this problem that will be much appreciated.
There is a fault with the date returned. This fixes it.
Private Sub txtAcquired_LostFocus(sender As Object, e As EventArgs) Handles txtAcquired.LostFocus
Dim Acquired As Date
If Date.TryParse(txtAcquired.Text, Acquired) Then
txtDisposal.Text = Acquired.AddYears(2).ToString("MM/dd/yyyy")
End If
End Sub

Do until EOF loop with records in VB 2010

I have a program below that doesn't seem to be doing what I want it to do. In general, the pseudocode is: enter the number of miles (miles.text), click button, check: is the mileage entered equal to or less than the mileage radius (milestotextbox) in the database? If so, grab the truckload rate that corresponds to that radius (truckloadratetext) and display it in a textbox called "rate" (rate.text) and if not, continue looking until EOF. I've shown the code below. It lets me enter the mileage but won't check and display the result.
The data in the table looks like this:
ID MILESTO TRUCKLOADRATE
1 50 200
2 100 300
3 200 700
4 300 800
So if someone enters a mileage like 10, I want it to take the truckload rate of $200. If someone enters 250, the rate would then be 800. I'm not too hung up right now about what happens if a mileage is out of range. Just trying to figure out why the mechanics of something like this isn't working. It's my first time using records with a LOOP command so I'm trying to keep it straightforward with my program.
What could I be doing wrong? Thank you in advance and hope all has a great New Years!
Public Class Form1
Private Property EOF As Boolean
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'TODO: This line of code loads data into the '_test_2DataSet.test' table. You can move, or remove it, as needed.
Me.TestTableAdapter.Fill(Me._test_2DataSet.test)
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Do Until EOF()
If Val(MilestoTextBox.Text) <= Val(Miles.Text) Then
rate.Text = TruckloadTextBox.Text
End If
Loop
End Sub
End Class
I neither know where you set the EOF variable nor do i understand its purpose. Have a look at following example which shows how to loop all rows of a DataTable(ORDER BY MILESTO ASC) to find the closest value greater than the given value:
Dim mileAge = Int32.Parse(Miles.Text)
Dim rate = 0
For Each row In _test_2DataSet.test
If mileAge <= row.MILESTO Then
rate = row.TRUCKLOADRATE
Exit For
End If
Next
If rate <> 0 Then
TxtRate.Text = rate.ToString
End If
If you cannot order by MILESTO initially or you simply want to see another approach that is not a database query, try this LINQ-To-DataSet approach:
rate = (From r In _test_2DataSet.test Order By r.MILESTO
Where mileAge <= r.MILESTO
Select r.TRUCKLOADRATE).FirstOrDefault
If you want to query the database, follwoing SQL returns the nearest TRUCKLOADRATE that is greater/equal than the #MileAge-parameter:
SELECT TOP (1) TRUCKLOADRATE
FROM Test
WHERE (MILESTO >= #MileAge)
ORDER BY MILESTO - #MileAge
Add a query to your DataAdapapter that returns a single value and has a meaningful name like getTruckloadRateByMileAge. Then it's that simple:
Dim loadRate = DirectCast(daTest.getTruckloadRateByMileAge(mileAge), Decimal)
Sorry for the delay in answering the question here and I want to thank everyone who answered, especially Tim.
In summary, Where a user wants to search through a dataset and compare a user-inputted value against some kind of index (in my case, if a mileage entered is less than or equal to some boundary value) and get the corresponding record that satisfies that criteria, the solution that works (thank you Tim!) is:
Dim mileAge = Int32.Parse(Miles.Text)
Dim rate = 0
For Each row In _test_2DataSet.test
If mileAge <= row.MILESTO Then
rate = row.TRUCKLOADRATE
Exit For
End If
Next
If rate <> 0 Then
TxtRate.Text = rate.ToString
End If
In the example, mileage is converted to a value that can be used to compare against a column in the dataset called MILESTO, which is a mile radius that corresponds to a price for transporting goods called TRUCKLOADRATE. The program iterates through each row in the dataset until the condition that mileage <= row.MILESTO is satisfied.
My original thought was using a search until EOF and this method works better.
Thanks all and again my apologies for the delay in summing this up for other users.