If I wanted to define a Date literal, I would write the following:
Dim myDate as Date = #1/1/2021#
What character should I use to do an analogous thing for a Currency variable?
That is
Dim amt as Currency = ?200.00?
What character should "?" be when using VBA?
In VBA a declaration cannot legally be joined with an assignment in the same instruction, so that would be:
Dim myDate As Date
myDate = #1/1/2021#
For the sake of this discussion it's important to differentiate the variable from the literal value, because the declared type of the variable is irrelevant to the type of the literal - this is perfectly confusing, but perfectly legal too:
Dim myDate As Long
myDate = #1/1/2021#
We're talking about the literals here.
A numeric literal is an Integer literal if it's between -32767 and 32767, a Long literal if it's between -2147483647 and 2147483647, and a Double otherwise (the VBE automatically adds a # type hint then).
That means the 200 in myAmount = 200 is an Integer literal, and if we typed 200.00 the VBE would "prettify" it to 200# (making it a Double literal).
The type hint character to use for a Currency literal, is #, so the 200 in myAmount = 200# is a Currency value that the VBA compiler understands as such.
It doesn't matter though, because VBA will do lots of widening (narrowing too) implicit type conversions for us: if we assign an Integer literal to a Currency variable, the Integer value is converted to "fit" the reserved Currency "bucket". So if we declared myAmount As Currency and then assigned it to the literal value 200 (an Integer literal), if we asked VBA what type myAmount is, we would get the declared type - Currency.
In other words it's perfectly legal to assign an Integer or a Double literal to a Currency variable, and that makes type-hinted literals somewhat awkward beasts that don't really belong, in the vast majority of situations:
Dim myAmount As Currency
myAmount = 200 'integer literal
Debug.Print TypeName(myAmount) 'currency
myAmount = 200# 'double literal
Debug.Print TypeName(myAmount) 'currency
myAmount = 200# 'currency literal
Debug.Print TypeName(myAmount) 'currency
Things get groovy when we drop the declared type and use a Variant instead (implicit or not):
Dim myAmount 'As Variant
myAmount = 200 'integer literal
Debug.Print TypeName(myAmount) 'integer
myAmount = 200# 'double literal
Debug.Print TypeName(myAmount) 'double
myAmount = 200# 'currency literal
Debug.Print TypeName(myAmount) 'currency
A date literal needs # "delimiters" on both sides, because the / date separator character has another grammatical meaning in VBA (and many other languages too): in other contexts, it's the division operator: in a sense, # delimiters are more closely related to the " double quotes that delimit string literals, than they are to # type hints.
Here is a list of VBA type-declaration characters I collected:
/ means no type-declaration character exists for that datatype.
Also no type-declaration character exists for any composite data types such as arrays or structures.
Type
Type-declaration character
Boolean
/
Byte
/
Currency
#
Date
/
Decimal
/
Double
#
Integer
%
Long
&
LongLong (64-bit VBA only)
^
Object
/
Single
!
String
$
You can prove that for example in die Immediate-Window:
?TypeName(1%) 'Returns Integer
?TypeName(1&) 'Returns Long
?TypeName(1#) 'Returns Currency
?TypeName(1#) 'Returns Double
?TypeName(1^) 'Returns LongLong
?TypeName(1!) 'Returns Single
Related
I am trying to understand code written by someone else, and I came across this>
...
dtStart = #1/1/2022#: Range("I3").Value = dtStart
...
I understand that hash, or number, is used in type declaration double, but this?
Anyone know?
That is just how dates are represented in vba.
Dim x As Variant
x = "1/28/2022"
Debug.Print x, VarType(x)
returns string type.
Dim x As Variant
x = #1/28/2022#
Debug.Print x, VarType(x)
returns date type.
Dim x As Variant
x = 1 / 28 / 2022 'This is NOT the date as a double, it is dividing
Debug.Print x, VarType(x)
returns double type.
A date in VBA is just a fancy double so it makes sense that it would be wrapped in #.
If you take a look at the conversion function docs you can see converting a string to a date isn't recommended. Instead it recommends using these date literals.
I want to check what data type is in: Cells(2, 1).Value i.e. "WHAT GOES HERE?" below.
I tried the names (Integer / Long etc.) but doesn't seem to accept.
If TypeName(Cells(r, 1).Value) = "WHAT GOES HERE?" Then
MsgBox "Yes"
Else
MsgBox "No"
End If
Well a look into MSDN reveals a table of possible return values
String Returned Variable
-------------------------------------------------------------------
Object type An object whose type is objecttype
Byte Byte value
Integer Integer
Long Long integer
Single Single-precision floating-point number
Double Double-precision floating-point number
Currency Currency value
Decimal Decimal value
Date Date value
String String
Boolean Boolean value
Error An error value
Empty Uninitialized
Null No valid data
Object An object
Unknown An object whose type is unknown
Nothing Object variable that doesn't refer to an object
In addition you can also see the above table by using the built-in help (credit goes to Axel Richter). To quickly jump to the according page, select the function and press F1 or navigate to the help page via the object browser like so:
If your cell contains a number, then the likely TypeName is "Double"
If TypeName(Cells(r, 1).Value) = "Double" Then
MsgBox "Yes"
Else
MsgBox "No"
End If
Quick note: You can just try it out. Fill the Cell you want to check with a Value and use
MsgBox TypeName(cells(2, 1).Value)
If the cells is empty, this returns Empty.
If you need the number of the variable from the MSDN Table, then you need VarType.
Like this:
Constant
Value
Description
vbEmpty
0
Empty (uninitialized)
vbNull
1
Null (no valid data)
vbInteger
2
Integer
vbLong
3
Long integer
vbSingle
4
Single-precision floating-point number
vbDouble
5
Double-precision floating-point number
vbCurrency
6
Currency value
vbDate
7
Date value
vbString
8
String
vbObject
9
Object
vbError
10
Error value
vbBoolean
11
Boolean value
vbVariant
12
Variant (used only with arrays of variants)
vbDataObject
13
A data access object
vbDecimal
14
Decimal value
vbByte
17
Byte value
vbLongLong
20
LongLong integer (Valid on 64-bit platforms only.)
vbUserDefinedType
36
Variants that contain user-defined types
vbArray
8192
Array
Then you can simply use:
If VarType(TempArray) = vbObject Then
Or
If VarType(TempArray) = 9 Then
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.
I have a TextBox named ValueText. when i execute the following code:
Dim txtval As Double = 0.0
txtval = Val(ValueText.Text)
txtval = CDbl(ValueText.Text)
Both Val() and CDbl() will do the same work. then what is the difference between these two? where to use Val() and where to use CDbl()
Two subtle differences between the functions:
CDbl("") throws a RTE13 "Type Mismatch" error on a blank/empty string where Val("") returns 0.
CDbl() allows commas as the thousands separator in strings where Val() does not. i.e. CDbl("-1,234.56") = -1234.56 but Val("-1,234.56") = -1
the val() Returns the numbers contained in a string as a numeric value of appropriate type. where as CDbl() will Returns an expression that has been converted to a Variant of subtype Double.
The main difference in its use is that
CDbl() will return Error as Conversion from string "" to type 'Double' is not valid. when The TextBox is blank or Empty.
While Val() will give 0.0 in the above situation
I have a string which was converted to a char array and stored in a stringcollection, how do I return the numerical value for the character in each string? How can I reverse this process, getting the character from the numerical value?
I know I could code a Select Case statement, but that would take a very long time as I need to cover every character a person could want to conceivably use in the English language, including punctuation.
Is there already a method built into vb.net for doing this?
Thanks for the help!
The Convert class has methods that can convert between characters and integers:
Dim c As Char = "A"C
Dim i As Integer = Convert.ToInt32(c)
Dim c2 As Char = Convert.ToChar(i)
To loop the values converted from the characters in a string into an array of integers:
Dim codes(theString.Length - 1) As Integer
For i As Integer = 0 to theString.Length - 1
codes(i) = Convert.ToInt32(theString.Chars(i))
Next
Try something like this:
For Each c As Char In yourString
Dim i As Int32 = DirectCast(c, Int32)
Next
Remeber that System.String implements IEnumerable<Char> so it is legal to For Each over it. And converting between a character and a number is as simple as casting between System.Char and System.Int32 (here I have shown how to get the numeric value for each character in the string).