-
Jun 23rd, 2017, 12:32 AM
#1
Thread Starter
New Member
Need help writing complex formula in VB.NET
I need to create a working retirement calculator using the user inputs of: current age, retirement age, annual expenses, inflation and interest.
the math is giving me trouble. how do you write complex formulas in vb.net? like this example for instance:
monthly_savings = (annual_expenses * interest) ^ (retirement_age - current_age)
Code:
Class MainWindow
Private Sub txtbox1_TextChanged(sender As Object, e As TextChangedEventArgs) Handles txtbox1.TextChanged
Dim current_age As Integer
Dim retirement_age As Integer
Dim annual_expenses As Integer
Dim inflation As Integer
Dim interest As Integer
Dim monthly_savings As Integer
current_age = Val(txtbox1.Text)
retirement_age = Val(txtbox2.Text)
annual_expenses = Val(txtbox3.Text)
inflation = Val(txtbox4.Text)
interest = Val(txtbox5.Text)
monthly_savings = (annual_expenses * interest) ^ (retirement_age - current_age)
ansbox1.Text = monthly_savings
End Sub
End Class
when running I get this error
System.OverflowException was unhandled
HResult=-2146233066
Message=Arithmetic operation resulted in an overflow.
Source=test
StackTrace:
at test.MainWindow.txtbox1_TextChanged(Object sender, TextChangedEventArgs e)
at System.Windows.Controls.TextChangedEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)
at System.Windows.Controls.Primitives.TextBoxBase.OnTextChanged(TextChangedEventArgs e)
at System.Windows.Controls.Primitives.TextBoxBase.OnTextContainerChanged(Object sender, TextContainerChangedEventArgs e)
at System.Windows.Controls.TextBox.OnTextContainerChanged(Object sender, TextContainerChangedEventArgs e)
at System.Windows.Documents.TextContainerChangedEventHandler.Invoke(Object sender, TextContainerChangedEventArgs e)
at System.Windows.Documents.TextContainer.EndChange(Boolean skipEvents)
at System.Windows.Documents.TextContainer.System.Windows.Documents.ITextContainer.EndChange(Boolean skipEvents)
at System.Windows.Documents.TextRangeBase.EndChange(ITextRange thisRange, Boolean disableScroll, Boolean skipEvents)
at System.Windows.Documents.TextRange.System.Windows.Documents.ITextRange.EndChange(Boolean disableScroll, Boolean skipEvents)
at System.Windows.Documents.TextRange.ChangeBlock.System.IDisposable.Dispose()
at System.Windows.Documents.TextEditorTyping.DoTextInput(TextEditor This, String textData, Boolean isInsertKeyToggled, Boolean acceptControlCharacters)
at System.Windows.Documents.TextEditorTyping.TextInputItem.Do()
at System.Windows.Documents.TextEditorTyping.ScheduleInput(TextEditor This, InputItem item)
at System.Windows.Documents.TextEditorTyping.OnTextInput(Object sender, TextCompositionEventArgs e)
at System.Windows.Controls.Primitives.TextBoxBase.OnTextInput(TextCompositionEventArgs e)
at System.Windows.UIElement.OnTextInputThunk(Object sender, TextCompositionEventArgs e)
at System.Windows.Input.TextCompositionEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
at System.Windows.Input.InputManager.ProcessStagingArea()
at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
at System.Windows.Input.TextCompositionManager.UnsafeCompleteComposition(TextComposition composition)
at System.Windows.Input.TextCompositionManager.PostProcessInput(Object sender, ProcessInputEventArgs e)
at System.Windows.Input.InputManager.RaiseProcessInputEventHandlers(ProcessInputEventHandler postProcessInput, ProcessInputEventArgs processInputEventArgs)
at System.Windows.Input.InputManager.ProcessStagingArea()
at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
at System.Windows.Input.TextCompositionManager.UnsafeStartComposition(TextComposition composition)
at System.Windows.Input.TextCompositionManager.PostProcessInput(Object sender, ProcessInputEventArgs e)
at System.Windows.Input.InputManager.RaiseProcessInputEventHandlers(ProcessInputEventHandler postProcessInput, ProcessInputEventArgs processInputEventArgs)
at System.Windows.Input.InputManager.ProcessStagingArea()
at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
at System.Windows.Interop.HwndKeyboardInputProvider.ProcessTextInputAction(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at System.Windows.Interop.HwndSource.OnPreprocessMessage(Object param)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
at System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority priority, Delegate method, Object arg)
at System.Windows.Interop.HwndSource.OnPreprocessMessageThunk(MSG& msg, Boolean& handled)
at System.Windows.Interop.HwndSource.WeakEventPreprocessMessage.OnPreprocessMessage(MSG& msg, Boolean& handled)
at System.Windows.Interop.ThreadMessageEventHandler.Invoke(MSG& msg, Boolean& handled)
at System.Windows.Interop.ComponentDispatcherThread.RaiseThreadMessage(MSG& msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
at System.Windows.Application.RunDispatcher(Object ignore)
at System.Windows.Application.RunInternal(Window window)
at System.Windows.Application.Run(Window window)
at System.Windows.Application.Run()
at test.Application.Main()
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
-
Jun 23rd, 2017, 05:00 AM
#2
Re: Need help writing complex formula in VB.NET
declaring monthly_savings should get you rid of the error.
nevertheless, consider the following:
- turn Option Strict ON
- Remove the VisualBasic Namespace from your Project
- User propper parsing methods on the TextBox Input
googling for each of those will get you arguments why
-
Jun 23rd, 2017, 06:06 AM
#3
Re: Need help writing complex formula in VB.NET
Originally Posted by digitalShaman
declaring monthly_savings should get you rid of the error.
@digitalShaman I think you'll find StarPlayerRob has declared 'monthly_savings', more likely to be the use of an integer rather than a double, 'Overflow' being the operative word.
Hi,
To save yourself some typing and some space... you can declare all of your integer variables in fewer lines.
For example: -
Code:
Dim a, b, c As Int32, d, e, f As String, g, h, i As Boolean
(Be careful with 'e' ! )
Code:
Dim current_age, retirement_age, annual_expenses, inflation, interest, monthly_savings As Int32
You can make these variables (Any variable) accessible to all your subroutines by placing the declaration before the first subroutine of your code:
Code:
Dim current_age, retirement_age, annual_expenses, inflation, interest, monthly_savings As Int32
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
If you're not using 'sender' or 'e', you can delete them from the automatic subroutine heading:
Code:
Private Sub Form1_Load() Handles MyBase.Load
Poppa.
Last edited by Poppa Mintin; Jun 23rd, 2017 at 07:43 AM.
Along with the sunshine there has to be a little rain sometime.
-
Jun 23rd, 2017, 07:30 AM
#4
Re: Need help writing complex formula in VB.NET
You need to declare your variables with the proper type. Interest should be a Decimal. Monthly_savings should be a Long as your formula is now. However, I don't believe your formula is correct, even using a proper decimal value for interest. Here's a simple example:
monthly_savings = (24000 * 0.01) ^ (65-55) => 240^10 = 634,033,809,653,760,000,000,000, which obviously is not going to be what is saved per month. That value will not fit in an Integer, which is why it should be Long with that formula.
-
Jun 23rd, 2017, 07:35 AM
#5
Re: Need help writing complex formula in VB.NET
Hi again StarPlayerRob...
Something else just occurred to me...
Code:
ansbox1.Text = monthly_savings
You shouldn't put numerical data into a Textbox... At least not like that!
Better like this...
Code:
ansbox1.Text = monthly_savings.ToString
...it'll convert the numerical data into a String data. Obviously if you want to use the data from the TextBox you'll have to convert it back. eg. ( = Val(ansbox1.Text))
Poppa.
Last edited by Poppa Mintin; Jun 23rd, 2017 at 07:46 AM.
Along with the sunshine there has to be a little rain sometime.
-
Jun 23rd, 2017, 07:40 AM
#6
Re: Need help writing complex formula in VB.NET
Rather than using a textbox, use a NumericUpDown control. Textboxes can only hold strings, so you have to convert to and from strings if the textbox holds a number (represented as a string). If you aren't doing that conversion explicitly, then the compiler is doing it implicitly, which is both less efficient, and will crash if the conversion doesn't work. If you use a NUD, then the .Value property returns a Decimal. You can ONLY enter numbers, and you can set max, min, and the number of decimal places permissible.
My usual boring signature: Nothing
-
Jun 23rd, 2017, 12:13 PM
#7
Re: Need help writing complex formula in VB.NET
"monthly_savings = (annual_expenses * interest) ^ (retirement_age - current_age)"
I'm pretty suspicious of that "^" in the equation. That is raising a value to a power so will give your really large numbers quite easily, which seems quite unlikely.
Who is going to have multiple billions in monthly_savings?
-
Jun 23rd, 2017, 01:24 PM
#8
Re: Need help writing complex formula in VB.NET
Originally Posted by Poppa Mintin
@digitalShaman I think you'll find StarPlayerRob has declared 'monthly_savings', more likely to be the use of an integer rather than a double, 'Overflow' being the operative word.
LOL, yeah, i missed to type the "as double"... it was in my head though
-
Jun 23rd, 2017, 04:13 PM
#9
Re: Need help writing complex formula in VB.NET
I, too, think that exponentiation is not the right operation for this formula. I think you got the wrong formula. Let's talk about the problem.
It looks like you're trying to answer, "If I save x per year for y years, how much will I save?"
That would best be represented by repeated addition. Let's say I save $5 for 10 years. I will save:
5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 = 5 * 10 = $50
Exponentiation is repeated multiplication. I can't even contrive a word problem version of what that'd be like in terms of savings.
So I think your ^ should be a *.
This answer is wrong. You should be using TableAdapter and Dictionaries instead.
-
Jun 23rd, 2017, 04:44 PM
#10
Re: Need help writing complex formula in VB.NET
So you need to execute:
Code:
monthly_savings = (annual_expenses * interest) ^ (retirement_age - current_age)
Where the annual_expenses is a value stored in txtbox3, interest is a value stored in txtbox5, retirement_age is a value stored in txtbox2, and current_age is a value stored in txtbox1. My first suggestion would be to represent anything related to money (monthly_savings and annual_expenses) as a Decimal, anything else that can accept a decimal place (interest) as a Double, and anything that represents age as a Byte (retirement_age and current_age). My second suggestion would be to use the respective type's TryParse method to convert the String value found in the TextBox control. My third suggestion would be to check if the retirement age is greater than the current age. My fourth suggestion, I agree with digitalShaman and Sitten Spynne that I think you really want to replace your exponent operator with a multiplication operator. My fifth and final suggestion is that since your current formula (with the operator fix) will return the annual savings, not the monthly savings.
Your formula should actually look like:
Code:
monthly_savings = ((annual_expenses * interest) * (retirement_age - current_age)) / 12
Here is an example of implementing those suggestions:
Code:
Dim monthly_savings, annual_expenses As Decimal
Dim interest As Double
Dim retirement_age, current_age As Byte
If Decimal.TryParse(txtbox3.Text, annual_expenses) AndAlso Double.TryParse(txtbox5.Text, interest) AndAlso Byte.TryParse(txtbox2.Text, retirement_age) AndAlso Byte.TryParse(txtbox1.Text, current_age) AndAlso retirement_age > current_age Then
monthly_savings = ((annual_expenses * interest) * (retirement_age - current_age)) / 12
ansbox1.Text = monthly_savings.ToString("c")
End If
Fiddle: https://dotnetfiddle.net/UED6Kc
Last edited by dday9; Jun 23rd, 2017 at 04:48 PM.
Reason: Included a Fiddle
-
Jun 23rd, 2017, 09:16 PM
#11
Thread Starter
New Member
Re: Need help writing complex formula in VB.NET
awesome thanks everyone for your help and great suggestions. I know my formula is incorrect, that's the part I'm having the most trouble with . is there any way to use excel's goal seeking function in VB? I know there have been retirement calculators built in excel using that function.
also dday9 I have used your suggestion so far.
-
Jun 23rd, 2017, 09:43 PM
#12
Thread Starter
New Member
Re: Need help writing complex formula in VB.NET
also if I shouldn't use textbox for the numeric value inputs what should this part look like?
Code:
current_age = Val(txtbox1.Text)
retirement_age = Val(txtbox2.Text)
Monthly_Expenses = Val(txtbox3.Text)
inflation = Val(txtbox4.Text)
interest = Val(txtbox5.Text)
-
Jun 25th, 2017, 08:07 AM
#13
Re: Need help writing complex formula in VB.NET
Originally Posted by Shaggy Hiker
Rather than using a textbox, use a NumericUpDown control. Textboxes can only hold strings, so you have to convert to and from strings if the textbox holds a number (represented as a string). If you aren't doing that conversion explicitly, then the compiler is doing it implicitly, which is both less efficient, and will crash if the conversion doesn't work. If you use a NUD, then the .Value property returns a Decimal. You can ONLY enter numbers, and you can set max, min, and the number of decimal places permissible.
Been doing a little work on this...
Choice of a NUD seems a little odd, I don't believe the user can be prevented from changing the value in the NUD should they 'play' with the results.
I would suggest a MaskedTextBox with a suitable mask.
Maybe something along these lines:
Code:
MaskedTextBox1.Mask = Convert.ToDecimal(value)
MaskedTextBox1.Text = value
Poppa.
Along with the sunshine there has to be a little rain sometime.
-
Jun 25th, 2017, 11:55 AM
#14
Thread Starter
New Member
Re: Need help writing complex formula in VB.NET
now I'm getting Error BC30690 Structure 'Decimal' cannot be indexed because it has no default property. what do I need to change to fix this?
Code:
Class MainWindow
Private Sub button_Click(sender As Object, e As RoutedEventArgs) Handles button.Click
Dim Yearly_expense, m_expenses As Decimal
Dim interest, inflation As Double
Dim retirement_age, current_age As Byte
current_age = Val(txtbox1.Text)
retirement_age = Val(txtbox2.Text)
m_expenses = Val(txtbox3.Text)
inflation = Val(txtbox4.Text)
interest = Val(txtbox5.Text)
If Decimal.TryParse(txtbox3.Text, Yearly_expense) AndAlso Double.TryParse(txtbox5.Text, interest) AndAlso Byte.TryParse(txtbox2.Text, retirement_age) AndAlso Byte.TryParse(txtbox1.Text, current_age) AndAlso retirement_age > current_age Then
Yearly_expense = m_expenses(1 + inflation) ^ (retirement_age - current_age) * 12
ansbox1.Text = Yearly_expense.ToString("c")
End If
End Sub
Private Sub button2_Click(sender As Object, e As RoutedEventArgs) Handles button2.Click
txtbox1.Clear()
txtbox2.Clear()
txtbox3.Clear()
txtbox4.Clear()
txtbox5.Clear()
ansbox1.Clear()
End Sub
End Class
-
Jun 25th, 2017, 12:29 PM
#15
Re: Need help writing complex formula in VB.NET
The piece of code
Code:
m_expenses(1 + inflation)
is using the syntax for addressing an element in an array - you probably mean
Code:
m_expenses * (1 + inflation)
-
Jun 26th, 2017, 08:48 AM
#16
Re: Need help writing complex formula in VB.NET
Originally Posted by StarPlayerRob
also if I shouldn't use textbox for the numeric value inputs what should this part look like?
Code:
current_age = Val(txtbox1.Text)
retirement_age = Val(txtbox2.Text)
Monthly_Expenses = Val(txtbox3.Text)
inflation = Val(txtbox4.Text)
interest = Val(txtbox5.Text)
If you use the appropriate control (which in this case would be a NumericUpDown) then you wouldn't need to convert the String values returned from the Text property of your TextBox since the NumericUpDown's Value property returns a Decimal. The reason why you should use a NumericUpDown is because it ensures that the user will enter a valid Decimal value whereas in a TextBox the user can literally enter whatever value they desire.
-
Jun 26th, 2017, 10:29 AM
#17
Re: Need help writing complex formula in VB.NET
Originally Posted by Poppa Mintin
Been doing a little work on this...
Choice of a NUD seems a little odd, I don't believe the user can be prevented from changing the value in the NUD should they 'play' with the results.
I don't understand the issue with that. I was assuming that the user WOULD be allowed to change the values. If the values shouldn't be changed, then a label would be the right control. A NUD is the right control for entering only numbers, while a textbox is the right control for entering text.
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|