Giải thích về Set:
Trong lập trình, phép tính căn bản nhất phép gán.
Theo tiêu chuẩn cổ xưa của BASIC thì dấu = là phép so sánh. Muốn gán thì phải là lênh Let và dấu bằng:
Let (biến cần gán) = (trị biểu thức)
Về sau này, máy tính mạnh hơn, trình dịch được cải tiến nên Let được bỏ đi.
VBA tuy không phải là loại ngôn ngữ hướng đối tượng nhưng nó có thể làm việc được với đối tượng. Căn bản là hầu hết các giao diện giữa VBA và Excel đều qua các đối tượng của Excel Application, Workbook, và Worksheet.
Tuy nhiên, các đối tượng hầu như luôn luôn có hàm mặc định để lấy giá trị, tức là lấy một thuộc tính nào đó của nó.
VBA quy định rằng lệnh gán bình thường (dấu =) sẽ là phép gọi hàm mặc định để lấy thuộc tính. Và để gán cả đối tượng thì dùng phép gán Set
Điển hình:
a = Range("a1") gọi hàm mặc định của range để lấy trị trong ô a1, gán cho biến a. Như vậy, sau lệnh này, a sẽ có trị bằng trị chứa trong a1
Set a = Range("a1") gán đối tượng Range("a1") cho a. Như vậy, sau lệnh này, a sẽ trỏ vào a1
Lưu ý rằng thực ra phép gán Set là gán tham chiếu/reference, gán địa chỉ. Trỏ biến vào địa chỉ của đối tượng
Vì vậy, nếu code Set đối tượng thì thường khi dùng xong, code sẽ Set nó về Nothing (tức là trỏ nó vào khoảng trống) để tránh tình trạng nó vẫn còn trỏ vào đối tượng ấy.
Tuy nhiên, nếu biến này là biến nội (được khai báo bên trong) của một Sub hay Function thì khi thoát Sub/Function nó sẽ tự giải thoát. Và do điều này, nhiều ngừoi cho rằng lệnh Set Nothing là thừa.
Tôi đã từng có bài so sánh thiệt hơn của hai quan niệm này. Việc bạn theo quan niệm nào là quyền của bạn. Tôi chỉ khuyên rằng đối với những người có thói quen dùng biến toàn cục thì lệnh Set khá nguy hiểm, lúc dùng phải cẩn thận theo dõi phạm vi của nó.
Giải thích về On Error Resume Next:
Trong lập trình, bẫy lỗi là điều quan trọng để bắt những sự kiện ngoài ý muốn.
Cụm từ "bẫy lỗi" là dịch tiếng nghề "error trap". Đó là từ xưa của lập trình. Ngày nay, các ngôn ngữ lập trình gọi nó là "exception handling" - "xử lý sự kiện ngoại lệ"
Khi chương trình bị một lỗi nào đó, ví dụ chia 0, thì tự nó sẽ không biết xử lý như thế nào, và sẽ "chết" (crash). Thực ra, bên trong hệ thống có phần xử lý an toàn, và có cả một quy trình xét ngăn xếp để biết chuyện gì xảy ra. Lệnh On Error dặn VBA đặt điều kiện trước để xử lý khi gặp lỗi. Lệnh Resume có nghĩa là bỏ qua lỗi đi và tiếp tục ở cái chỗ sau từ khoá Resume.
Như vậy On Error Resume Next có nghĩa là nếu gặp lỗi thì kệ nó đi và tiếp tục ở dòng kế tiếp.
Ở diễn đàn này, nhiều ngừoi thích sử dụng On Error Resume Next để trơn tru công việc. Thực ra, trước khi sử dụng nó, ngừoi lập trình phải cân nhắc các điểm sau:
- các lệnh xét lôgic (IF). Next của lệnh này là chỗ nào?
- các lệnh kép (ngăn bởi dấu ":"). Next của chúng lắm khi đưa vào chỗ sai.
- các lệnh gọi sub/function. Như trên, phải nắm vững là sub/function lúc đó đã chạy chưa. Nhất là các sub/function làm việc với biến/đối tượng toàn cục.
- các nơi vòng lặp duyệt. Bỏ qua như vậy là bỏ qua con tính hay bỏ qua một biến vòng lặp? Ví dụ, code lấy dữ liệu từ các files trong một folder. Lúc găp lỗi thì bỏ qua file đó. Như vậy, cuối cùng làm sao biết file nào được xử lý và file nào bị bỏ qua?
Tóm lại, lệnh On Error Resume Next là lệnh nguy hiểm. Toi khong hề nói là không nên dùng. Tôi chỉ nhấn mạnh là nếu dùng thì phải nắm vững cách xử lý các trường hợp tôi nêu trên.
Chú: lệnh On Error GoTo... ít nguy hiểm hơn, nhưng nên lưu ý rằng GoTo là lệnh rẽ nhánh không có kiểm soát. Nếu không cẩn thận thì sẽ dẫn đến tình trạng code rối chỉ (tiếng chính là spaghetti/mì Ý)