what is the meaning of the dollar sign after a method name in vb.net - vb.net

what is the meaning of the dollar sign after a method name in vb.net
like this:
Replace$("EG000000", "0", "")

Old type notifier - see this
Some other old ones:
& -> Long
% -> Integer
# -> Double
! -> Single
# -> Decimal
$ -> String
Still exist in VB.Net for the sake of backward compatibility...

In "classic" VB, there were two versions of the built in-string functions. Let me use Left as an example:
Left(s, length) takes a variant as the first parameter and returns a variant.
Left$(s, length) takes a string as the first parameter and returns a string.
This distinction still exists in modern-day VBA.
I suspect that the reason behind this is that strings in VBA cannot be Null (note that Null <> ""). Thus, when dealing with nullable database fields, you had to use variant variables. Variant variables can take any value, including all of the integral values (strings, integers, ...) as well as some special values such as Null, Empty or Missing. The non-$ functions allowed you to use variants as input and get variants as output. For example, Left(Null, ...) returns Null.
In VB.NET, this distinction is no longer necessary: The non-$ functions do exactly the same as the $ functions, which are kept only for backwards compatibility with old code.

What Heinzi said and to clear up the type character business
Dim s$ = "FooBar" 'dim s as String = "FooBar"
Dim r As String
Stop
r = Replace$(s, "Bar", "")
'.Net equivalent
r = s.Replace("Bar", "")

Related

IsNumeric() allowing minus at last of the values

I am using IsNumeric() function in my code to validate numbers.
IsNumeric(100) - true,
IsNumeric(-100) - true,
IsNumeric(+100) - true,
IsNumeric(100-) - true - I have doubt in this. (100-) Is this a valid number? IsNumeric () returns true to this value.
Dim latitude As String = "12.56346-"
If IsNumeric(latitude) Then
If (Convert.ToDouble(latitude) >= -90 And Convert.ToDouble(latitude) <= 90) Then
isValidLatitude.Text = "true"
Else
isValidLatitude.Text = "false"
End If
Else
isValidLatitude.Text = "false"
End If
Error while converting latitude to double
Input string was not in a correct format.
IsNumeric is from the Microsoft.VisualBasic namespace/dll, a bunch of helper stuff intended to help VB6 programmers get their arcane VB6 code /knowledge working on VB.NET
You'll note if you use other functions from the same dll such as Microsoft.VisualBasic.Conversion.Int(), or you use dedicated VB.NET converters such as CInt or CDbl these will also cope with a trailing minus sign and return a negative value
If you want to dispense with the old ways of VB6, use a numeric type's TryParse.. but all in, be consistent / if you use a function from Microsoft.VisualBasic to determine if a conversion can be made, use the vb conversion because within itself the package will be consistent but between Microsoft.VB and normal .net System there are some differences in behavior
Edit:
A couple of people have been wondering about the source code and how it uses TryParse, so why doesn't it work like using TryParse directly?
Microsoft.VisualBasic.Information.IsNumeric() uses Microsoft.VisualBasic.CompilerServices.DoubleType.TryParse() to determine whether an expression is numeric. This DoubleType.TryParse is not the same as Double.TryParse - it is a helper method again in the VB namespace that specifically sets the NumberStyles.AllowTrailingSign flag among many other flags. When parsing the number (first as non currency related, using Double.Parse, then if it fails a second attempt is made using adjusted values for currency related tests) this AllowTrailingSign flag will be considered in conjunction with other regional number formatting rules in determining if the passed in value is numeric
You'll note that on a machine obeying a USA number formatting culture, a string of "(100$)" is also declared to be numeric but calling Double.TryParse("(100$)", x) will also return false. The VB helper methods here are being a lot more liberal in what they accept than the System methods, because they're telling the System methods to be more liberal than they are by default
As noted, I've always regarded the Microsoft.VisualBasic namespace as a bunch of helper methods intended to allow terrible old VB6 code to be pasted into VB.NET and work with minimal fiddling. I wouldn't advocate using it for new projects and I remove the reference when I work on VB.NET - using it to support the VB6 notions of "just sling anything in, of any type, and it'll probably figure it out and work.. and if it doesn't we can always on error resume next" should be discarded in favour of precise and accurate about the operations executed and their intent
Note: my previous answers were wrong about assuming it was a bug. As the answer of #Damien_The_Unbeliever states, this function tries to validate the string as a lot of data types. And actually, the value "100-" is a valid Decimal number. That's why it returns true (as it's a "valid" Decimal) but gives a exception when converting to Double (as it's not a valid Double). #Damien_The_Unbeliever really deserves your +1 for pointing that.
From the documentation (showing all the data types that IsNumeric tries to validate):
IsNumeric returns True if the data type of Expression is Boolean, Byte, Decimal, Double, Integer, Long, SByte, Short, Single, UInteger, ULong, or UShort. It also returns True if Expression is a Char, String, or Object that can be successfully converted to a number. Expression can contain non-numeric characters. IsNumeric returns True if Expression is a string that contains a valid hexadecimal or octal number. IsNumeric also returns True if Expression contains a valid numeric expression that begins with a + or - character or contains commas.
Also, #CaiusJard did a nice search and pointed out that inner methods use a NumberStyles.AllowTrailingSign option, which allows this behavior.
Ok, now to the solution:
Just use a TryParse method, from your desired data type (int, long, etc...). The cool thing is that it'll behaves exactly as you expect, and if the parsing is successful, we have the parsed value already available to use!
if (Int32.TryParse(value, out int number))
{
// String is a valid number, and is already parsed in the 'number' variable!
}
else
{
// String is not a valid number!
}
Solution's VB.Net version:
Dim value As String = "12.56346-"
Dim number As Double = 0
If Double.TryParse(value, number) Then
' String is a valid number, and is already parsed in the "number" variable!
isValidLatitude.Text = "true"
Else
' String is not a valid number!
isValidLatitude.Text = "false"
End If
IsNumeric answers a question no sane person wants to ask. As quoted by Vitox's answer:
IsNumeric returns True if the data type of Expression is Boolean, Byte, Decimal, Double, Integer, Long, SByte, Short, Single, UInteger, ULong, or UShort. It also returns True if Expression is a Char, String, or Object that can be successfully converted to a number.
Note, it doesn't tell you that the given string can be converted to all numeric types. It tells you that the string can be converted to at least one numeric type. And for bonus bad style points, of course, it doesn't tell you which types the string can be converted to.
Decimal.Parse("100-") will execute perfectly well and give you a Decimal containing a value of -100.
So, it's not a bug, it's a bad function that has been retained for backwards compatibility reasons. Nowadays, we know better, and that we want to test whether a string can be converted to a specific data type, for which the TryParse family of functions have been designed.

CDec doesn't return the correct value

I make code that multiply all values of a DatagridView column. The code is working, but there's a problem. In particular, I've added this:
Return CDec(x.Cells("Quote").Value.ToString.Replace(",", "."))
That returns me the split value, for example, if I would have:
2,7 the correct value to return is: 2.7, but the code returns 27 and this is strange. I performed some trying, and if I delete the CDec like:
Return x.Cells("Quote").Value.ToString.Replace(",", ".")
The value returned is correct, but I've a contrast with this function:
Private Function MultiplyDecimals(ByVal sender As Decimal()) As Decimal
Dim Result As Decimal
If Not sender Is Nothing AndAlso Not sender.Length = 0 Then
Result = sender.Aggregate(Function(a, b) a * b)
End If
Return Result
End Function
That returns me 0 if I delete "As Decimal". So what's wrong?
UPDATE with possible solution:
Dim bles = x.Cells("Quote").Value.ToString.Replace(",", ".")
Dim key = Convert.ToDecimal(bles)
MessageBox.Show(key)
Return CDec(key)
Since it looks like you are also trying to manually convert from a different culture, you should use the .NET methods for this, rather than roll your own. You have two conversions going on: From one cultural number system to another and from string to a numeric type.
To convert a string like "2,7" which might be a French or Italian value:
Dim str As String = "2,7"
Dim decVal As Decimal
If Decimal.TryParse(str, NumberStyles.AllowDecimalPoint,
New CultureInfo("it-IT"), decVal) Then
' decVal has the value
Else
' Parse failed
End If
or:
Dim cult As New CultureInfo("fr-FR")
If Decimal.TryParse(str, NumberStyles.AllowDecimalPoint,
cult, decVal) Then ...
This can often work, but you might get an exception depending on the content:
Dim decVal As Decimal
Dim cult As New CultureInfo("fr-FR")
decVal = Convert.ToDecimal(str, cult)
Console.WriteLine(decVal.ToString)
Note: I am guessing at the culture of the data. Based on your recent, related question Google indicates "Nazione" is Italian, but data from/about Algeria might well be French Algerian.
CDec, like most of the legacy VB functions, is only equipped to work with the active culture settings. So, it will seem like it is "broken" in some cases:
Console.WriteLine(CDec("2.7")) ' --> 2.7D US/Can
Console.WriteLine(CDec("2,7")) ' --> 27D
Console.WriteLine(CDec("2,,7")) ' --> 27D
On a machine using French or Italian culture, the opposite will happen: "2.7" will come out 27, "2,7" to 2.7D, but "2,,7" will probably crash just like "2..7" would in the US/Can.
The reason for this behavior is that in US/Can, a comma looks like noise and CDec ignores it. A string with a single decimal-dot will convert, but a string with 2 is invalid. It would be the reverse for French where the comma is used: any number of dots look like noise, and only single decimal-comma format will parse.
It is all part of the reason no one included CDec in the solution: It is sub-optimal for any sort of cultural conversions. Manually removing or replacing decimal markers is even less optimal when there are methods designed to do that only when needed.
Since you have a string value, try Decimal.Parse() instead of CDec().
If that doesn't give you the result you expect, then either you're not handling the string that you think you are (in which case, try logging the exact string to a text file or similar so you can see exactly what you have), or the PC's culture settings are not what you think they are (it may be set to a culture that uses the comma, rather than a period, as the decimal separator), in which case try one of the Decimal.Parse() overloads that allows you to specify the culture, or perhaps even just remove the call to .Replace().

Log() behaviour and number# notation

Below example from Excel Help about VBA Log function, notation number# makes conversion of numberinto decimal data type, but makes it any difference for Log function if it takes 10 instead of 10# as an argument ?
Static Function Log10(X)
Log10 = Log(X) / Log(10#)
End Function
To explain why it won't make a difference I need to explain how type conversion is handled in VBA.
In VBA, by default types are attempted to be implicitly converted to the type required by a function/operation, using the default conversions based on your system locale (the system locale bit has meaning when it comes to dates and converting numbers as strings to a numeric type and vice versa).
Consider:
Dim aNumber As Integer, aString As String
aString = 1 & 2
aNumber = aString
aNumber = aString + 1
MsgBox aNumber
In the above, the numbers 1 and 2 are implicitly converted to strings. As system locale doesn't matter when dealing with integral types, aString subsequently is storing "12". Assigning a string to a number results in the string being implicitly converted to a number, so aNumber subsequently is 12, then 13 after the addition. Calling MsgBox passing in a number will result in the number being converted to a string before it is passed in.
Implicit type conversion like the above cannot be disabled in VBA, unlike in VB that has the Option Strict directive.
So, for your Log question above, an integral type passed in will be implicitly converted to a double before actually being passed in. Passing in e.g. 10# compared to 10 will save the conversion (an utterly irrelevant performance consideration) but otherwise is semantically equivalent.

VBA: Does Str(myString) do the same as Str(CDbl(myString))?

Question: Can I assume that Str(myString) will always return the same result as Str(CDbl(myString)) (assuming that myString is statically typed as a string)?
Context:
I am trying to understand VBA's implicit conversions. So far, it appears to me that Str(myString)
implicitly parses myString into a double (culture-sensitive) and then
converts the result into a culture-insensitive string.
For example, using a German locale (i.e. using , as the decimal separator), it holds that
" 1.2" = Str(1.2) = Str("1,2") = Str(CDbl("1,2"))
Since these implicit conversions contain a lot of "magic" to me, I am trying to rewrite a procedure that uses an implicit conversion (Str(myString)) to one using explicit conversion without changing the behavior.
Unfortunately, the documentation is wrong and, thus, useless. (The documentation claims that the argument to Str is interpreted as a Long, which is obviously rubbish: If that were the case Str(1.2) could never yield " 1.2".)
Your statement is true. Str(x) and Str(Cdbl(x)) give identical result provided that x is String data type and contains a valid number.
I made a small test to get convinced.
I used Excel, but it holds the same with Access.
Public Function myStr(txt As String) As String
myStr = Str(txt)
End Function
Public Function myStrCDbl(txt As String) As String
myStrCDbl = Str(CDbl(txt))
End Function
I tried with some key values (0, 1.2, 1E+307, 1E-307, ...) : result of myStr and myStrCDbl are always identical.
I also agree with you that the documentation is wrong. If Str() argument would be interpreted as Long, then Str(1.2) would give "1", because Long is an integer type.
In the mean time, I've found the VBA language specification and can confirm that the spec also answers the question with "yes":
CDbl, when receiving a string, performs a Let-coercion to Double:
If the value of Expression is not an Error data value return the Double data value that is the result of Expression being Let-coerced to Double.
Str, when receiving a string, first performs a Let-coercion to Double and then applies Str:
[If Number is a String,] the returned value is the result of the Str function applied to the result of Let-coercing Number to Double.

CStr() vs. Str() vs. .ToString()

I want to know what exactly are the differences between CStr(), Str() and .ToString()?
Label1.Text = CStr(Int(Rnd() * 10))
and
Label1.Text = Str(Int(Rnd() * 10))
and
Label1.Text = Int(Rnd() * 10).ToString
If I use this condition:
If Label1.Text = "7" Then
'Some code here
End If
Str() doesn't work here. What's the difference?
ToString will call the .ToString() function on a particular instance.
In practice, this means that it will throw an exception if the object in
question is Nothing. However, you can implement .ToString() in your own
classes to get a useful string representation of your object, whereas
CType/CStr only work with built-in classes and interfaces.
CStr and CType(expression, String) are exactly equivalent (I'm not
sure where the other poster got the idea that CStr is faster). But they
aren't really functions, they're compiler directives that will emit very
different code depending on the declaration of expression. In most
cases, these directives call a bunch of internal VB code that tries to
get a reasonable string out of expression.
DirectCast(expression, String) assumes that the expression in
question really is a String and just casts it. It's the fastest of all
these options, but will throw an exception if expression is anything
other than a String.
As an Addition to the VBA/VB6 Environment where we have no ToString():
Str() is not aware of international representation. The decimal separator always is a dot (.).
As already mentioned above it prefixes the resulting string with a blank in case of positive values.
There also exists Str$(). The difference to Str() is the return type:
Str() returns a variant of type string, Str$() returns a string.
And Str$() is slightly faster then Str().
CStr() in contrast is aware of international representation. The decimal separator depends on the Windows international settings.
No additional prefixing for positive values will be done.
So if you need to convert a value type to a string and have to ensure a dot as a decimal separator and no prefixing blank, then use this syntax:
Dim d As Double
d = 123.456
Dim s As String
s = Trim(Str$(d))
I don't know about ToString() and i don't know about VB.NET
But in VB6 (Visual Basic 6):
Both of Cstr() and Str() converts values to string. but Cstr() is better because:
Str(): After converting to string it adds 1 space before positive numbers. for example: Str(22) > " 22"
Cstr(): After converting to string it never adds the above extra space - For best result use it with Trim() - Trim(Cstr(Variable))
Although not a problem in the code in the question, it is important to mention that Str() only converts numerical expressions to string, gives an error in other cases, so don't use it for converting values of a cell.
My answer is str() is evil as it always prepends a space for the sign character so if you are comparing values it fails. Instead use CStr() instead which does not do this.
You may comes across business logic that tries to do this:
Eg:
Dim sVar as String = "1"
Dim i as Integer = 1
console.write( cstr(i) = sVar )
Which outputs:
False
I lost a couple hours on this one as the code was quite deep in old code and was very difficult to grok in production environment where logging based debugging was all that was available.