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
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 ... –
Das liegt daran, dass der Operator '^' ein Double zurückgibt, was das in meiner Antwort beschriebene Problem umgeht. –