Chạy bằng tay thì không lỗi, chạy một mạch thì bị lỗi- Cần chỉ định rõ ràng

tuhocvba

Administrator
Thành viên BQT
1. Câu chuyện của ngày hôm nay: là xuất phát từ topic này.
Hiện tại tôi đang tập trung vào dự án này, hiện đang ở giai đoạn 2, về cơ bản đã xong demo.
Tôi cố gắng không sử dụng các từ ngữ chuyên môn của người ra yêu cầu, mà sử dụng các ngôn ngữ dễ hiểu trong bài viết này.
2. Vấn đề:
[Đã xóa ảnh]
Ở dòng 255 bạn thấy hai ký tự cuối của nó là IV. Trong các dòng 256, 257, 258 thực ra là muốn IW, IX, IY:
Bạn cần đăng nhập để thấy đính kèm

Việc tăng thứ tự này trùng hợp với thự tự cột trong excel. Tuy nhiên dù chạy macro bao nhiêu lần thì cứ tới IV là sau đó không chạy được nữa.
Tuy nhiên nếu chặn code ở i = 256 rồi chạy từng dòng lệnh bằng F5 hoặc F8 thì sau đó tôi vẫn thấy nó lần lượt ra các đáp số IW, IX, IY.
Tôi cũng không xử lý trực tiếp trên excel, mà dùng mảng và dictionary.
3. Nhắc lại về việc lấy tên cột.
Trước đây trên GPE đã từng có một yêu cầu của thành viên liên quan tới vấn đề này. Các thành viên đưa ra giải đáp khi đó đều rất thủ công, họ nói rằng vì họ chưa có kinh nghiệm, chưa làm điều này bao giờ.
Đại ý là, nếu người ta viết A tức cột A, thì làm sao để hiểu được đó là cột 1. B thì là cột 2...
Khi đó tôi có đưa ra ý tưởng là lấy địa chỉ cells, việc này tôi cũng đã viết lại trên diễn đàn ta, được trình bày ở đây:
4. Tìm hiểu lỗi.
Tôi thử tìm các giới hạn về dictionary thì thấy không có chú ý nào.
Trong chương trình tôi có dùng thêm lệnh split.
Đại khái Dictionary thì được ghi:
key, item =thongtin1,thongtin2,thongtin3,...
sau đó: arr = split(item,",")
Có lẽ nào lệnh split lại có giới hạn ở 255 phần tử? Tại sao cứ tới IV là không được nữa? Tôi cũng thử tìm hiểu về Split và không thấy có chú ý nào về giới hạn.
Tại sao cho macro chạy một mạch thì kết quả lại lỗi, còn khi chặn i và chạy từng dòng lệnh thì lại ra kết quả đúng?
5. Giải quyết:
Tôi không đợi i = 256, mà ngay ở dòng đầu tiên, tôi cho code xây dựng item = thongtin1,thongtin2,...,thongtin256.
Và kết quả sau đó ra OK.
Nhưng bất ngờ là ở các lần chạy sau đó đều ra kết quả sai.
Tắt excel và mở lại, chạy lại, vẫn sai. Luôn luôn ra kết quả sai.
Tôi tiếp tục chặn từng dòng lệnh, và may mắn là lần này việc chặn từng dòng lệnh để chạy cũng cho ra kết quả sai. Và vì vậy tôi đã nhìn ra vấn đề.
Quay trở lại chủ đề Tìm cột theo số, ta thấy có dòng code sau:
Mã:
i = Range(s & "1").Column
Khi ghi như thế này, thì VBA hiểu workbook là workbook đang được active, sheet là sheet đang được active.
Việc viết code như trên, tất nhiên trong quá trình chạy thử nghiệm trước kia thì luôn đúng. Nhưng tôi không ngờ, khi mang nó áp dụng cho chương trình khác, khi số lượng dữ liệu xử lý nhiều hơn, thì bắt đầu sai.
Tôi nhanh chóng hiểu ra rằng, mình cần phải chỉ định rõ ràng trong trường hợp xử lý nhiều dữ liệu, Excel có thể bị mất tập trung và dẫn tới sai.
Thật vậy, khi tôi chỉ định rõ ràng hơn:
Mã:
i = Thisworkbook.Sheets(1).Range(s & "1").Column
thì chương trình cho ra kết quả chính xác.
6. Bài học rút ra:
Lỗi nếu là lỗi logic, tức là dù chạy thế nào cũng luôn ra kết quả sai giống nhau thì dễ xử lý.
Tuy nhiên với những lỗi mà nay xảy ra, lúc khác lại không xảy ra, thì việc xử lý thật khó khăn và mất thời gian. Nếu có thể, hãy tái hiện lại data lỗi ở ngay lần chạy đầu tiên i = 1, thay vì i = 256.
Nên chỉ định rõ ràng, để tránh sự mất tập trung của Excel, dẫn tới ra kết quả không như ý muốn.
[Đã xóa ảnh]
 

vbano1

SMod
Thành viên BQT
Sửa lỗi thì chỉ tích tắc, tìm ra chỗ sai để sửa thì mất hàng tiếng.
Chỉ có va vấp mới cho chúng ta những kinh nghiệm quý báu. Những va vấp của tất cả mọi người nên được chia sẻ nhiều hơn ^_^
 
Top