Wrong Number of Characters returned by Len - vb.net

I am new to VB and have a simple program. I just want the program to display in a message box the number of characters in a long variable. I am using the Len() function. The code is as follows.
Try
Dim num As Long = 1230456985623145
Dim numLength As Long
numLength = Len(num)
MessageBox.Show(numLength.ToString())
Catch ex As Exception
End Try
Simple. However when i run the function, it returns a value of 8 instead of the actual value. Can anyone tell me what i'm doing wrong. Do i need to add anything else to obtain the right value

It should be like this:
Dim num As Long = 1230456985623145
Dim numLength As Long
numLength = Len(num.ToString())
MessageBox.Show(numLength.ToString())
If you forgot to use ToString(), Len function returns the number of bytes required to store the variable, which is 8 because a Long variable requires 8 byte to store.
Definition of Len function in MSDN:
Returns an integer containing either the number of characters in a
string or the nominal number of bytes required to store a variable.
In your original code (before your edit):
You use Name as a parameter in your Len function. Since your code is a WinForm, the Name is a property of the Form. Check the value of the Name using:
MessageBox.Show(Name)
String.Length
Using the Length property of a string is more preferable. Like Adrian Wragg said, it's easier to convert your codes between the languages which are supported by .Net (C#, VB and F#).

Related

"VBA.len" is 4 times slower than "len" (?!) [duplicate]

When I run the following macro:
Sub try()
Dim num As Integer
num = 123
MsgBox Len(num)
MsgBox VBA.Len(num)
End Sub
The first Msgbox displays 2 and the second Msgbox displays 3.
If I remove the first line which says Dim num As Integer, both MsgBoxes display 3.
Can anyone explain why?
Len and LenB are not just ordinary functions, they are keywords, and as such are found on the list of VBA keywords (although LenB is only mentioned after you click through to Len).
Mid would be another example of such keyword disguised as function, whereas e.g. Left isn't on the list at all, because that is just an ordinary function.
It has to be a keyword because one of its jobs is to perform the compile-time task of determining the storage size of a variable. E.g. with private user-defined types, an ordinary function could not do that at all:
Private Type foo
a As Long
b As String
End Type
Sub TestLens()
Dim f As foo
MsgBox Len(f) ' OK
MsgBox VBA.Len(f) ' Compile time error
End Sub
The fact that the object browser brings you to VBA.Len when you press Shift+F2 on that Len(f) is both correct and misleading.
The Len(f) here does not actually call the VBA.Len function that determines the string size, it simply cannot do that because it would require coercing a private struct into a Variant. Instead it calculates the size of foo at compile time and substitutes the result as a literal constant into the executable.
In your example the Len(num) calculates the compile-time size of variable num (which is 2) and substitutes the constant 2 into the resulting object code, whereas VBA.Len(num) packs the value of num into a Variant and passes that variant to VBA.Len where it's further converted to string "123" and the length of that is returned.
It has to do with the way that VB stores integers and how the Len() function handles arguments that are not strings.
When a datatype that is not a string is passed to the Len() function, it returns the nominal number of bytes used to store the data (VB uses 2 bytes to store an integer). See the documentation for the Len function.
The Len() function will automatically cast the variant variable (which is created by assigning a value to a variable without declaring it first) as a string. The return isn't changing because the storage allocation changes (although it does; variants require 16 bytes of storage space, minimum). Since the implicitly declared variable is actually a variant type, VB will automatically change its type based on the situation. In this case, Len() expects a string so VB makes the variable a string.
You could use Msgbox Len(Cstr(num)) to cast the integer variable as a string before passing it to the Len function if your intent is to return the number of characters in your integer value.

How to loop a sub w/ a variable value?

I'm creating a program that outputs a randomly generated password in which the user has jurasdiction over how many characters they want their password to be. How would i go about taking the input from the user and then looping the subroutine (which generates a single random character)? Any help would be much appreciated, thank you!
' this is the code for my input where n = the no. of characters the user wants in their pasword
Public Sub inp()
Console.WriteLine("How many characters do you want in your password?
(up to 20 allowed)")
n = Console.ReadLine()
End Sub
'this is the simple sub that generates a random number from which a character from my database is chosen
Public Sub randi()
Randomize()
i = Rnd() * 92
End Sub
Let us think about the steps envolved.
Ask user for a number
Place the response in a variable.
Create a random string with n characters
I looks like you have taken care of 1 and 2.
Now let's break down number 3 into tasks.
What characters do you want to include.
Uppercase letters? Lowercase letters? Numbers? Punctuation?
An ASCII table will tell you that there are readable characters from ASCII 33 to 126.
If you were to ask for a random number in the range 33 to 126 then change it to the character it represnts, it would be a start.
Luckily .net provides a Random class.
First we will need to get an instance of that class to use its methods.
Private rnd As New Random
Now we have a variable holding an instance of the random class so we can use any of the classed properties and methods.
There is a method, .Next(Int32, Int32), that will produce a random number in a range.
The first parameter is the bottom number in the range and the second is one more than the top number.
Going back to ASCII table we need a random number like this
rnd.Next(33, 125)
Next we need to change the result to a character.
Convert.ToChar(Ascii number)
The next problem is to get the number of characters the user asked for. Remember n.
We can do this is a For...Next loop.
Inside the loop we want to build a string with these random characters. This could be done with an ampersand equals but every time you changes a string the compiler has to throw away the old string and create an entirely new one because strings are immutable. To solve this .net has provided a StringBuilder class. We create an instance of this class and then use the .Append method to add the characters to the sb.
After the loop we change the StringBuilder to a regular string and return it to the calling code.
Public Sub Main()
Console.WriteLine("How many characters do you want in your password?
(up to 20 allowed)")
Dim n As Integer = CInt(Console.ReadLine())
Dim Pword As String = GetRandomString(n)
Console.WriteLine(Pword)
End Sub
Private rnd As New Random
Private Function GetRandomString(stringLength As Integer) As String
Dim sb As New StringBuilder
For c = 1 To stringLength
Dim newAscii = rnd.Next(33, 127)
Dim newChr = Convert.ToChar(newAscii)
sb.Append(newChr)
Next
Return sb.ToString
End Function
In a real application you would have to check if the user entered a valid number. An Integer.TryParse and a check for 0 would probably do it.

Why do Len and VBA.Len return different results?

When I run the following macro:
Sub try()
Dim num As Integer
num = 123
MsgBox Len(num)
MsgBox VBA.Len(num)
End Sub
The first Msgbox displays 2 and the second Msgbox displays 3.
If I remove the first line which says Dim num As Integer, both MsgBoxes display 3.
Can anyone explain why?
Len and LenB are not just ordinary functions, they are keywords, and as such are found on the list of VBA keywords (although LenB is only mentioned after you click through to Len).
Mid would be another example of such keyword disguised as function, whereas e.g. Left isn't on the list at all, because that is just an ordinary function.
It has to be a keyword because one of its jobs is to perform the compile-time task of determining the storage size of a variable. E.g. with private user-defined types, an ordinary function could not do that at all:
Private Type foo
a As Long
b As String
End Type
Sub TestLens()
Dim f As foo
MsgBox Len(f) ' OK
MsgBox VBA.Len(f) ' Compile time error
End Sub
The fact that the object browser brings you to VBA.Len when you press Shift+F2 on that Len(f) is both correct and misleading.
The Len(f) here does not actually call the VBA.Len function that determines the string size, it simply cannot do that because it would require coercing a private struct into a Variant. Instead it calculates the size of foo at compile time and substitutes the result as a literal constant into the executable.
In your example the Len(num) calculates the compile-time size of variable num (which is 2) and substitutes the constant 2 into the resulting object code, whereas VBA.Len(num) packs the value of num into a Variant and passes that variant to VBA.Len where it's further converted to string "123" and the length of that is returned.
It has to do with the way that VB stores integers and how the Len() function handles arguments that are not strings.
When a datatype that is not a string is passed to the Len() function, it returns the nominal number of bytes used to store the data (VB uses 2 bytes to store an integer). See the documentation for the Len function.
The Len() function will automatically cast the variant variable (which is created by assigning a value to a variable without declaring it first) as a string. The return isn't changing because the storage allocation changes (although it does; variants require 16 bytes of storage space, minimum). Since the implicitly declared variable is actually a variant type, VB will automatically change its type based on the situation. In this case, Len() expects a string so VB makes the variable a string.
You could use Msgbox Len(Cstr(num)) to cast the integer variable as a string before passing it to the Len function if your intent is to return the number of characters in your integer value.

convert string to double in vb.net

data table contain column named as Fld_primary. this column contain value like 0.00 it is double datatype in mysql table.i want store that datatable value in double variable. am always getting error when i convert to double datatype.
my code
-------
Dim ds5 As dataset1.DTSUMDataTable = TA5.GetData(users)
Dim dttot As Double
dttot = CType(ds5("fld_primary").ToString, Double)
Error
Conversion from string "fld_primary" to type 'Integer' is not valid.
Edited # 3:01 AM with most recent screen caps.
Sometimes I find myself second guessing certain code based on people's answers, but I went ahead and took the time to check if the code that they are all using is even valid:
As you can see that code is a no go, so I used the correct code you see at the bottom there to reference a column.
However, if you wish to get a single cell use the chunk of code below that uses the foreach loop (the rest is my basic setup to show you how it works):
"Y" will equal the value of the datatable cell and you may convert it using the Double.Parse() method:
Dim y = Double.Parse(zDataRow("cat").ToString())
Be careful, if you have multiple rows you will notice that the value of y will change as it makes its way through all the rows.
you can convert it using the Convert class.
Dim dttot As Double = Convert.ToDouble(ds5("fld_primary"))
Your error is actually: ds5 expects an integer as a parameter, so using ds5("fld_primary") is not valid in your code. Perhaps you can try ds5(0)("fld_primary").
After you fixed it, use
dttot = Double.Parse(whatever_string_you_should_put_here)
If you cannot ensure your string must be a valid double, then use Double.TryParse.
You are better off using the 'Double.TryParse' way of converting as this handles any errors better and simply returns a boolean if succesful or not, using 'parse' will throw an exception which isnt anywhere near as elegant.
Dim dub as Double = 0
Double.TryParse("Your String Here", dub)
Try using Double.TryParse(text,value)
Try using this:
For a=0 to yourgridview.rows.count-1
Yourgridview.rows(a).cells(targetcolumnnumber).value=cdbl(Yourgridview.rows(a).cells(targetcolumnnumber).value)
Next

What is LenB actually doing on none string parameters

I have this bit of code that is being converted from vb6 to vb.net. I need to know what LenB is doing in this bit of code.
Dim singleValue As Single 'var for conversion use(4byte -> 1single)'
Dim bytes() As Byte
Dim valueB() As Byte 'this gets set elsewhere and is redim-d to its size'
For n = 0 To CDbl(ItemNumberCombo.Text) - 1
'bytes() -> single'
'UPGRADE_ISSUE: LenB function is not supported.'
ReDim bytes(LenB(singleValue) - 1)
bytes(3) = valueB(n * 4)
bytes(2) = valueB(n * 4 + 1)
bytes(1) = valueB(n * 4 + 2)
bytes(0) = valueB(n * 4 + 3)
'UPGRADE_ISSUE: LenB function is not supported.'
'UPGRADE_ISSUE: VarPtr function is not supported. '
Call memcpy(VarPtr(singleValue), VarPtr(bytes(0)), LenB(singleValue))
'display the result'
DText(n).Text = VB6.Format(singleValue, "0.000000E+00") 'CStr(singleValue)'
If DataSaveCheckBox.CheckState = 1 And FileNameText.Text <> "" Then
csvOutput = csvOutput & DText(n).Text & ","
End If
Next n
Am I right in thinking that bytes is always ReDim'ed to the same size? By the looks of it 4 elements.
Why then use LenB to ReDim if you could just use a number? And why ReDim in the loop at all?
LenB() returns the length in bytes of a variable. The most common example is for strings, where it returns the size of the string in bytes rather than the number of characters, regardless of character encoding. For other types it returns the size of an object- the size of a single being 4. The reason they would do this is that they wanted the code to survive if a future version of visual basic ever changed the size of a single (never mind hard-coding the number 4 when assigning to the byte array).
When upgrading LenB() to .Net, for strings use System.Text.Encoding.Unicode.GetBytes() to get an array already populated with your string text bytes. Remember that .Net always uses Unicode for strings internally. If you really need a different encoding there are a number of alternatives in the Encoding namespace. For other types use the BitConverter class. Either way, don't go line by line as the newer methods take away a lot of the busy work.
Here — I'll help you out with the conversion some:
(earlier)
Dim csvOutput As New StringBuilder()
(later)
Dim valueB() As Byte 'this gets set elsewhere and is redim-d to its size'
Dim singleValue As Single 'var for conversion
' Included because the original developer was concerned the size of a single could change
Dim singleSize As Integer = BitConverter.GetBytes(singleValue).Length
Dim NumberItems As Double
If Double.TryParse(ItemNumberCombo.Text, NumberItems) Then
For n As Integer = 0 To NumberItems - 1
singleValue = BitConverter.ToSingle(valueB, n * singleSize)
'display the result
DText(n).Text = singleValue.ToString("E6") 'CStr(singleValue)
If DataSaveCheckBox.CheckState = 1 AndAlso Not String.IsNullOrEmpty(FileNameText.Text) Then
csvOutput.Append(DText(n).Text & ",")
End If
Next n
Else
' Handle Invalid ComboBox value here- may not be an issue for you
End If
Note that this code also demonstrates a StringBuilder as a much better way to build your csv data, the AndAlso operator, the .TryParse() methods, String.IsNullOrEmpty(), and Standard Format Strings, all of which are intended to replace constructs or techniques from vb6.
Trying to explain bad code... is just an effort in futility.
Interesting way to fill a Single by loading a byte array.
The LenB function gives you the length in bytes of a variable.
Yes it will always return 4 when passed a Single variable type.
My guess for the redim is so the array gets initialized instead of preserved.
But since it then assigns all 4 bytes, it isn't technically needed and is probably just defensive programming. Defensive programming might also explain the LenB. In case Single changes size in the future.