Results 1 to 6 of 6

Thread: Distance Calc Problems

  1. #1

    Thread Starter
    Member
    Join Date
    Jun 2017
    Posts
    35

    Distance Calc Problems

    I am building a distance calculator for an assignment. I have opted for two textboxes where the user can enter the following information: (speed limit, days planning to drive.) A list box for the user to enter the amount of hours they plan to drive on those days. I am running into some issues and going to start at the top and work my way down.

    Initially the user will enter (speed limit, days driving) into the text boxes and once confirmed this will enable the button for the listbox where the user can enter the hours for driving.

    How can I make the listbox recognize the number of days that has been entered into the textbox? When I run the code now I enter a number and it automatically enters that for all 7 days available.

    This is what I have now. Advice always very appreciated. Thanks!

    Code:
    Private Sub btnCalculate_Click(sender As Object, e As EventArgs) Handles btnDistance.Click
    
            Dim decSpeedLimit As Decimal
            'Dim decDays As Decimal
            Dim strHours As String
            Dim decHours As Decimal
            Dim decTotalMiles As Decimal = 0
    
            Dim strInputMessage As String = "Enter the hours you are driving day #"
            Dim strInputHeading As String = "Daily Driving Hours"
            Dim strNormalMessage As String = "Enter the hours you are driving day #"
            Dim strNonNumericError As String = "Enter Numeric values only"
            Dim strNegativeError As String = "ERROR- Negative values are not allowed"
            Dim strTwentyError As String = "ERROR - Hours can only be between 1 and 20"
    
            'Loop Variables
            Dim intMaxNumberOfEntries As Integer = 7
            Dim intNumberOfEntries As Integer = 1
            Dim strCancelClicked As String = ""
    
            strHours = InputBox(strInputMessage & intNumberOfEntries, strInputHeading, " ")
    
            Do Until intNumberOfEntries > intMaxNumberOfEntries Or strHours = strCancelClicked
    
                If IsNumeric(strHours) Then
                    decHours = Convert.ToDecimal(strHours)
                    If decHours >= 1 And decHours <= 20 Then
                        lstData.Items.Add(decHours)
                        decHours += decHours
                        intNumberOfEntries += 1
                        strInputMessage = strNormalMessage
                    Else
                        strInputMessage = strTwentyError
                    End If
                Else
                    strInputMessage = strNonNumericError
                End If
            Loop
    
            If intNumberOfEntries > 1 Then
                lblTotal.Visible = True
                decTotalMiles = (decSpeedLimit * decHours)
                lblTotal.Text = "Total distance traveled is " & decTotalMiles.ToString("F1") & "miles"
            Else
                MsgBox("No values entered", , "Input Error")
            End If
    
        End Sub
    
        Private Sub mnuDistance_ItemClicked(sender As Object, e As ToolStripItemClickedEventArgs) Handles mnuDistance.ItemClicked
    
        End Sub
    
        Private Sub DistanceCalculator_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
    
            lstData.Items.Clear()
            lblTotal.Text = ""
            lblTotal.Visible = False
            btnDistance.Enabled = False
            btnInfo.Enabled = True
            txtDays.Clear()
            txtSpeed.Clear()
            txtSpeed.Focus()
    
        End Sub
    
        Private Sub btnInfo_Click(sender As Object, e As EventArgs) Handles btnInfo.Click
    
            Dim decSpeedLimit As Decimal
            Dim decDays As Decimal
    
            If IsNumeric(txtSpeed.Text) Then
                decSpeedLimit = Convert.ToDecimal(txtSpeed.Text)
                If decSpeedLimit <= 0 Then
                    MsgBox("Enter A Value between 25-85", , "Input Error")
                    txtSpeed.Text = ""
                    txtSpeed.Focus()
                End If
            Else
                MsgBox("Enter A Numeric Value", , "Input Error")
                txtSpeed.Text = ""
                txtSpeed.Focus()
            End If
    
            If IsNumeric(txtDays.Text) Then
                decDays = Convert.ToDecimal(txtDays.Text)
                If decDays >= 1 And decDays <= 7 Then
                    decDays = decDays
                    decSpeedLimit = decSpeedLimit
                    btnDistance.Enabled = True
                Else
                    MsgBox("Enter a value between 1-7", , "Input Error")
                    txtDays.Text = ""
                    txtDays.Focus()
                End If
            Else
                MsgBox("Enter a Numeric Value", , "Input Error")
                txtDays.Text = ""
                txtDays.Focus()
            End If
    
    
        End Sub

  2. #2
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,038

    Re: Distance Calc Problems

    The first thing I'd do is get rid of the InputBox. I realize that you sometimes don't have a choice about using that, so you can ignore that if you must, but InputBox is almost never the right solution to any problem (I do have a single place where it was totally perfect, which is why I added the 'almost'). Creating a form that does the same thing without the problems would take only minutes, at most, so it's worth doing. The big issue with InputBox is that you can't tell the difference between cancel and no entry. That's kind of a stupid design, since you can't be sure what the user intended.

    Another issue with InputBox is that it ALWAYS returns a string. That string may be a valid number, or it could be something else, including an empty string (which is indistinguishable from pressing Cancel). If you make your own input box form, you can put a label on there (to hold your caption), and a NumericUpDown control such that the user can only enter numbers where numbers are wanted. The .Value from the NUD would be a Decimal. You can leave it as such, or safely convert it to an integer. You are currently going through some contortions to convert the string from InputBox into a number, and a NUD would remove those contortions.

    You should also consider using NUD in place of textboxes. The NUD is really made for numeric input, while the textbox deals only with strings.

    However, if you stick with InputBox, then scrap the IsNumeric and Convert.ToDecimal() calls. You can just use Decimal.TryParse() to do both of those steps in one.
    My usual boring signature: Nothing

  3. #3
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,038

    Re: Distance Calc Problems

    I guess I skipped over the actual question entirely in that reply.

    The listbox seems like it will cause you trouble. A listbox is largely for displaying data, but you said you wanted to enter some number of hours for each day, and the listbox is not really suited for data entry. What you might consider is using a DataGridView for this. There are LOADS of options for a DGV, so it can appear a bit daunting...and you can certainly make it daunting if you want to. For example, I'd create a datatable and bind it to the DGV, which makes some things easier, but may make it appear more complicated.

    Without the datatable, a DGV can act something like a spreadsheet. You could have a column for Day and a column for Hours Driven. You may want to set the AllowUserToAddRows to false (at least initially, though it might inspire you later on). If the user enters X days, then you could add X rows to the DGV, with that first column having just the numbers 1 to X. You could also make that column read only. The user would then be able to enter numbers into the other column, and you'd be able to get those numbers back out by looking at DGV.Rows(Y).Cells(X).
    My usual boring signature: Nothing

  4. #4

    Thread Starter
    Member
    Join Date
    Jun 2017
    Posts
    35

    Re: Distance Calc Problems

    Yes unfortunately the list box is required on this assignment. I have not seen anything in my book about creating your own form. Can you help point me in the right direction? I am interested to look into it, if it will only take a small amount of time to help me figure this out. I'm feeling a little discouraged here. Thanks again

  5. #5
    PowerPoster ChrisE's Avatar
    Join Date
    Jun 2017
    Location
    Frankfurt
    Posts
    3,048

    Re: Distance Calc Problems

    Hi Bsquared,

    take the advice from S

    here a sample with DGV, I added some sample Data, you just need to extend it to what you want

    Code:
    'Controls you need:
    '1x ComboBox = cboJahr
    '1x Datagridview = DataGridView1
    '1x Button = Button1
    '1 x Form = daysinYear
    
    Option Strict On
    
    
    Public Class daysinYear
        Dim ActivJahr As Long
    
        Sub IniCombos()
            Dim formatInfo = System.Globalization.DateTimeFormatInfo.CurrentInfo
            For i As Integer = 2010 To 2099
                cboJahr.Items.Add(i)
            Next
            cboJahr.SelectedIndex = CInt(ActivJahr - 2010)
        End Sub
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            BindData()
            FormatDataTable()
            GetData()
            DGVColumsAutoSize(True)
            Me.DataGridView1.FirstDisplayedScrollingRowIndex = Me.DataGridView1.RowCount - 1
    
        End Sub
    
        Private Sub BindData()
            DataGridView1.DataSource = GetData()
        End Sub
        Protected Function FormatDataTable() As DataTable
            Dim dt As DataTable = New DataTable()
            ' Create Columns
            dt.Columns.Add("Date", System.Type.GetType("System.String"))
            dt.Columns.Add("Week", System.Type.GetType("System.String"))
            dt.Columns.Add("Day", System.Type.GetType("System.String"))
            dt.Columns.Add("Day No.", System.Type.GetType("System.String"))
            '     dt.Columns.Add("TagKe", System.Type.GetType("System.String"))
            Return dt
        End Function
    
        Protected Function GetData() As DataTable
            Dim dt As DataTable = FormatDataTable()
            Dim dr As DataRow
            Dim d As Date = New Date(CInt(cboJahr.Text), 1, 1)
            Do While d.Year = CDbl(cboJahr.Text)
                Dim dateValue As Date = d
                dr = dt.NewRow
                dr("Date") = d.ToString("dd.MM.yyyy")
                dr("Week") = GetWeekfromDate(CDate(d.ToString("dd.MM.yyyy")))
                dr("Day") = d.ToString("ddd")
                dr("Day No.") = dateValue.DayOfWeek.ToString("d")
                ' dr("TagKe") = ""
                ' Add the row
                dt.Rows.Add(dr)
                d = d.AddDays(1)
            Loop
            '  ApplyFormatting()
            Return dt
        End Function
    
        Public Sub DGVColumsAutoSize(ByVal AutoSize As Boolean)
    
            If DataGridView1 Is Nothing Then
                Exit Sub
            End If
    
            Dim ColumnMode As DataGridViewAutoSizeColumnMode
            If AutoSize Then
                ColumnMode = DataGridViewAutoSizeColumnMode.AllCells
            Else
                ColumnMode = DataGridViewAutoSizeColumnMode.None
            End If
    
            With DataGridView1
                For i As Integer = 0 To .Columns.Count - 1
                    .Columns(i).AutoSizeMode = ColumnMode
                Next
            End With
        End Sub
    
        Private Sub dayinYear_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            ActivJahr = If(ActivJahr = 0, Year(Now), ActivJahr)
            IniCombos()
        End Sub
    
        Function GetWeekfromDate(ByVal Datum As Date) As Byte
            Return CByte(DatePart(DateInterval.WeekOfYear, _
            Datum, FirstDayOfWeek.System, _
            FirstWeekOfYear.System))
        End Function
    
      
    End Class
    regards
    Chris
    to hunt a species to extinction is not logical !
    since 2010 the number of Tigers are rising again in 2016 - 3900 were counted. with Baby Callas it's 3901, my wife and I had 2-3 months the privilege of raising a Baby Tiger.

  6. #6
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,038

    Re: Distance Calc Problems

    If the listbox is a requirement, then you may have no choice, but....that would be a terrible constraint, because the listbox is not designed for data entry, so any solution you can come up with will suck to one extent or another. What people tend to do would be to handle the SelectedIndex changed event for the listbox, which will tell you when a person selects something, and in that event handler, move the data to a textbox, at which point you then enter something into a different textbox (or NUD), then press a button to move the information back to the listbox....where you will format it poorly, because that's about all you can do. As a solution, this is awkward and ugly, but assignments often are.

    You actually already know how to create a new form, though you may have never done it explicitly, since you are given one by default in a blank project. To add a new one, go to the Project menu and select Add Windows Form. You then get a new form to play around with just as you have done with any other form. So, to make it look like an InputBox, put a label on it, a NUD, an OK button, and a CANCEL button (just buttons with their captions set). This form will be called Form2, by default, though you can change the name around.

    Then, to use it, you could do something like this:
    Code:
    dim nf As New Form2
    
    nf.YourLabel.Text = "Whatever text you want to show"
    'You could also set the minimum and maximum for the NUD, if you wanted to.
    
    If nf.ShowDialog = DialogResult.Ok Then
     'Get the value from the NUD:
     whateverVariable = nf.YourNUD.Value 'This will be type Decimal, even if you didn't allow decimal places.
    End If
    The only other thing is that in the button handler for the OK button you'd set Me.DialogResult = DialogResult.OK, and in the cancel button you'd set the dialog result to Cancel. I may have some part of the DialogResult part typed wrong, but I'm close.
    My usual boring signature: Nothing

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width