Sửa lỗi 'Run-time error 6: Overflow' trong VBA Excel khi biến vượt giới hạn kiểu dữ liệu

intermediate📊 Microsoft Excel2026-06-01| Microsoft Excel 2016/2019/2021/Microsoft 365, Windows 10/11, VBA Editor (Alt+F11)

Error Message

Run-time error '6': Overflow
#excel#vba#overflow#kiểu-dữ-liệu#integer#long

Lỗi Và Thời Điểm Xuất Hiện

Bạn đang chạy một macro VBA — duyệt qua 50.000 hàng, tính tổng doanh số, hoặc theo dõi một bộ đếm vượt quá con số 33.000 — thì Excel ném cho bạn thông báo này:

Run-time error '6': Overflow

Macro dừng lại ngay lập tức. VBA Editor mở ra và tô vàng một dòng code. Đó chính là nơi VBA cố nhét một con số vào một "chiếc hộp" quá nhỏ để chứa nó.

Mỗi biến VBA có một phạm vi số cố định. Đẩy một giá trị vượt ngoài phạm vi đó là bạn nhận ngay lỗi Overflow. Chín trên mười trường hợp, nguyên nhân là một biến Integer đang làm một công việc cần đến Long.

Nguyên Nhân Gốc Rễ

Mỗi kiểu dữ liệu VBA chỉ chứa được giá trị trong một phạm vi nhất định:

  • Integer: –32.768 đến 32.767
  • Long: –2.147.483.648 đến 2.147.483.647
  • Single: ±3,4 × 1038 (độ chính xác hạn chế)
  • Double: ±1,8 × 10308
  • Byte: 0 đến 255
  • Currency: –922.337.203.685.477,5808 đến 922.337.203.685.477,5807

Giới hạn 32.767 của Integer chính là con số hay gây rắc rối. Excel đã hỗ trợ tới 1.048.576 hàng kể từ Excel 2007. Khai báo một Integer làm biến đếm hàng và VBA sẽ sập ngay khi bạn đến hàng 32.768. Trang tính có tới một triệu hàng, còn bộ đếm của bạn chỉ đi được đến ba mươi hai nghìn.

Bước 1 — Xác Định Dòng Lỗi Chính Xác

Đừng nhấn End khi hộp thoại xuất hiện. Hãy nhấn Debug thay vào đó. VBA Editor sẽ mở ra và tô vàng dòng lệnh bị lỗi — đó chính xác là nơi xảy ra tràn số.

Ba dạng lỗi phổ biến nhất:

' Biến đếm khai báo là Integer, trang tính có hơn 32.767 hàng
Dim i As Integer
For i = 1 To 100000  ' Crashes at 32,768
    ' ...
Next i

' Kết quả phép tính vượt quá phạm vi Integer
Dim result As Integer
result = 200 * 200  ' 40,000 > 32,767 → Overflow

' Số hàng cuối cùng trả về 50.000+ nhưng lưu trong Integer
Dim rowCount As Integer
rowCount = Cells(Rows.Count, 1).End(xlUp).Row

Bước 2 — Xác Định Biến Bị Tràn

Di chuột qua bất kỳ biến nào trên dòng được tô vàng — tooltip sẽ hiện giá trị hiện tại của nó. Vẫn chưa rõ? Thêm một lệnh Debug.Print vào dòng trước chỗ bị lỗi:

Debug.Print "Value before overflow: " & yourVariable

Mở cửa sổ Immediate bằng Ctrl+G, rồi chạy lại macro. Giá trị được in ra sẽ cho bạn biết chính xác con số nào đã gây ra lỗi.

Bước 3 — Sửa Kiểu Dữ Liệu

Thay Integer Bằng Long

Thay đổi đơn giản này giải quyết khoảng 80% lỗi Overflow. Bất kỳ biến nào dùng để đếm hàng, lưu ID, hoặc tích lũy tổng có thể vượt quá 32.767 đều nên dùng Long:

' Trước — sập khi vượt hàng 32.767
Dim i As Integer
For i = 1 To lastRow
    ' process row
Next i

' Sau — xử lý đủ 1.048.576 hàng mà không có vấn đề gì
Dim i As Long
For i = 1 To lastRow
    ' process row
Next i

Sửa Phép Tính Gây Tràn Số

Có một bẫy khá tinh vi ở đây. VBA tính toán biểu thức dựa trên kiểu dữ liệu của các toán hạng — không phải kiểu của biến nhận kết quả. Khai báo result As Long sẽ không giúp được gì nếu bạn nhân hai số nguyên kiểu Integer. Biểu thức đã bị tràn trước khi lệnh gán được thực thi.

' Bẫy: biểu thức tràn trước khi gán
Dim result As Long
result = 200 * 200  ' 200 và 200 là Integer → Integer * Integer → Overflow

' Cách 1: Hậu tố Long literal
result = 200& * 200

' Cách 2: Ép kiểu tường minh
result = CLng(200) * 200

' Cách 3: Khai báo toán hạng là Long
Dim a As Long, b As Long
a = 200 : b = 200
result = a * b

Sửa Tràn Số Single/Double

Các con số cực lớn hoặc tính toán khoa học có thể vượt quá giới hạn ~2,1 tỷ của Long. Hãy chuyển sang Double:

Dim bigNum As Double
bigNum = 3000000000# * 1500  ' # suffix forces Double literal

Sửa Tràn Số Byte

Byte chỉ chứa giá trị 0–255. Gán mã lỗi –1 vào một biến Byte là bạn nhận ngay lỗi Overflow:

' Trước
Dim status As Byte
status = someFunction()  ' Returns -1 on error → Overflow

' Sau
Dim status As Integer

Ví Dụ Đã Sửa Hoàn Chỉnh

Một tình huống thực tế: tính tổng một cột trên tất cả các hàng đang dùng. Phiên bản lỗi chạy tốt trên file thử nghiệm nhỏ — rồi âm thầm sập trên môi trường thực khi dữ liệu vượt quá 32.767 hàng.

' LỖI — tràn số trên trang tính có hơn 32.767 hàng
Sub ProcessData_Broken()
    Dim i As Integer
    Dim total As Integer
    Dim lastRow As Integer
    
    lastRow = Cells(Rows.Count, 1).End(xlUp).Row
    
    For i = 2 To lastRow
        total = total + Cells(i, 2).Value
    Next i
    
    MsgBox "Total: " & total
End Sub

' ĐÃ SỬA
Sub ProcessData_Fixed()
    Dim i As Long
    Dim total As Double    ' Double cho tổng có thể tăng lớn
    Dim lastRow As Long
    
    lastRow = Cells(Rows.Count, 1).End(xlUp).Row
    
    For i = 2 To lastRow
        total = total + CDbl(Cells(i, 2).Value)
    Next i
    
    MsgBox "Total: " & total
End Sub

Kiểm Tra Sau Khi Sửa

  • Nhấn F5 để chạy. Không có hộp thoại lỗi nghĩa là lỗi tràn số đã được xử lý.
  • In số hàng ra để xác nhận các phạm vi lớn được xử lý đúng: Debug.Print "Processing " & lastRow & " rows".
  • Kiểm thử với trang tính có hơn 32.767 hàng nếu dữ liệu của bạn có thể đạt đến con số đó.
  • Chạy từng bước với F8 và quan sát cửa sổ Locals (View → Locals Window) để phát hiện bất kỳ biến nào đang tiệm cận giới hạn kiểu dữ liệu của nó.

Thói Quen Phòng Ngừa Về Sau

  • Mặc định dùng Long, không dùng Integer: Long chiếm 4 byte so với 2 byte của Integer, nhưng các bộ vi xử lý hiện đại xử lý số nguyên 32-bit một cách tự nhiên — không có sự khác biệt hiệu năng đáng kể. Bạn loại bỏ được giới hạn phạm vi của Integer mà không phải đánh đổi bất cứ điều gì.
  • Dùng Option Explicit: Đặt Option Explicit ở đầu mỗi module. Nó bắt buộc khai báo biến, giúp bạn quyết định kiểu dữ liệu ngay từ đầu thay vì để chúng thành lỗi runtime.
  • Chú ý đến các số nguyên kiểu literal: 200 mặc định là Integer trong VBA. Dùng hậu tố kiểu để rõ ràng hơn: 200& cho Long, 200# cho Double.
  • Kiểm tra dữ liệu từ bên ngoài: Nếu giá trị ô tính điều khiển một lệnh gán, hãy chạy IsNumeric() trước và kiểm tra phạm vi hợp lệ trước khi lưu vào biến có kiểu dữ liệu cụ thể.

Related Error Notes