VBA
Tipos de datos y límites
Buscar..
Byte
Dim Value As Byte
Un byte es un tipo de datos de 8 bits sin firmar. Puede representar números enteros entre 0 y 255 y tratar de almacenar un valor fuera de ese rango dará como resultado un error de tiempo de ejecución 6: Overflow
. Byte es el único tipo sin signo intrínseco disponible en VBA.
La función de conversión para convertir a un byte es CByte()
. Para las conversiones de tipos de punto flotante, el resultado se redondea al valor entero más cercano con .5 redondeo hacia arriba.
Byte Arrays y cadenas
Las cadenas y las matrices de bytes se pueden sustituir entre sí mediante una asignación simple (no se requieren funciones de conversión).
Por ejemplo:
Sub ByteToStringAndBack()
Dim str As String
str = "Hello, World!"
Dim byt() As Byte
byt = str
Debug.Print byt(0) ' 72
Dim str2 As String
str2 = byt
Debug.Print str2 ' Hello, World!
End Sub
Para poder codificar caracteres Unicode , cada carácter de la cadena ocupa dos bytes en la matriz, con el byte menos significativo primero. Por ejemplo:
Sub UnicodeExample()
Dim str As String
str = ChrW(&H2123) & "." ' Versicle character and a dot
Dim byt() As Byte
byt = str
Debug.Print byt(0), byt(1), byt(2), byt(3) ' Prints: 35,33,46,0
End Sub
Entero
Dim Value As Integer
Un entero es un tipo de datos firmado de 16 bits. Puede almacenar números enteros en el rango de -32,768 a 32,767 y tratar de almacenar un valor fuera de ese rango resultará en un error de tiempo de ejecución 6: Desbordamiento.
Los enteros se almacenan en la memoria como valores little-endian con negativos representados como un complemento de dos .
Tenga en cuenta que, en general, es una mejor práctica utilizar un tipo Long en lugar de un Integer, a menos que el tipo más pequeño sea miembro de un Tipo o sea requerido (ya sea por una convención de llamada de API o por alguna otra razón) para que sea de 2 bytes. En la mayoría de los casos, VBA trata a los enteros como 32 bits internamente, por lo que generalmente no hay ninguna ventaja al usar el tipo más pequeño. Además, hay una penalización en el rendimiento en la que se incurre cada vez que se usa un tipo Integer, ya que se lanza silenciosamente como un Long.
La función de conversión para convertir a un entero es CInt()
. Para las conversiones de tipos de punto flotante, el resultado se redondea al valor entero más cercano con .5 redondeo hacia arriba.
Booleano
Dim Value As Boolean
Un booleano se utiliza para almacenar valores que pueden representarse como Verdadero o Falso. Internamente, el tipo de datos se almacena como un valor de 16 bits con 0 que representa Falso y cualquier otro valor que representa Verdadero.
Se debe tener en cuenta que cuando un valor booleano se convierte en un tipo numérico, todos los bits se establecen en 1. Esto da como resultado una representación interna de -1 para los tipos con signo y el valor máximo para un tipo sin signo (Byte).
Dim Example As Boolean
Example = True
Debug.Print CInt(Example) 'Prints -1
Debug.Print CBool(42) 'Prints True
Debug.Print CByte(True) 'Prints 255
La función de conversión para convertir a un Booleano es CBool()
. Aunque se representa internamente como un número de 16 bits, la conversión a un valor booleano desde valores fuera de ese rango está a salvo del desbordamiento, aunque establece todos los 16 bits en 1:
Dim Example As Boolean
Example = CBool(2 ^ 17)
Debug.Print CInt(Example) 'Prints -1
Debug.Print CByte(Example) 'Prints 255
Largo
Dim Value As Long
A Long es un tipo de datos firmado de 32 bits. Puede almacenar números enteros en el rango de -2,147,483,648 a 2,147,483,647 y tratar de almacenar un valor fuera de ese rango resultará en un error de tiempo de ejecución 6: Desbordamiento.
Los largos se almacenan en la memoria como valores little-endian con negativos representados como un complemento de dos .
Tenga en cuenta que dado que un Largo coincide con el ancho de un puntero en un sistema operativo de 32 bits, los Largos se usan comúnmente para almacenar y pasar punteros hacia y desde las funciones API.
La función de conversión para convertir a un largo es CLng()
. Para las conversiones de tipos de punto flotante, el resultado se redondea al valor entero más cercano con .5 redondeo hacia arriba.
Soltero
Dim Value As Single
Un Single es un tipo de datos de punto flotante de 32 bits firmado. Se almacena internamente utilizando un diseño de memoria IEEE 754 little-endian . Como tal, no hay un rango fijo de valores que pueda representarse por el tipo de datos; lo que está limitado es la precisión del valor almacenado. Un Single puede almacenar valores de valores enteros en el rango de -16,777,216 a 16,777,216 sin pérdida de precisión. La precisión de los números de punto flotante depende del exponente.
Un solo se desbordará si se le asigna un valor mayor que aproximadamente 2 128 . No se desbordará con exponentes negativos, aunque la precisión utilizable será cuestionable antes de que se alcance el límite superior.
Al igual que con todos los números de punto flotante, se debe tener cuidado al hacer comparaciones de igualdad. La mejor práctica es incluir un valor delta apropiado para la precisión requerida.
La función de conversión para convertir a un solo es CSng()
.
Doble
Dim Value As Double
Un doble es un tipo de datos de punto flotante de 64 bits firmado. Al igual que el Single , se almacena internamente utilizando un diseño de memoria IEEE 754 little-endian y se deben tomar las mismas precauciones con respecto a la precisión. Un Double puede almacenar valores enteros en el rango de -9,007,199,254,740,992 a 9,007,199,254,740,992 sin pérdida de precisión. La precisión de los números de punto flotante depende del exponente.
Un doble se desbordará si se le asigna un valor mayor que aproximadamente 2 1024 . No se desbordará con exponentes negativos, aunque la precisión utilizable será cuestionable antes de que se alcance el límite superior.
La función de conversión para convertir a un doble es CDbl()
.
Moneda
Dim Value As Currency
Una moneda es un tipo de datos de punto flotante con signo de 64 bits similar a un doble , pero escalado en 10,000 para dar una mayor precisión a los 4 dígitos a la derecha del punto decimal. Una variable de moneda puede almacenar valores desde -922,337,203,685,477.5808 hasta 922,337,203,685,477.5807, lo que le otorga la mayor capacidad de cualquier tipo intrínseco en una aplicación de 32 bits. Como lo indica el nombre del tipo de datos, se considera la mejor práctica usar este tipo de datos cuando se representan cálculos monetarios, ya que la escala ayuda a evitar errores de redondeo.
La función de conversión para convertir a una moneda es CCur()
.
Fecha
Dim Value As Date
Un tipo de fecha se representa internamente como un tipo de datos de coma flotante de 64 bits con signo con el valor a la izquierda del punto decimal que representa el número de días desde la fecha de época de 30 de diciembre de 1899 (aunque véase la nota a continuación). El valor a la derecha del decimal representa la hora como un día fraccionario. Por lo tanto, una fecha entera tendría un componente de hora de 12:00:00 AM y x.5 tendría un componente de hora de 12:00:00 PM.
Los valores válidos para fechas están entre el 1 de enero de 100 y 31 de diciembre de 9999. Desde una doble tiene un alcance más amplio, es posible desbordamiento de una fecha mediante la asignación de valores fuera de ese rango.
Como tal, se puede usar indistintamente con los cálculos de Doble para la fecha:
Dim MyDate As Double
MyDate = 0 'Epoch date.
Debug.Print Format$(MyDate, "yyyy-mm-dd") 'Prints 1899-12-30.
MyDate = MyDate + 365
Debug.Print Format$(MyDate, "yyyy-mm-dd") 'Prints 1900-12-30.
La función de conversión para convertir a una Fecha es CDate()
, que acepta cualquier tipo de representación numérica de fecha / hora de cadena. Es importante tener en cuenta que las representaciones de cadena de las fechas se convertirán en función de la configuración regional actual en uso, por lo que se deben evitar los lanzamientos directos si se pretende que el código sea portátil.
Cuerda
Una cadena representa una secuencia de caracteres y viene en dos sabores:
Longitud variable
Dim Value As String
Una cadena de longitud variable permite agregar y truncar y se almacena en la memoria como un COM BSTR . Consiste en un entero sin signo de 4 bytes que almacena la longitud de la cadena en bytes seguidos por los propios datos de cadena como caracteres anchos (2 bytes por carácter) y terminados con 2 bytes nulos. Por lo tanto, la longitud máxima de la cadena que puede ser manejada por VBA es 2,147,483,647 caracteres.
El puntero interno a la estructura (recuperable por la función StrPtr()
) apunta a la ubicación de la memoria de los datos , no al prefijo de longitud. Esto significa que una cadena de VBA se puede pasar directamente a las funciones de la API que requieren un puntero a una matriz de caracteres.
Debido a que la longitud puede cambiar, VBA reasigna la memoria para una Cadena cada vez que se asigna la variable , lo que puede imponer penalizaciones de rendimiento para los procedimientos que las alteran repetidamente.
Longitud fija
Dim Value As String * 1024 'Declares a fixed length string of 1024 characters.
Las cadenas de longitud fija se asignan a 2 bytes para cada carácter y se almacenan en la memoria como una simple matriz de bytes. Una vez asignada, la longitud de la Cadena es inmutable. No están terminación nula en la memoria, por lo que una cadena que se llena la memoria asignada con caracteres que no son nulos no es adecuado para pasar a funciones API esperan una cadena terminada en nulo.
Las cadenas de longitud fija superan una limitación del índice de 16 bits heredado, por lo que solo pueden tener hasta 65.535 caracteres de longitud. El intento de asignar un valor más largo que el espacio de memoria disponible no generará un error de tiempo de ejecución; en su lugar, el valor resultante simplemente se truncará:
Dim Foobar As String * 5
Foobar = "Foo" & "bar"
Debug.Print Foobar 'Prints "Fooba"
La función de conversión para convertir a una cadena de cualquier tipo es CStr()
.
Largo largo
Dim Value As LongLong
A LongLong es un tipo de datos firmado de 64 bits y solo está disponible en aplicaciones de 64 bits. No está disponible en aplicaciones de 32 bits que se ejecutan en sistemas operativos de 64 bits. Puede almacenar valores enteros en el rango de -9,223,372,036,854,775,808 a 9,223,372,036,854,775,807 y tratar de almacenar un valor fuera de ese rango resultará en un error de tiempo de ejecución 6: Desbordamiento.
Los LongLongs se almacenan en la memoria como valores little-endian con negativos representados como un complemento de dos .
El tipo de datos LongLong se introdujo como parte del soporte del sistema operativo de 64 bits de VBA. En aplicaciones de 64 bits, este valor se puede utilizar para almacenar y pasar punteros a API de 64 bits.
La función de conversión para convertir a un LongLong es CLngLng()
. Para las conversiones de tipos de punto flotante, el resultado se redondea al valor entero más cercano con .5 redondeo hacia arriba.
Variante
Dim Value As Variant 'Explicit
Dim Value 'Implicit
Una variante es un tipo de datos COM que se utiliza para almacenar e intercambiar valores de tipos arbitrarios, y cualquier otro tipo en VBA se puede asignar a una variante. Las variables declaradas sin un tipo explícito especificado por As [Type]
defecto a Variant.
Las variantes se almacenan en la memoria como una estructura VARIANTE que consta de un descriptor de tipo de byte ( VARTYPE ) seguido de 6 bytes reservados y luego un área de datos de 8 bytes. Para los tipos numéricos (incluidos Date y Boolean), el valor subyacente se almacena en la propia Variant. Para todos los demás tipos, el área de datos contiene un puntero al valor subyacente.
El tipo subyacente de una Variante se puede determinar con la función VarType()
que devuelve el valor numérico almacenado en el descriptor de tipo, o la función TypeName()
que devuelve la representación de la cadena:
Dim Example As Variant
Example = 42
Debug.Print VarType(Example) 'Prints 2 (VT_I2)
Debug.Print TypeName(Example) 'Prints "Integer"
Example = "Some text"
Debug.Print VarType(Example) 'Prints 8 (VT_BSTR)
Debug.Print TypeName(Example) 'Prints "String"
Debido a que las Variantes pueden almacenar valores de cualquier tipo, las asignaciones de literales sin sugerencias de tipo se convertirán implícitamente a una Variante del tipo apropiado de acuerdo con la siguiente tabla. Los literales con sugerencias de tipo se convertirán a una Variante del tipo indicado.
Valor | Tipo resultante |
---|---|
Valores de cadena | Cuerda |
Números de punto no flotante en rango Integer | Entero |
Números de punto no flotante en largo alcance | Largo |
Números de punto no flotante fuera de largo alcance | Doble |
Todos los números de punto flotante | Doble |
Nota: A menos que haya una razón específica para usar una Variante (es decir, un iterador en un bucle For Each o un requisito de API), el tipo generalmente se debe evitar para las tareas de rutina por las siguientes razones:
- No son de tipo seguro, lo que aumenta la posibilidad de errores de tiempo de ejecución. Por ejemplo, una Variante que contiene un valor Integer se convertirá silenciosamente en un Largo en lugar de desbordarse.
- Introducen la sobrecarga de procesamiento al requerir al menos una desreferencia de puntero adicional.
- El requisito de memoria para una Variante es siempre al menos 8 bytes más alto que el necesario para almacenar el tipo subyacente.
La función de conversión para convertir a una variante es CVar()
.
LongPtr
Dim Value As LongPtr
El LongPtr se introdujo en VBA para admitir plataformas de 64 bits. En un sistema de 32 bits, se trata como un sistema Long y en sistemas de 64 bits se trata como un LongLong .
Su uso principal es proporcionar una forma portátil para almacenar y pasar punteros en ambas arquitecturas (consulte Cambiar el comportamiento del código en tiempo de compilación .
Aunque el sistema operativo lo trata como una dirección de memoria cuando se usa en llamadas a la API, se debe tener en cuenta que VBA lo trata como un tipo firmado (y, por lo tanto, está sujeto a desbordamiento firmado y no firmado). Por esta razón, cualquier aritmética de punteros realizada con LongPtrs no debe usar comparaciones >
o <
. Esta "peculiaridad" también hace posible que agregar desplazamientos simples que apuntan a direcciones válidas en la memoria puede causar errores de desbordamiento, por lo que se debe tener cuidado al trabajar con punteros en VBA.
La función de conversión para convertir a un LongPtr es CLngPtr()
. Para las conversiones de tipos de punto flotante, el resultado se redondea al valor entero más cercano con .5 redondeo hacia arriba (aunque como es generalmente una dirección de memoria, usarlo como un objetivo de asignación para un cálculo de punto flotante es, en el mejor de los casos, peligroso).
Decimal
Dim Value As Variant
Value = CDec(1.234)
'Set Value to the smallest possible Decimal value
Value = CDec("0.0000000000000000000000000001")
El tipo de datos Decimal
solo está disponible como subtipo de Variant
, por lo que debe declarar cualquier variable que deba contener un Decimal
como Variant
y luego asignar un valor Decimal
mediante la función CDec
. La palabra clave Decimal
es una palabra reservada (lo que sugiere que VBA eventualmente agregará soporte de primera clase para el tipo), por lo que el Decimal
no se puede usar como una variable o nombre de procedimiento.
El tipo Decimal
requiere 14 bytes de memoria (además de los bytes requeridos por la variante principal) y puede almacenar números con hasta 28 decimales. Para los números sin ningún lugar decimal, el rango de valores permitidos es de -79,228,162,514,264,337,593,550,335 a +79,228,162,514,264,337,593,543,950,335 inclusive. Para los números con el máximo de 28 decimales, el rango de valores permitidos es de -7.9228162514264337593543950335 a +7.9228162514264337593543950335 inclusive.