2013-06-26 42 views
8

Nếu tôi nhập thông tin sau vào cửa sổ ngay lập tức, tôi gặp lỗi Runtime '6': Tràn.Tràn khi nhân số nguyên và gán cho Long

MsgBox 24 * 60 * 60 

Tại sao điều này?

này cũng thất bại:

Dim giveTime As Long 
giveTime = 24 * 60 * 60 

Tại sao điều này? giveTime được khai báo là loại Dài, vì vậy 24 × 60 × 60 = 86400 phù hợp thoải mái.

+0

Tiếp tục cho việc này. - Nếu tôi đặt msgbox 26 * 60^2 trong cửa sổ ngay lập tức thì không có vấn đề gì cả. Nó là một thứ tự của vấn đề ưu tiên? Điều đó có vẻ khó xảy ra ... –

+0

Đó là bởi vì toán tử '^' trả về một Double, điều này sẽ tránh được vấn đề được mô tả trong câu trả lời của tôi bên dưới. –

Trả lời

22

Đây thực sự là một điều kỳ quặc của VBA. Tôi ngạc nhiên là tôi chưa bao giờ đụng vào chuyện này.

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

Vì vậy, nó trông giống như *+ khai thác trở lại một Integer trong hai ví dụ đầu tiên. Chắc chắn, trong file trợ giúp cho các nhà điều hành * (tương tự cho các nhà điều hành +):

result = number1 * number2

[...]

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

literals bạn 24, 60 và 60 là tất cả các loại Integer theo mặc định, vì vậy bạn * (hoặc +) điều hành trả về một số nguyên, nó tràn vì kết quả lớn hơn 32,767.

Tuy nhiên, chữ cái 32.768 trong ví dụ thứ ba ở trên mặc định là Loại dài (vì nó quá lớn để là Số nguyên) và do đó + trả về giá trị Dài; không tràn.

Các tập tin trợ giúp cũng nói điều này:

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

Nhấn mạnh tôi. Bây giờ quy tắc nhỏ này có vẻ giống như ý thức thông thường, và bất cứ ai sẽ giả định hợp lý rằng nó áp dụng trong trường hợp của bạn. Nhưng các con số của bạn thuộc kiểu Integer, không phải là Variant/Integer, do đó VBA không áp dụng quy tắc này! Làm cho hoàn toàn không có ý nghĩa với tôi, nhưng đó là cách nó được, và đó là những gì tài liệu nói.

Giải pháp: thực hiện một trong các đối số của toán tử * có loại chính xác hơn Integer (ví dụ: Long) và sự cố sẽ biến mất.

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

Trong thực tế, và điều này có lẽ là lý do tại sao tôi đã không bao giờ đụng vào không minh bạch này, tôi thực hiện một thói quen tuyên bố tất cả các biến Integer của tôi như dài thay vào đó, trừ khi có một mối quan tâm cụ thể mà có Longs thay vì Số nguyên sẽ gây ra vấn đề với việc sử dụng bộ nhớ hoặc thời gian thực hiện (gần như không bao giờ là trường hợp). Cấp, điều này sẽ không giúp đỡ trong trường hợp khi bạn hoạt động trên literals nhỏ hơn 32,768, bởi vì họ mặc định để loại Integer.


Bạn yêu cầu a comment Biến thể/số nguyên là gì. Biến thể về cơ bản là một loại container cho bất kỳ loại dữ liệu nào khác. Trong trường hợp cụ thể mà bạn thực hiện nó chứa một Integer:

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

Nhưng như đã nói ở trên, một đồng bằng cũ Integer kích hoạt lỗi tràn bộ nhớ:

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

Chắc chắn là một Quirk! Vì vậy, sự khác biệt giữa một biến thể/Integer và một Integer là gì? Tôi cho rằng một cái được khai báo trong mã, cái kia được khai báo trong nội bộ? –

+0

hoặc 'x = [24 * 60 * 60]' –

+1

Phải. Vâng, dấu ngoặc vuông '[]' là viết tắt của phương pháp ['Đánh giá'] (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). Vì vậy, bạn đang gọi trình thông dịch Excel để đánh giá một biểu thức trong VBA. Âm thanh như một cái gì đó mà thêm rất nhiều chi phí nếu thực hiện lặp đi lặp lại, nhưng tôi đoán đó là ok nếu sử dụng vào dịp. –

1

Sau mỗi số, nơi #. Nó định nghĩa mỗi số là một đôi.Hãy nghĩ về nó như là, mỗi số được đặt vào bộ nhớ để tính toán như là một loại biến tạm thời. Nếu bạn xác định mỗi số, nó sẽ cho phép đủ không gian để tính toán.

ví dụ:

Dim x As Long

x = 24 # * 60 # * 60 #

hoặc 24 & 'chỉ dài

Các vấn đề liên quan