texbox calculation not correct - vba

I'm running this code that should sum the values of two textboxes which it does correctly up to 999 if the number goes into the thousands the result comes back as 2.00 this is my code:
Private Sub Txtunitcost_Exit(ByVal Cancel As MSForms.ReturnBoolean)
Me.TxtTotal.Value = Val(Me.TxtQty.Value) * Val(Me.TxtUnitCost.Value)
TxtTotal.Value = Format(TxtTotal.Value, ("#,##0.00;-#,##0.00"))
TxtUnitCost.Value = Format(TxtUnitCost.Value, ("#,##0.00;-#,##0.00"))
End Sub

For your code a quick fix could be to remove the thousand separator during the calculation like that
Private Sub Txtunitcost_Exit(ByVal Cancel As MSForms.ReturnBoolean)
txtUnitCost = Replace(txtUnitCost, Application.ThousandsSeparator, "")
Me.txtTotal.Value = Val(Me.txtQty.Value) * Val(Me.txtUnitCost.Value)
txtTotal.Value = Format(txtTotal.Value, ("#,##0.00;-#,##0.00"))
txtUnitCost.Value = Format(txtUnitCost.Value, ("#,##0.00;-#,##0.00"))
End Sub
For further expalnation have a look at the output of the following code
Sub Test()
Debug.Print Val("1000,00"), Val("1.000,00")
End Sub
1000 1
The strings represent thousand for me (german version, depending on the thousand separator) but the result of the conversion is different because of the thousand separator.
And the quick fix is
Sub Test()
Dim s1 As String
Dim s2 As String
s1 = "1000,00"
s2 = "1.000,00"
Debug.Print Val(s1), Val(s2), Val(Replace(s2, _
Application.ThousandsSeparator, ""))
End Sub
1000 1 1000
Even better would be to use CLng or CDbl instead of Val because
The Val function stops reading the string at the first character it
can't recognize as part of a number.
So the better fix would be
Private Sub Txtunitcost_Exit(ByVal Cancel As MSForms.ReturnBoolean)
Me.txtTotal.Value = CDbl(Me.txtQty.Value) * CDbl(Me.txtUnitCost.Value)
txtTotal.Value = Format(txtTotal.Value, ("#,##0.00;-#,##0.00"))
txtUnitCost.Value = Format(txtUnitCost.Value, ("#,##0.00;-#,##0.00"))
End Sub
This is also stated in the above documentation
Note: The only valid decimal separator recognized by the Val()
function is the period (.). If you use a different decimal separator,
as some international applications do, use the CDbl function instead.

How about:
Private Sub Txtunitcost_Exit(ByVal Cancel As MSForms.ReturnBoolean)
Dim TxtQty, TxtUnitCost, TxtTotat as Long
TxtQty = Format(Me.TxtQty.Value, ("#,##0.00;-#,##0.00"))
TxtUnitCost = Format(Me.TxtQty.Value, ("#,##0.00;-#,##0.00"))
TxtTotat = Format(TxtQty * TxtUnitCost, ("#,##0.00;-#,##0.00"))
End Sub

Related

Pricing a European Option using Simulaitons

I have created a user form that allows the user to change the various variables involved in pricing an option (Exercise Price, volatility..etc) along with allowing the user to change the simulations needed to arrive at the Price (or mean price in this case). However, I am unable to call the public subs within my code once I click the OK Button. Any suggestions on what I'm doing wrong would be greatly appreciated. [I have also included a picture of my user form below]
Option Explicit
Private cancel As Boolean
Public Function ShowInputsDialog(currentPrice As Single, _
exercisePrice As Single, riskfreeRate As Double, _
volatility As Single, duration As Single, simulation As Double) As Boolean
Call Initialize
Me.Show
If Not cancel Then
'Capture the other inputs.
currentPrice = txtCurrentPrice.Text
exercisePrice = txtExercisePrice.Text
riskfreeRate = txtRiskfreeRate.Text
volatility = txtVolatility.Text
duaration = txtDuration.Text
simulation = txtSimulation.Text
ShowInputsDialog = Not cancel
Unload Me
End Function
Public Sub ErrorCheck()
' Perform error checking for user inputs.
If IsNumeric(currentPrice) = False Or currentPrice < 0 Then
MsgBox ("Please enter a numeric value for the Current Price")
End If
If IsNumeric(exercisePrice) = False Or exercusePrice < 0 Then
MsgBox ("Please enter a positive numeric value for the exercise price")
End If
If IsNumeric(riskfreeRate) = False Then
MsgBox ("Please enter a numerical value for the risk-free rate")
End If
If IsNumeric(volatility) = False Then
MsgBox ("Please enter a numerical value for the Standard deviation")
End If
If IsNumeric(duration) = False Then
MsgBox ("Please enter a numerical valye for duration")
End If
End Sub
Public Sub Call_Eur(currentPrice As Single, _
exercisePrice As Single, riskfreeRate As Double, _
volatility As Single, duration As Single, simulation As Double)
Dim stockPrice As Single
Dim CallcashflowTermination As Single
Dim PutcashflowTermination As Single
Dim CalldiscountedValue As Double
Dim PutdiscountedValue As Double
Dim i As Integer
Dim CallMean As Double
Dim PutMean As Double
Dim arrayCallPrice() As Integer
Dim arrayPutPrice() As Integer
For i = 1 To simulation
' stock price
stockPrice = currentPrice * Exp((riskfreeRate - 0.5 * volatility ^ 2) * duration + volatility * Application.WorksheetFunction.Norm_Inv(Rnd(), 0, 1) * Sqr(duration))
' option cash flow at termination
CallcashflowTermination = Application.WorksheetFunction.Max(0, stockPrice - exercisePrice)
PutcashflowTerminatio = Application.WorksheetFunction.Funciton.Max(0, exercisePrice - stockPrice)
' discounted value of the option
CalldiscountedValue = CallcashflowTermination * Exp(-duration * riskfreeRate)
PutdiscountedValue = PutcashflowTermination * Exp(-duration * riskfreeRate)
arrayCallPrice(i) = CalldiscountedValue
arrayPutPrice(i) = PutdiscountedValue
CallMean = Application.WorsheetFunction.Average(arrayCallPrice)
PutMean = Application.WorksheetFunction.Average(arrayPutPrice)
Next i
MsgBox "The Call option price is " & CallMean & " the Put option price is " & PutMean
End Sub
Private Sub CmdCancel_Click()
Me.Hide
cancel = True
End Sub
Private Sub CmdOK_Click() '<--- ERROR!!!
Call Call_Eur(currentPrice As Single, _
exercisePrice As Single, riskfreeRate As Double, _
volatility As Single, duration As Single, simulation As Double)
End Sub
Private Sub UserForm_Click()
End Sub
BIG RED FLAG!!!!
When calling a subroutine. you need to pass values into it. Not redefine it's parameters.
Private Sub CmdOK_Click() '<--- ERROR!!!
Call Call_Eur(12.50, 13.43, 14, 33.56, 100, 13.67)
End Sub
I prefer removing the parenthesis and not using Call at all.
Private Sub CmdOK_Click() '<--- ERROR!!!
Call_Eur 12.50, 13.43, 14, 33.56, 100, 13.67
End Sub

Error while comparing msgbox with textbox in vba

I am new to VBA. I have created a program in VBA that compares a msgbox value with a textbox value, but the result is not right. I have copied the code below. What have I done wrong on this? Please help me.
Private Sub CommandButton1_Click()
Dim num As String
num = Application.InputBox("enter num")
If TextBox1.Value * num > TextBox2.Value Then
MsgBox "textbox1 is higher"
Else
MsgBox "textbox2 is higher"
End If
End Sub
You need an input validation before processing it
like follows
Option Explicit
Private Sub CommandButton1_Click()
Dim num As Long, tb1Val As Long, tb2Val As Long
Const DEFNUM As Long = 1 '<--| define a default value for 'num'
If Not ValidateInput(tb1Val, tb2Val) Then Exit Sub '<--| exit if textboxes have improper input
num = Application.InputBox("enter num", , DEFNUM, Type:=1) '<-_| 'Type:=1' forces a number input
With Me
If tb1Val * num > tb2Val.Value Then
MsgBox "textbox1 is higher"
Else
MsgBox "textbox2 is higher"
End If
End With
End Sub
Function ValidateInput(tb1Val As Long, tb2Val As Long) As Boolean
With Me
If IsNumber(.TextBox1) And IsNumber(.TextBox2) Then
tb1Val = CLng(.TextBox1.Value)
tb2Val = CLng(.TextBox2.Value)
ValidateInput = True
Else
MsgBox "Improper textbox input, try again", vbCritical
End If
End With
End Function
as you can see:
demanded to Function ValidateInput() the validation of relevant userfom input
you may want to change it to suit your actual needs
used Application.InputBox() function instead of VBA.InputBox() to exploit its Type parameter and force the input to a number
I assumed you need Long numbers, should not this be the case just change all Long occurrences with the needed data type (Double, Integer,...) and CLng() with corresponding Type conversion function (CDbl(), CInt(), ...
You Need to make sure all values you are getting from the InpoutBox and TextBox are numbers (in my code converted to Long , just to be on the safe side):
Private Sub CommandButton1_Click()
Dim num As Long
' convert the number received from the InputBox to a number (type Long)
num = CLng(Application.InputBox("enter num"))
If CLng(TextBox1.Value) * num > CLng(TextBox2.Value) Then
MsgBox "textbox1 is higher"
Else
MsgBox "textbox2 is higher"
End If
End Sub
What you had to do was just use the Val() function when getting the TextBox values. which means you had to use Val(TextBox1.Value) instead of TextBox1.Value
Private Sub CommandButton1_Click()
Dim num As String
num = Application.InputBox("enter num")
If Val(TextBox1.Value) * num > Val(TextBox2.Value) Then
MsgBox "textbox1 is higher"
Else
MsgBox "textbox2 is higher"
End If
End Sub

Fastest way too check input for punctuations in VBA

Just as the title says whats the fastest way to check if a userinput contains a punctuations except / , i'm New to VBA and struggeling with this for A couple of hours now
See if the string contains anything thats not A to Z, 0 to 9 or /
hasPunctuation = astring like "*[!A-Za-z0-9/]*"
If all you want is letters, numerals, and the slash then is one way:
Sub PuncCheck()
Dim strng1 As String, strng2 As String
strng1 = "qwerty12345678~!##$%^&*()_+"
strng2 = "qwerty12345678/"
Call StringCheck(strng1)
Call StringCheck(strng2)
End Sub
Sub StringCheck(sIN As String)
Dim i As Long, sCH As String
For i = 1 To Len(sIN)
sCH = Mid(sIN, i, 1)
If sCH Like "[0-9a-zA-Z]" Or sCH = "/" Then
Else
MsgBox "string has junk"
Exit Sub
End If
Next i
MsgBox "string has no junk"
End Sub

How do you count the list of strings VBA Excel?

I'm still new to VBA Excel coding. Do tell me if there's anything that needs improvement.
In the example below I'm trying to get the list of even values from the generate class and insert into the excel vba sheet. But how do I count the number of list returned?
Private Function Generate()
Dim red(1 To 20) As String
For i = 1 To 20
red(i) = i * 2
Next i
Generate = red()
End Function
Sub Format()
Dim str() As String
str() = Generate
Range("A1").Select
With Selection
For i = 1 To str().Count 'what do I do with this? Obviously str().Count is not working.
.Offset(1, i).Value = str(i)
Next
End With
End Sub
Thank you.
Managed to solve on my own and here is the answer:
Private Function Generate()
Dim red(1 To 20) As String
For i = 1 To 20
red(i) = i * 2
Next i
Generate = red()
End Function
Sub Format()
Dim str() As String
str() = Generate
Range("A1").Select
With Selection
For i = LBound(str) To UBound(str)
.Offset(i - 1, 0).Value = str(i)
Next
End With
End Sub

Extracting Capital Letters on a String during KeyPress

I have two TextBoxes..
I want to extract/duplicate ALL CAPITAL LETTERS to be inputted by the user to another TextBox during an event of KeyPress.
Logic :
Private Sub TextBox1_KeyPress()
'If the Character is a Capital Letter Then
' Copy and Concatenate it to the second TextBox
'End If
End Sub
You can try this:
For i = 0 To TextBox1.Text.Length - 1
Dim c As Char = TextBox1.Text.Chars(i)
If Char.IsUpper(c) Then
TextBox2.AppendText(c)
End If
Next
If you need it as a function:
Private Function ExtractUppers(ByVal txt As TextBox) As String
Dim sExtract As String = ""
For i = 0 To txt.Text.Length - 1
Dim c As Char = txt.Text.Chars(i)
If Char.IsUpper(c) Then
sExtract = sExtract & c
End If
Next
Return sExtract
End Function
And in your button:
TextBox2.Text = ExtractUppers(TextBox1)
It was solved by my friend! :) Thanks for your replies!
Private Sub TextBox1_TextChange()
CapitalLetter = Regex.Replace(TextBox1.Text, "[^A-Z]", String.Empty)
TextBox2.Text = CapitalLetter
End Sub
Maybe you can use this trick:
If letterVar = letterVar.ToUpper() then
TextBox2.Text &= letterVar
End if