2012-07-30 40 views
5

Tôi đã thấy một số người dùng SO gặp sự cố khi cố sử dụng một số biến thể của Cells.Count; mã VBA ném một lỗi tràn trong một số trường hợp.Giá trị không đúng khi đếm các ô trong các phiên bản Excel khác nhau

Để tham khảo, xem ý kiến ​​về this answer:

Tôi nghĩ rằng đây sẽ làm việc, nhưng tôi nhận được một lỗi "tràn" và nó chỉ cho tôi vào mã "Nếu Master.Cells.SpecialCells (xlCellTypeVisible) Count> 0 Sau đó" --- nó có vẻ như nó không lọc cho bất cứ điều gì đặc biệt - user1556069

this answer:

Đây có phải là onyl working (và Cells.Count didnt work) vì sau này sử dụng một số nguyên, 16 bit, giá trị lớn nhất là 65,536 và toàn bộ bảng tính trả lại một số lớn hơn? - fast_code


Tôi giả định rằng ở đâu đó đằng sau hậu trường VBA đang cố gắng ép buộc số lượng tế bào để một Integer nhỏ (16-bit) hoặc số nguyên Long (32-bit). Số lượng ô của trang tính Excel 2007 sẽ tràn cả hai kiểu dữ liệu này. Rất tiếc, tôi không thể cách ly nó ngay bây giờ vì tôi không có bản sao Excel 2007 tiện dụng và không thể thực sự tạo lại lỗi của bạn. - mwolfe02

Cố gắng hiểu điều này, tôi cố gắng tái tạo bản thân và bị tràn khi cố gắng chỉ định Cells.Count làm số nguyên. Điều này có ý nghĩa vì giá trị quá lớn cho kiểu dữ liệu Integer.

Sử dụng mã bên dưới trong cả Excel 2003 và 2010, tôi đã được cung cấp kết quả bằng số khi cố gắng chỉ định làm Dài hoặc Biến thể.

Option Explicit 

Sub testInteger() 
    Dim i As Integer 
    i = Cells.Count 'Overflow 
    Debug.Print i 'Doesn't get this far... 
End Sub 

Sub testLong() 
    Dim l As Long 
    l = Cells.Count 
    Debug.Print l 'Prints 16777216 in both versions 
End Sub 

Sub testVariant() 
    Dim v As Variant 
    v = Cells.Count 
    Debug.Print v 'Prints 16777216 in both versions 
End Sub 

Như bạn thấy trong ý kiến ​​của tôi, giá trị Cells.Count16777216 (đó là chính xác năm 2003), nhưng nó là như nhau cho cả hai phiên bản, và điều đó không có ý nghĩa đối với tôi. Để báo giá mwolfe02 từ một trong các câu trả lời được liên kết ở trên:

Trang tính Excel 2007 có 1.048.576 hàng và 16,384 cột với tổng số 17,179,869,184 ô.

Điều này cho tôi biết giá trị được in trong năm 2010 ít nhất phải là (tôi cho rằng nó thực sự giống nhau) 17,179,869,184.

Vậy tại sao con số này không in chính xác/tại sao giá trị năm 2003 được trả lại trong năm 2010?

+2

16777216 là '0x1000000' và 17179869184 là' 0x400000000' trong hệ thập lục phân chỉ FYI. – TheZ

+0

Bạn có đang chạy Excel 2010 ở chế độ Tương thích hay xem tệp được lưu ở định dạng 2003 không? –

+0

@TimWilliams Tôi bắt đầu bằng cách mở phiên Excel 2010 mới, được đặt mặc định thành Book1, trong đó tôi đã dán mã ở trên. Làm cách nào để xác định xem tôi có đang ở trong giai đoạn tương thích hay không. chế độ? – Gaffi

Trả lời

7

Khi tính số lượng lớn như vậy, hãy sử dụng thuộc tính .Countlarge.

Ví dụ

Sub CellsCount() 
    Dim l As Double 
    l = ActiveSheet.Cells.CountLarge 
    Debug.Print l 
End Sub 

Cũng không bao giờ sử dụng Cells.Count hay Cells.CountLarge mà không quy định cụ thể đối tượng bảng. Điều này là để đảm bảo rằng chúng tôi không nhận được số lượng/lỗi không chính xác trong chế độ tương thích. Tương tự, không bao giờ sử dụng Rows.Count. Luôn sử dụng ws.Rows.Count. Đây là lỗi phổ biến nhất mà mọi người mắc phải khi cố gắng tìm hàng cuối cùng trong excel. Ví dụ

này

lRow = ws.Range("A" & Rows.Count).End(xlUp).Row 

lRow = ws.Range("A" & ws.Rows.Count).End(xlUp).Row 

có thể không cung cấp cho bạn kết quả tương tự luôn.

Tôi cũng khuyên bạn nên đọc thêm this.

+0

Cảm ơn, Sid. Tôi đánh giá cao sự hiểu biết của bạn. (Tuy nhiên, tại sao MSFT phải có cả '.Count' * và *' .CountLarge' ...?) – Gaffi

+2

Nó giống như hỏi tại sao MS có Excel 2003 và Excel 2007: P. '.CountLarge' được giới thiệu với Excel 2007 và không có sẵn với các phiên bản trước của Excel. Thuộc tính 'Count' sử dụng Kiểu dữ liệu dài để giá trị lớn nhất mà nó có thể lưu trữ là 2.147.483.647. '.CountLarge' sử dụng kiểu dữ liệu đôi ehich có thể xử lý lên đến 1,79 + E^308. –

+1

+1: Đối với khả năng tương thích ngược, bạn có thể bao gồm một kiểm tra dựa trên 'val (application.version)> = 12' và sử dụng Cells.Countlarge nếu đúng và Cells.Count nếu không. Lưu ý rằng nếu sử dụng tăng gấp đôi để lưu trữ số nguyên, bạn cũng có thể đạt đến giới hạn do 15 chữ số chính xác ~ 2^50 nhưng điều này vượt quá kích thước lưới 2^20 * 2^14 = 2^34. –

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