converting integer to decimal values while adding both - vb.net

I am working on a vb.net application.
My code is the following:
txtTotalPrevious.Text = Val(txtTotalPrevious.Text) + Val(txtoldtotal.text)
my values are:
txtTotalPrevious.Text=187.0000
txtoldtotal=3
I get the result
result =190
but my expected result is:
result=190.0000
What is the issue in my logic?

You can use String.Format if you want to output string be like you want:
Dim str1 As String = "187.0000"
Dim str2 As String = "3"
Dim resultString As String = String.Format("{0:0.0000}", Val(str1) + Val(str2))
' And the result will be 190.0000
And if you want the double result:
Dim resultDouble as Double= Val(str1) + Val(str2)
' And the result will be Double 190
EDIT
Based on varocarbas comments you should consider some notes:
Avoid using Val method
The Val function stops reading the string at the first character it
cannot recognize as part of a number. Symbols and characters that are
often considered parts of numeric values, such as dollar signs and
commas, are not recognized. However, the function recognizes the radix
prefixes &O (for octal) and &H (for hexadecimal). Blanks, tabs, and
linefeed characters are stripped from the argument.
The following call
returns the value 1615198.
Val(" 1615 198th Street N.E.")
The Val function recognizes only the period (.) as a valid decimal
separator. When different decimal separators are used, as in
international applications, use CDbl or CInt instead to convert a
string to a number. To convert the string representation of a number
in a particular culture to a numeric value, use the numeric type's
Parse(String, IFormatProvider) method. For example, use Double.Parse
when converting a string to a Double.
As a VB.Net Programmer use & instead of + for string concatenation
When you use the + operator, you might not be able to determine
whether addition or string concatenation will occur. Use the &
operator for concatenation to eliminate ambiguity and to provide
self-documenting code.

Related

What does concatenating an empty string to a string do?

I've come across this convention in some code I'm editing where they frequently concatenate an empty string to an existing string when assigning it to another variable.
For example:
Dim var1
Dim var2 = "string"
var1 = var2 & ""
I can't think of a reason why they would do this since & already makes the result a string. Is there any reason why this is done?
I can't think of a reason to do it exactly as you show, but this is a pattern you sometimes see used to coerce something into a string type - for example when working with database recordsets:
blah = rs.Fields("foo").Value & ""
where there's a chance that the field value may be null and you just want an empty string instead.
https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/ampersand-operator
If an expression is not a string, it is converted to a String variant.
The data type of result is String if both expressions are string
expressions; otherwise, result is a String variant.
If both expressions are Null, result is Null. However, if only one
expression is Null, that expression is treated as a zero-length string
("") when concatenated with the other expression. Any expression that
is Empty is also treated as a zero-length string.

Formatting Main Part of Number While Keeping the decimal part untouched in VBA

I need to format the main part (whole) of a number without touching or affecting the decimal part:
12345.123456 becomes 12,345.123456
123.123 becomes 123.123
12345678.123 becomes 12,345,678.123
123 becomes 123
The fractional part length is variable in length of decimal places and need to be kept untouched (as is).
The formatting applies only to the whole number. Formatting the whole number is simple, but how to not affect the decimal part.
The Format parameter should work with any length of decimal places.
I am using the following:
Format(123456789.12345,"#,#.#############################")
However, the only problem with this solution is:
There is always an assumption on the maximum possible number of decimal places by the number of # used.
If the number is without a fraction say "123.0" or "123", the output will be "123." always with a decimal separator (dot).
Thanks
Like #nicomp said you'll want to break this into two parts.
dim num as string 'or a double converted to a string
dim nums() as string 'array
num = 123456789.123456
nums = split(num, ".") 'break into array at decimal
nums(0) = format(nums(0), "###,###") 'format whole numbers
num = nums(0) & "." & nums(1) 'recombine
This should add a comma after every three whole numbers

How to split and trim a string in one line

I want to Split a string and then Trim the results in one single line.
So the string:
"psychology ¦ history ¦ geography"
should return the following members without trailing or leading spaces:
psychology
history
geography
I've tried:
String.Split("¦").Trim
but Trim does not work for arrays. Is there a one-line method, no matter how dirty, that does this job?
I'm sure this has been duped many times but I couldn't find the relevant solution for VB.Net. Please don't just link to a question in another language without explaining how I can convert the solution to VB.Net.
You can Split and Trim your string in one line using the LINQ's Select method.
Both assigning the string to a local variable:
Dim input As String = "psychology ¦ history ¦ geography"
Dim result1 = input.Split("¦"c).Select((Function(s) s.Trim))
Or directly using the string as source:
Dim result2 = "psychology ¦ history ¦ geography".Split("¦"c).Select((Function(s) s.Trim))
Note that the Type of result1 and result2 is now an IEnumerable(Of String), not an array:
LINQ's methods return a IEnumerable<T> if not otherwise instructed.
Also note that this syntax supposes that Option Infer is On. If you keep it Off, you need to declare the type explicitly:
Dim result As IEnumerable(Of String) = (...)
If you need a string Array as output, you need to ask:
Dim result3 As String() = input.Split("¦"c).Select((Function(s) s.Trim)).ToArray()
About the Type Characters (c) appended to the Split method parameter:
From the Visual Basic Language Reference: Char Data Type
Type Characters. Appending the literal type character C to a
single-character string literal forces it to the Char data type. Char
has no identifier type character.
If you don't have embedded spaces in the items, you can just pass the space character as a separator as well as pipe. Combine that with the remove empty entries option and multiple space separators aren't an issue. If you need to handle other whitespace characters, you can add those.
input.Split(New String() {"|", " "}, StringSplitOptions.RemoveEmptyEntries)

using IndexOf in Mid function

Perhaps this is a simple solution for most, but I can't get this to work like it should according to syntax.
I have this line of text "Part Number123456Price$50.00"
I want to pull the part number out of it, so I use this function...
str = Mid(str, str.IndexOf("Part Number") + 12, str.IndexOf("Price"))
My results are str = "123456Price$50.0" every time. I know the part number can vary in length so I need a solid solution of pulling this out.
It can be confusing to mix the legacy VB string methods (such as Mid) with the .Net string methods (like IndexOf). The VB methods use 1 as the index of the first character while the .Net methods use 0.
The following code will extract the part number from a string
Dim str As String = "Part Number123456Price$50.00"
Dim iPart As Integer = str.IndexOf("Part Number") + 11
Dim iPrice As Integer = str.IndexOf("Price")
str = str.Substring(iPart, iPrice - iPart).Trim
The Mid() function of Visual Basic is documented as having three arguments: (1) a string, (2) the beginning location in the string, and (3) the number of characters to copy.
So if your string is "Part Number123456Price$50.00" and you want to pull the part number as a series of digits, the "123456" part of the string, using the Mid() function then you need to find the beginning of the part number digit string and to then know the number of digits.
If your string is in the variable str then you can find the offset by something like str.IndexOf("Number") + len("Number") which will provide the offset to after the string "Number".
Next you need to find the number of digits so you would do something like str.IndexOf("Price") to find where the text "Price" begins and then subtract from that offset the offset of where the digits begin.
The result of all of this is you need a bit of code something like the following. I have not tested this source as I am not a VB programmer so it may need a tweak and you might want to put some checks on data validity as well.
Dim TextNumber as String = "Number"
Dim TextPrice as String = "Price"
iOffset = str.IndexOf(TextNumber) + len(TextNumber)
str = Mid(str, iOffset, str.IndexOf(TextPrice) - iOffset)
Alternatively, if Price is always the format $00.00, this will also work.
Dim str as String = "Part Number123456Price$50.00"
str = str.Remove(str.IndexOf("Price"))

Decimal number in CSV file

My application generates CSV file from some objects. These CSV files are used in many countries so I must use correct separator.
To seperate values (cells) in a file I use separator:
Dim separator As String = My.Computer.Info.InstalledUICulture.TextInfo.ListSeparator
This should be OK. But one column contains decimal numbers so I want to be sure that I use correct decimal separator (must be different than list separator).
I am converting decimal value to a string like this:
Dim intValue as Integer = 123456
Dim strValue as String = (intValue / 100).ToString()
In my country a list separator is a semicolon and decimal separator is a comma. In this combination it is OK. But I found out that in some country where the list separator is a comma, decimal separator is comma as well. And this is a problem. How I have to convert a decimal number to string if I want to use correct local decimal separator? Thanks!
How I have to convert a decimal number to string if I want to use
correct local decimal separator?
By default the current culture's separator is used anyway. But you can use the overload of Decimal.ToString that takes a CultureInfo:
Dim localizedNumber = (intValue / 100).ToString( CultureInfo.CurrentCulture )
If you want to use a different culture:
Dim usCulture = new System.Globalization.CultureInfo("en-US")
localizedNumber = (intValue / 100).ToString( usCulture )
If you want to know the decimal separator of a given culture:
Dim separator As String = usCulture.NumberFormat.NumberDecimalSeparator
Edit So your customers don't want to use tab as separator since they have to specify the delimiter manually. You could either generate a real excel-file, for example by using EPPlus which doesn't even need an excel-license or you need to provide another solution.
I have checked it, there are 13 cultures where the decimal-separator is the same as the list-separator (used by excel):
Dim conflictCultures = CultureInfo.GetCultures(CultureTypes.SpecificCultures).
Where(Function(c) c.NumberFormat.NumberDecimalSeparator = c.TextInfo.ListSeparator)
So you have to check it manually and then provide a different list-separator. If decimal/list-separator is comma you can use semicolon as list-separator and vice-versa:
Dim argentinaCulture = New CultureInfo("es-AR") ' uses same separator for both
Dim decimalSeparator = argentinaCulture.NumberFormat.NumberDecimalSeparator ' comma
Dim listSeparator = argentinaCulture.TextInfo.ListSeparator 'comma
If decimalSeparator = listSeparator Then
listSeparator = If(listSeparator = ",", ";", ",")
End If