Decimal points handling within textbox in an excel form - vba

I want to display a number in a textbox within an excel form. report, however I only want to show any decimal points if they are present and the I only want to show 2 decimal places.
e.g. if the number is 12 then I want to show 12
If the number is 12.1 then I want to show 12.10
If the number is 12.126 then I want to show 12.13
At the moment i have the below code and it is not showing me decimal points:
Me.Amount.Value = Format(Me.Amount, "#,###")

You could write a function to conditionally return one of two format strings:
Function GetFormatString(varValue As Variant) As String
Dim dblValue As Double
If IsNumeric(varValue) Then
dblValue = CDbl(varValue)
If dblValue = Int(dblValue) Then
GetFormatString = "#,###"
Else
GetFormatString = "#,###.00"
End If
End If
End Function
Private Sub Amount_AfterUpdate()
Dim strFormat As String
strFormat = GetFormatString(Me.Amount.Value)
Me.Amount.Value = Format(Me.Amount.Value, strFormat)
End Sub

Related

Vb.net how to get the number after decimal places

in Vb.net how to get the number after decimal places.
I tried below code.
Dim number As Decimal = 143.500
Dim wholePart As Integer = Decimal.Truncate(number)
Dim fractionPart As Decimal = number - wholePart
Dim secondPart3 As Integer
secondPart3 = Replace(fractionPart, "0.", "0")
then the result is coming 500, but when i tried 143.050 its giving 50 it should show 050
Thanks
Thanks everyone. i got it with sample below code
Dim numar As Double
If Double.TryParse(TextBox1.Text, numar) Then
Dim rmndr As Double
rmndr = numar Mod 1
If rmndr = 0 Then
Else
TextBox2.Text = Split(CStr(TextBox1.Text), ".")(1)
End If
End If
Your solution (here) is unnecessarily complex. You were on the right track in your original post, but conflated numeric values with formatted string values. Because while 050 are 50 are the same numeric value, when you implicitly call ToString on the value (or explicitly with the wrong formatting) then you would always get 50 because the prefixing 0 is unnecessary when working with numeric values.
What you should do is:
Get the integral digits of the decimal value
Convert the underlying decimal value to a String
(optionally) Format the String specifying the level of precision
Drop the integral digits off converted string
Here is an example:
Private Function GetFractionalDigits(value As Decimal) As String
Dim integralDigits = Decimal.Truncate(value)
Return value.ToString().Remove(0, integralDigits.ToString().Length + 1)
End Function
Private Function GetFractionalDigits(value As Decimal, precisionSpecifier As Integer) As String
If (precisionSpecifier < 0) Then
Throw New ArgumentOutOfRangeException("precisionSpecifier", "precisionSpecifier cannot be less than 0")
End If
Dim integralDigits = Decimal.Truncate(value)
Return value.ToString("N" & precisionSpecifier).Remove(0, integralDigits.ToString().Length + 1)
End Function
Fiddle: https://dotnetfiddle.net/SBOXG0

VB windows form calculate the digit in a multiline textbox

I want to calculate each line: it's like first line 123*1.616 and the second line 213*1.616, and display each total.
Every number entred in the kilogram textbox will mutiply 1.616 and then show the result in the kati label.
Here is my code:
Private Sub b1_Click(sender As Object, e As EventArgs) Handles b1.Enter
For Each digit In (TextBox1.Text)
total1 = Val(digit) * 1.616
Label9.Text = total1
Next
Label9.Text = total1
End sub
Please help me find some solution or explanation to achieve the output.
This should work
Private FACTOR As Decimal = 1.616
Private SEPARATOR As String = Environment.NewLine
Private Sub b1_Click(sender As Object, e As EventArgs) Handles b1.Click
Label9.Text = TextBox1.Text.
Split({SEPARATOR}, StringSplitOptions.RemoveEmptyEntries).
Select(Function(s1) $"{Decimal.Parse(s1) * FACTOR:0.00#}").
Aggregate(Function(s1, s2) $"{s1}{SEPARATOR}{s2}")
End Sub
Here are the functions in the LINQ
Split makes an array out of each line in the TextBox using SEPARATOR as the delimiter
Select transforms the elements into their value times FACTOR
Aggregate puts the elements back together into a SEPERATOR delimited string
Why didn't your original code work?
You were iterating over each char in the text, and multiplying the char by a float (Option Strict On, as suggested in the comments would have prevented that).
Then in each iteration, you do (simplified) Label9.Text = Val(digit) * 1.616 which overwrites the Label every time.
If you were to step through in debug (also suggested in comments), you would see the Label becoming 1x1.616=1.616, 2x1.616=3.232, 3x1.616=4.848, etc. The result was the very last character in your TextBox, '3', times 1.161 = 4.848. Obviously, this was not what you wanted. You needed to instead iterate over each entire number. The multiline TextBox separates each line with a new line. So we iterate over each line instead.
you can use split string by vbCrLf
Sub main()
Dim multilinetext As String =
"10
20
30
40
50
60"
Dim number_array = multilinetext.Split(vbCrLf)
Dim output As Integer = 0
For Each i In number_array
output += i
Next
Stop
End Sub

tryParse not converting value

I have Option Strict On. The code below does not work when I it is on. I was able to isolate the issue to this line
Decimal.TryParse(lblAnnualMid.Text, decAnnualMid)
Because this line is not changing the value from text to decimal, the rest of my code does not work and my labels display $0.
How can I fix this. I am still feeling my way through VB.Net so if this seems obvious, please forgive me.
Here is the rest of my code:
Option Strict On
Option Explicit On
Public Class frmCustomRanges
'Variables for the MidPoint TextBoxes
Dim decAnnualMid As Decimal
Dim decHourlyMid As Decimal
Private Sub txtRangeSpread_TextChanged(sender As Object, e As EventArgs) Handles txtRangeSpread.TextChanged
'This event runs when the user enters a number in the
'txtRangeSpread text box. The amount is converted to a decimal
'it then calculates the min and max of the range for annual
'and hourly ranges. The ranges change as the user changes the range
'spread.
'Variables for the event
Dim decRangeSpreadResults As Decimal
'Verify entry is numeric
If IsNumeric(txtRangeSpread.Text) Then
'Convert entry to decimal
Dim decRangeSpread As Decimal = Convert.ToDecimal(txtRangeSpread.Text)
'convert the Mid point value to decimal
Decimal.TryParse(lblAnnualMid.Text, decAnnualMid)
'convert range spread value to percentage
decRangeSpreadResults = decRangeSpread / 100
'Display results in dollar string Annual salary
lblAnnualMin.Text = Convert.ToDecimal(decAnnualMid - (decRangeSpreadResults * decAnnualMid)).ToString("C")
lblAnnualMax.Text = Convert.ToDecimal(decAnnualMid + (decRangeSpreadResults * decAnnualMid)).ToString("C")
''Display results in dollar string in Hourly rate
lblHourlyMin.Text = Convert.ToDecimal(decAnnualMid + (decRangeSpreadResults * decAnnualMid) / 52 / 40).ToString("C")
lblHourlyMax.Text = Convert.ToDecimal(decAnnualMid + (decRangeSpreadResults * decAnnualMid) / 52 / 40).ToString("C")
Else
MsgBox("You have entered a non-numeric value. Please check value and enter again", vbCritical, "Input Error")
With txtRangeSpread
.Text = ""
.Focus()
End With
End If
End Sub
what you want in fact would be this
decimal.TryParse("$35,000",NumberStyles.Currency ,null , out test)
ex:
using System;
using System.Globalization;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
decimal test;
Console.WriteLine(decimal.TryParse("$35,000",NumberStyles.Currency ,null , out test));
Console.WriteLine(test);
Console.Read();
}
}
}
more information about NumberStyles
I changed my line to:
Decimal.TryParse(lblAnnualMid.Text.Replace("$", ""), decAnnualMid)
this worked perfect.
thank you all.

Is possible to ignore the TextBox?

I'm creating a program to calculate the average. There are 12 TextBox and I want to create the possibility to leave some fields blank. Now there are only errors and the crash of the program. Is possible to create that?
This is part of code:
ItalianoScritto = (TextBox1.Text)
MatematicaScritto = (TextBox2.Text)
IngleseScritto = (TextBox3.Text)
InformaticaScritto = (TextBox4.Text)
ScienzeScritto = (TextBox5.Text)
FisicaScritto = (TextBox6.Text)
MediaScritto = (ItalianoScritto + MatematicaScritto + IngleseScritto + InformaticaScritto + ScienzeScritto + FisicaScritto) / 6
Label10.Text = Str(MediaScritto)
If i leave blank the textbox1 when I click on the button to calculate the average Vb says Cast not valid from the string "" to type 'Single' and the bar of te textbox1 become yellow
I would do the following:
Iterate over the textboxes and check if you can parse the value into an iteger. If yes, add it to a value list.
Then add all values from that list and divide it by the number of cases.
It is faster than big if-statements and resilient against error
dim TBList as new list(of Textbox)
'add your textboxes to the list here
TbList.add(Textbox1)
...
dim ValList as new List(Of Integer)
for each elem in Tblist
dim value as integer
If integer.tryparse(elem.text,value)=True
ValList.add(Value)
else
'report error or do nothing
end if
next
dim Result as Integer
Dim MaxVal as Integer =0
for each elem in ValList
Maxval +=elem
next
Result = MaxVal / ValList.count
If you need support for point values, just choose double or single instead of Integer.
Also: regardless what you do -CHECK if the values in the textboxes are numbers or not. If you omit the tryparse, somebody will enter "A" and your app will crash and burn
Also: You OPTION STRICT ON!
You just have to check if the TextBox is blank on each one before using the value:
If TextBox7.TextLength <> 0 Then
'Use the value inside
End If
The way to do it depends a lot of your code. You should consider editing your question giving more information (and code) in order to us to help you better.

Decimal places in a number in VB.NET

How do I check how many decimal places a number has in VB.NET?
For example: Inside a loop I have an if statement and in that statement I want to check if a number has four decimal places (8.9659).
A similar approach that accounts for integer values.
Public Function NumberOfDecimalPlaces(ByVal number As Double) As Integer
Dim numberAsString As String = number.ToString()
Dim indexOfDecimalPoint As Integer = numberAsString.IndexOf(".")
If indexOfDecimalPoint = -1 Then ' No decimal point in number
Return 0
Else
Return numberAsString.Substring(indexOfDecimalPoint + 1).Length
End If
End Function
Dim numberAsString As String = myNumber.ToString()
Dim indexOfDecimalPoint As Integer = numberAsString.IndexOf(".")
Dim numberOfDecimals As Integer = _
numberAsString.Substring(indexOfDecimalPoint + 1).Length
Public Shared Function IsInSignificantDigits(val As Double, sigDigits As Integer)
Dim intVal As Double = val * 10 ^ sigDigits
Return intVal = Int(intVal)
End Function
For globalizations ...
Public Function NumberOfDecimalPlaces(ByVal number As Double) As Integer
Dim numberAsString As String = number.ToString(System.Globalization.CultureInfo.InvariantCulture)
Dim indexOfDecimalPoint As Integer = numberAsString.IndexOf(".")
If (indexOfDecimalPoint = -1) Then ' No decimal point in number
Return 0
Else
Return numberAsString.Substring(indexOfDecimalPoint + 1).Length
End If
End Function
Some of the other answers attached to this question suggest converting the number to a string and then using the character position of the "dot" as the indicator of the number of decimal places. But this isn't a reliable way to do it & would result in wildly inaccurate answers if the number had many decimal places, and its conversion to a string contained exponential notation.
For instance, for the equation 1 / 11111111111111111 (one divided by 17 ones), the string conversion is "9E-17", which means the resulting answer is 5 when it should be 17. One could of course extract the correct answer from the end of the string when the "E-" is present, but why do all that when it could be done mathematically instead?
Here is a function I've just cooked up to do this. This isn't a perfect solution, and I haven't tested it thoroughly, but it seems to work.
Public Function CountOfDecimalPlaces(ByVal inputNumber As Variant) As Integer
'
' This function returns the count of deciml places in a number using simple math and a loop. The
' input variable is of the Variant data type, so this function is versatile enougfh to work with
' any type of input number.
'
CountOfDecimalPlaces = 0 'assign a default value of zero
inputNumber = VBA.CDec(inputNumber) 'convert to Decimal for more working space
inputNumber = inputNumber - VBA.Fix(inputNumber) 'discard the digits left of the decimal
Do While inputNumber <> VBA.Int(inputNumber) 'when input = Int(input), it's done
CountOfDecimalPlaces = CountOfDecimalPlaces + 1 'do the counting
inputNumber = inputNumber * 10 'move the decimal one place to the right
Loop 'repeat until no decimal places left
End Function
Simple...where n are the number of digits
Dim n as integer = 2
Dim d as decimal = 100.123456
d = Math.Round(d, n);
MessageBox.Show(d.ToString())
response: 100.12