2013-06-26 3 views
8

Wenn ich Folgendes in das unmittelbare Fenster eintippe, bekomme ich Laufzeitfehler '6': Überlauf.Überlauf beim Multiplizieren von Ganzzahlen und Zuweisen von Long

MsgBox 24 * 60 * 60 

Warum ist das?

Dies scheitert auch:

Dim giveTime As Long 
giveTime = 24 * 60 * 60 

Warum ist das? giveTime ist als Long-Typ deklariert, also sollte 24 × 60 × 60 = 86400 bequem passen.

+0

Weiter zu diesem. - Wenn ich msgbox 26 * 60^2 in das unmittelbare Fenster setze, gibt es kein Problem. Ist es eine Frage des Vorrangs? Das scheint unwahrscheinlich ... –

+0

Das liegt daran, dass der Operator '^' ein Double zurückgibt, was das in meiner Antwort beschriebene Problem umgeht. –

Antwort

22

Dies ist eine wirklich merkwürdige VBA-Eigenart. Ich bin erstaunt, dass ich noch nie darauf gestoßen bin.

Dim x As Long 
x = 24 * 60 * 60 ' Overflow 
x = 32767 + 1 ' Overflow. 
x = 32768 + 1 ' Works fine! 

So sieht es aus wie die * und + Operatoren einen Integer in den ersten beiden Beispielen zurück. Sicher genug, in der Hilfedatei für den * Operator (ähnlich für den + Operator):

result = number1 * number2

[...]

The data type of result is usually the same as that of the most precise expression.

Ihre Literale 24, 60 und 60 sind alle vom Typ Integer standardmäßig so Ihre * (oder +) Betreiber gibt eine Ganzzahl zurück, die überläuft, weil das Ergebnis größer als 32.767 ist.

Allerdings verwendet das Literal 32.768 im dritten obigen Beispiel standardmäßig Long type (da es zu groß ist, um ein Integer zu sein) und so gibt + einen Long zurück; kein Überlauf.

Die Hilfe-Datei sagt auch dies:

If [...] the data type of result is an Integer variant that overflows its legal range [...] Then result is [...] converted to a Long variant.

Schwerpunkt Mine. Jetzt klingt diese kleine Regel wie gesunder Menschenverstand, und jeder würde vernünftigerweise annehmen, dass es in Ihrem Fall gilt. Aber Ihre Zahlen sind vom Typ Integer, nicht Variant/Integer, also wendet VBA diese Regel nicht an! Macht absolut keinen Sinn für mich, aber so ist es, und das ist es, was die Dokumentation sagt.

Lösung: machen Sie eines der Argumente Ihres *-Operators von einem Typ, der genauer ist als Integer (z. B. Long) und das Problem wird verschwinden.

x = CLng(24) * 60 * 60 ' Result is Long, works fine. 

In der Tat, und dies ist wahrscheinlich, warum ich nie in diese Marotte gestoßen habe, mache ich eine Gewohnheit, alle meine Integer-Variablen als Long statt erklärt, es sei denn, ein besonderes Anliegen ist Longs, dass mit statt Ganzzahlen verursachen Probleme mit der Speicherbelegung oder Ausführungszeit (was fast nie der Fall ist). Zugegeben, dies hilft nicht, wenn Sie mit Literalen arbeiten, die kleiner als 32.768 sind, weil sie standardmäßig auf den Integer-Typ eingestellt sind.


Sie fragen in a comment was ein Variant/Integer ist. Variante ist grundsätzlich ein Containertyp für jeden anderen Datentyp. In dem speziellen Fall, in dem Sie es ein Integer machen enthalten:

Dim a As Variant ' a is now Empty 
a = CInt(32767) ' a is now Variant/Integer 
x = a + 1 ' works fine 

Aber wie oben erwähnt, ein einfachen alten Integer löst den Überlauffehler:

Dim b As Integer 
b = 32767 
x = b + 1 ' overflow 
+0

Sicher ist eine Quirk! Also, was ist der Unterschied zwischen einem Variant/Integer und einem Integer? Ich nehme an, dass einer im Code deklariert ist, der andere intern deklariert? –

+0

oder 'x = [24 * 60 * 60]' –

+1

Richtig. Nun, '[]' eckige Klammern sind Abkürzungen für die ['Evaluate' Methode] (http://office.microsoft.com/client/helppreview14.aspx?AssetId=HV080005401&lcid=2057&NS=EXCEL.DEV&Version=14&tl=2&respos=0&CTT = 1 & queryid = 0b704676-cdcb-458a-b300-1bf8775c4ed3). Sie rufen also den Excel-Interpreter auf, um einen Ausdruck in VBA auszuwerten. Klingt wie etwas, das viel Overhead hinzufügt, wenn es wiederholt wird, aber ich denke, es ist in Ordnung, wenn es gelegentlich verwendet wird. –

1

Nach jeder Nummer, Platz #. Es definiert jede Nummer als ein Doppel.Stellen Sie sich vor, dass jede Zahl für die Berechnung als eine Art temporäre Variable im Speicher abgelegt wird. Wenn Sie jede Zahl definieren, wird genügend Speicherplatz für die Berechnungen zur Verfügung stehen.

zB:

Dim x As Long

x = 24 # * 60 # * 60 #

oder 24 & ‚zeigt lange

Verwandte Themen