2008-11-25 5 views
3

De l'aide pour l'erreur de débordement dans VBA, il y a les exemples suivants:Malentendu de type de données Long en VBA

Dim x As Long 
x = 2000 * 365 ' gives an error 

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

j'aurais pensé que, puisque le type de données Long est censé être en mesure de tenir Nombres de 32 bits, que le premier exemple fonctionnerait bien.

Je pose cette question parce que j'ai un code comme ceci:

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

et cela jette une erreur de débordement lorsque AnnualCost est 5000 et mois est 12.

Qu'est-ce que je manque?

+0

Je vois que vous avez une réponse au problème. Il peut être préférable d'utiliser la devise (ccur), plutôt que longue, à la fois pour la cohérence et parce que même si vous n'avez pas besoin de décimales maintenant, vous pouvez le faire à l'avenir. – Fionnuala

+0

2000 est un nombre entier. Utilisez 2000 et 365 et vous serez bien. – Robino

Répondre

12

2000 et 365 sont des valeurs entières. Dans VBA, les entiers sont des types signés 16 bits, lorsque vous effectuez une opération arithmétique sur 2 entiers, l'arithmétique est effectuée sur 16 bits. Puisque le résultat de la multiplication de ces deux nombres dépasse la valeur qui peut être représentée avec 16 bits, vous obtenez une exception. Le deuxième exemple fonctionne car le premier nombre est d'abord converti en un type 32 bits et l'arithmétique est ensuite effectuée en utilisant des nombres de 32 bits. Dans votre exemple, l'arithmétique est effectuée avec des entiers de 16 bits et le résultat est alors converti en long, mais à ce stade, il est trop tard, le dépassement de capacité est déjà survenu. La solution est de convertir l'un des opérandes dans la multiplication première longue:

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

Le problème est que la multiplication se passe à l'intérieur des crochets, avant la conversion de type. C'est pourquoi vous devez d'abord convertir au moins une des variables en Long, avant de les multiplier.

Vous avez probablement défini les variables comme Integer. Vous pourriez envisager d'utiliser Long au lieu d'Integer, en partie parce que vous aurez moins de problèmes de débordement, mais aussi parce que Longs calcule (un peu) plus vite que Integers sur les machines 32 bits. Longs prennent plus de mémoire, mais dans la plupart des cas, ce n'est pas un problème.

1

En VBA, les littéraux sont des entiers par défaut (comme mentionné). Si vous devez forcer un type de données plus grand sur eux, vous pouvez les refaire comme dans l'exemple ci-dessus ou simplement ajouter un caractère de déclaration de type. (La liste est ici: http://support.microsoft.com/kb/191713) Le type Long est « & » pour que vous puissiez le faire simplement:

Price = CLng(AnnualCost * Months/12&) 

et les 12 seraient reconvertis en un long. Cependant, il est généralement recommandé d'éviter les littéraux et d'utiliser des constantes. Dans ce cas, vous pouvez taper la constante dans sa déclaration.

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