manipulating textbox variables in calculations

2019-03-06 06:39发布

I have some code where I am trying to use variables in a tabpage. The first tabpage only has one text box for user entry (miles.text) and a button to do a calculation: traveltime = mileage/speed. The value from miles.text is stored into a variable called mileage while the speed used is stored in a variable called speed (me.speedtextbox.text).

Ordinarily, doing val(variable.text) works like a charm and it's not doing it in this case. When the user enters 100 for the mileage, it should be divided by 65 (the number in the database) and, therefore, the answer should be 1.53 hours. In my case, I'm getting "infinity" and whenever I do anything else with the variable, I get "when casting from a number, the value must be a number less than infinity." But it is! It's only 65 and I double-checked that the dataset said that too, which it does. Not sure why I am getting this error...thank you!

Public Class Form1

    Private Property Traveltime As Decimal

    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 'fooDataSet.testdata' table. You can move, or remove it, as needed.
        Me.TestdataTableAdapter.Fill(Me.foouDataSet.testdata)

    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim mileage As Integer
        Dim speed As Integer


        mileage = Val(miles.Text)
        speed = Val(Me.SpeedTextBox.Text)
        traveltime = mileage / speed

        txttraveltime.text = Traveltime.ToString

    End Sub

    Private Sub txtrate_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txttraveltime.TextChanged

    End Sub
End Class

So I did a test program where it did only one thing and that was to simply read one data column in a one row database and store it to a local variable and multiply it by 1.60 except now I am getting "reference to a non-shared member requires an object reference" and it doesn't seem to recognize Me.Speed when I declare it. What am I doing wrong?

Public Class Form1

    Dim Speed As Object
    Dim Me.Speed As New Speed

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Me.Speed = CDec(fooDataSet.testdataRow.Item("speed"))*1.60
        Speedtextbox.text = Me.Speed.tostring

    End Sub

    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 'fooDataSet.testdata' table. You can move, or remove it, as needed.
        Me.TestdataTableAdapter.Fill(Me.fooDataSet.testdata)

    End Sub
End Class

3条回答
Evening l夕情丶
2楼-- · 2019-03-06 06:58

Before you do anything else, you should do the following:

  1. Open the project's properties (right-click on the Project, then select Properties)

  2. Click on the Compile tab (left-hand side)

  3. Select All Configurations from the dropdown menu

  4. Select On from the Option Explicit menu.

  5. Select On from the Option Strict menu.

  6. Save the project

This will more than likely cause a lot of errors to be displayed, but fixing these errors will substantially improve your application's health.

Now, that that is done, the following code will fix the problems in the button click:

    Dim mileage As Integer
    Dim speed As Integer

    If IsNumeric(Me.Miles.Text) Then
        mileage = CInt(Me.Miles.Text)
    End If
    If IsNumeric(Me.SpeedTextBox.Text) Then
        speed = CInt(Me.SpeedTextBox.Text)
    End If

    If speed <> 0 Then
        Traveltime = CDec(mileage / speed)
    Else
        Traveltime = 0
    End If

    txtTravelTime.Text = Traveltime.ToString

However, the code as you have it will produce correct results, so there must be something else amiss. Try the above first and if there are still issues, you can update your question with the details.

查看更多
相关推荐>>
3楼-- · 2019-03-06 06:58

I would implement the calculation in a separate class and then use object-binding. Here is how the travel time calculator would look like:

Imports System.ComponentModel

Public Class TraveltimeCalculator
    Implements INotifyPropertyChanged

    Private _miles As Double
    Public Property Miles() As Double
        Get
            Return _miles
        End Get
        Set(ByVal value As Double)
            If _miles <> value Then
                _miles = value
                OnPropertyChanged("Miles")
                OnPropertyChanged("Traveltime")
            End If
        End Set
    End Property

    Private _speed As Double
    Public Property Speed() As Double
        Get
            Return _speed
        End Get
        Set(ByVal value As Double)
            If _speed <> value Then
                _speed = value
                OnPropertyChanged("Speed")
                OnPropertyChanged("Traveltime")
            End If
        End Set
    End Property

    Public ReadOnly Property Traveltime() As Double
        Get
            Return If(_speed = 0.0, 0.0, _miles / _speed)
        End Get
    End Property

#Region "INotifyPropertyChanged Members"

    Public Event PropertyChanged As PropertyChangedEventHandler _
     Implements INotifyPropertyChanged.PropertyChanged

    Private Sub OnPropertyChanged(ByVal propertyName As String)
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
    End Sub

#End Region

End Class

In Visual Studio, add a data source in the Data Sources panel. Choose "Object" and then select the TraveltimeCalculator (it has to be compiled, before you can do that). Now you can drag the speed, mileage and travel time fields from the data sources panel to your form. All the wire-up will happen automatically. VS automatically inserts a BindingSource and a navigator into your form. You will not need the navigator and can safely remove it. The only thing you still have to do is to add the following code in the form load event handler or in the form constructor:

Private Sub frmTravelTime_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    TraveltimeCalculatorBindingSource.DataSource = New TraveltimeCalculator()
End Sub

When you enter speeds and mileages, the travel time textbox will automatically be updated. Non-numeric entries will automatically be rejected and all the text-number conversions happen automatically.

查看更多
女痞
4楼-- · 2019-03-06 07:10

I discovered what the problem was.

To store a field from a one-line database to a local variable for calculations, apparently it has to happen in the form1_load event, after the dataadapter fill statement, like so:

Me.TestdataTableAdapter.Fill(Me.foouDataSet.testdata)
  speed = Me.fooDataSet.testdata(0).speed

and just DIM speed as Decimal after the Public Class line. The same could be done for any other field you want to work with in a similar kind of single datarow:

yourvarname = Me.yourdatasetname.yourtablename(0).the_database_field_you_want_to_fetch

(Wow! Did I just write something textbooky? LOL)

Then, after the button click, to do a calculation, it is:

traveltime = CDec(miles.Text/ speed) 
txttraveltime.Text = traveltime.ToString

making sure to DIM traveltime as Decimal.

Works! The problem was the (0) to indicate row 0 (because it's only one row.) Thank you everyone for your help, especially Competent_Tech. I learned something and I'm happy that I could get back to you guys and share.

查看更多
登录 后发表回答