emulator vba

emulator - vba excel pdf



Malentendido del tipo de datos largos en VBA (3)

De la ayuda para el error de desbordamiento en VBA, hay los siguientes ejemplos:

Dim x As Long x = 2000 * 365 '' gives an error Dim x As Long x = CLng(2000) * 365 '' fine

Hubiera pensado que, dado que se supone que el tipo de datos Long puede contener números de 32 bits, el primer ejemplo funcionaría bien.

Pregunto esto porque tengo un código como este:

Dim Price as Long Price = CLng(AnnualCost * Months / 12)

y esto arroja un error de desbordamiento cuando AnnualCost es 5000 y Months is 12.

¿Qué me estoy perdiendo?


2000 y 365 son valores enteros. En VBA, los enteros son tipos con signo de 16 bits, cuando realiza aritmética en 2 enteros, la aritmética se lleva a cabo en 16 bits. Como el resultado de multiplicar estos dos números excede el valor que se puede representar con 16 bits, se obtiene una excepción. El segundo ejemplo funciona porque el primer número se convierte primero a un tipo de 32 bits y la aritmética se lleva a cabo utilizando números de 32 bits. En su ejemplo, la aritmética se realiza con enteros de 16 bits y el resultado se convierte a largo, pero en ese punto ya es demasiado tarde, el desbordamiento ya se ha producido. La solución es convertir primero uno de los operandos en la multiplicación a largo:

Dim Price as Long Price = CLng(AnnualCost) * Months / 12


El problema es que la multiplicación está ocurriendo dentro de los corchetes, antes de la conversión de tipo. Es por eso que primero debe convertir al menos una de las variables a Long, antes de multiplicarlas.

Es de suponer que definió las variables como Entero. Puede considerar usar Long en lugar de Integer, en parte porque tendrá menos problemas de desbordamiento, pero también porque Longs calcula (un poco) más rápido que Integers en máquinas de 32 bits. Longs toma más memoria, pero en la mayoría de los casos esto no es un problema.


En VBA, los literales son enteros por defecto (como se mencionó). Si necesita forzar un tipo de datos más grande sobre ellos, puede modificarlos como en el ejemplo anterior o simplemente agregar un carácter de declaración de tipo. (La lista está aquí: http://support.microsoft.com/kb/191713 ) El tipo para Long es "&", por lo que podría hacer:

Price = CLng(AnnualCost * Months / 12&)

Y el 12 sería refundido como un largo. Sin embargo, generalmente es una buena práctica evitar literales y usar constantes. En ese caso, puede escribir la constante en su declaración.

Const lngMonths12_c as Long = 12 Price = CLng(AnnualCost * Months / lngMonths12_c)