HeSanbi
Nam Nhân✨Hiếu Lễ Nghĩa Trí Tín✨
- Tham gia
- 24/2/13
- Bài viết
- 2,629
- Được thích
- 4,095
- Giới tính
- Nam
Hôm nay tôi chia sẻ cho các bạn chủ đề liên quan đến các lỗi viết mã cơ bản trong lập trình VBA và cách tránh lỗi viết mã bị xem là nguy hiểm bị xem là ứng dụng có virus, nếu các bạn thiếu kinh nghiệm trong lập trình sẽ tạo ra nhiều lỗi, mà sau này phải bỏ nhiều thời gian để sửa lỗi cho các dự án. Chính vì vậy mà tôi chia sẻ bài viết này với những gì tôi đã tích lũy được trong quá trình lập trình ứng dụng của mình. Các bạn hãy đọc qua bài viết để biết thêm chi tiết.
Các lỗi viết mã cơ bản
Các cách lập trình nên ứng dụng nhiều hơn
Trên đây tôi chỉ đề cập qua các điều nên biết liên quan đến VBA, không đề cập đến lỗi lập trình ứng dụng Excel, Word, Access, PowerPoint, có thời gian tôi sẽ mở chủ đề mới nếu được.
Chúc các bạn thành công!
Các bạn có thể tham khảo Tools liên quan đến lập trình mã VBA để học và viết mã nhanh chóng hơn
Dưới đây là hai tệp đính kèm lớp StringBuilder để ghép chuỗi. Và JsonConvert để tách và tạo dữ liệu json mà tôi đã tối ưu và cải tiến, các bạn có thể tải về để tham khảo. Tải về và đổi tên .txt thành .cls để import vào VBA.
Các lỗi viết mã cơ bản
Khi lập trình với VBA thì các bạn cần nắm vững điều này để không bao giờ mắc phải lỗi cơ bản, để phát triển ứng dụng
1. Lỗi trong khai báo:
Lỗi khai báo nhiều biến trên cùng một khai báo.
Dim r1, r2, r3 As Range
là khai báo không hợp lý phải khai báo đầy đủ như sau:
Dim r1 As Range, r2 As Range, r3 As Range
Lỗi khai báo Define Name, khi bạn khai báo DefLng A-Z, DefBool B, K, ...v.v.
Thì cần khai báo rõ ràng kiểu biến cho các khai báo trong mã.
Các bạn có thể hiểu về Define Name như sau:
Giả sử bạn đã khai báo DefLng A-Z có nghĩa là tất cả các khai báo trong phương thức với các ký tự bắt đầu từ A đến Z đều là kiểu Long. Tuy nhiên bạn muốn tạo biến kiểu khác thì phải khai báo rõ ràng.
Không được khai báo:
Dim r1
Khai báo sau, hiểu là biến r1 phải là kiểu Range, không còn là Long nữa:
Dim r1 As Range
2. Lỗi không để cho chương trình chạy qua 'End With' sau khi gọi 'With [object]'.
Không nên để điều này xảy ra, vì sẽ gây ra lỗi không giải phóng được đối tượng đã gọi với 'With' cho dù đã thoát khỏi phương thức.
Không nên gọi lệnh Goto hoặc Exit để nhảy ra khỏi khối With nhanh chóng.
3. Lỗi xử lý chuỗi và chuỗi Unicode
Vấn đề khi so sánh chuỗi với số
Lỗi đặt phép so sánh với các toán tử <>, = , >, <, Like,... giữa chuỗi với số và ngược lại là lỗi, chính vì vậy hãy sử dụng các hàm bổ trợ để chuyển đổi số thành chuỗi hoặc chuỗi số thành số trước khi so sánh.
Ví dụ các trường hợp tạo mã sau sẽ lỗi:
JavaScript:
v = 1 like "x"
v = 1 <> "x"
Ví dụ các trường hợp nên tận dụng:
JavaScript:
v = CStr(1) like "x"
v = CStr(1) <> "x"
v = StrComp(1, "x") <> 0
Với ô Excel có nhiều dạng giá trị như Số, Logic, Chuỗi, Lỗi, thì việc so sánh buộc phải chuyển đổi như các ví dụ ở trên.
Vấn đề về ghép chuỗi
Hãy luôn sử dụng hàm CStr khi chuyển các biến là kiểu số khi ghép chuỗi với số, với thời gian hãy sử dụng các hàm Format
Không nên viết mã như sau:
JavaScript:
Const v = 5.5
s = "x" & 6.6 & v
Viết mã thêm CStr như sau:
JavaScript:
Const v = 5.5
s = "x" & CStr(6.6) & CStr(v)
Khi ghép chuỗi dài, nhiều lần hãy tận dụng thư viện StringBuilder (tải về ở đính kèm) xử ký chuỗi tại bộ nhớ máy tính để ghép chuỗi, giúp tăng tốc ghép chuỗi nhanh hơn rất nhiều lần thay cho việc sử dụng toán tử & để ghép chuỗi.
Vấn đề về lưu chuỗi dài
Trong VBA nếu bạn muốn lưu trữ mã Base64 hoặc một dạng mã hóa nào khác cần ngắt dòng hợp lý và tách ra nhiều hàm để lưu. Để tránh lỗi biên dịch và đóng gói.
Ví dụ như cách lưu đoạn Base64 dưới đây:
JavaScript:
s = s & "s18SbXSnq61roHyt2IMMOPk2hnBYbNll3vPCxNYnfLk/cy6LU4cAtFpn8hIZkc"
s = s & "lptslyqITx2VN/QwxEJMxWlF5gOI8EDApbrY0JmpMwYomVQKHBFHKDCgN"
s = s & "Vbn4GQKdGGmvBwAms5YkxEqMwmjsLl5TlUey3uNSCsnCKSFv0ZhGB02Q"
s = s & "UuAtBMMTPfUixwBBEkHKQJQcFbJqls4YsQdI+8qoHk04vYNTIG8pNOTNjW"
Vấn đề về Unicode
Các bạn cần lưu ý khi lập trình với chuỗi Unicode, chuỗi Unicode có trong nhiều kiểu dữ liệu như chuỗi, chuỗi tải về từ mạng, trong đường dẫn, vì VBA là ngôn ngữ lập trình lỗi thời nên đa số các hàm cơ bản chỉ hỗ trợ Ascii như Dir, MkDir, ... Chính vì vậy cần sử dụng các phương thức thay thế cho hợp lý. Nếu không dự án của bạn khi đến tay người dùng sẽ gặp lỗi.
Có các hàm API cũng cần khai báo các hàm hỗ trợ Unicode. Mã hóa và giải mã chuỗi Unicode hay Utf8, ... sang unicode là rất cần thiết.
4. Hạn chế tạo tên biến, tên Enum và Type có chứa các từ khóa cú pháp.
Không đặt tên biến trùng các hàm như Format là hàm Format, ... hãy thêm một hoặc hai ký tự như vFormat
Không đặt Enum và Type có chứa các từ khóa Enum, Type, Global, ... như sau dễ gây ra lỗi thông dịch:
Enum NewEnumrates
Type NewType
5. Hạn chế khởi tạo đối tượng toàn cục trong lớp (Class module).
Do tiêu chuẩn trong lập trình phụ thuộc trình biên dịch và đóng gói của ứng dụng VBA, nên mục này là rất cần thiết. Cách viết mã có thể tạo cơ hội cho các cuộc tấn công từ bên ngoài.
Khai báo như sau là nên hạn chế, cách khai báo sau thường do tính "lười biếng" gây ra:
Public cls As Collection
Public cls As New Collection
Hãy khai báo Private trước sau đó Set New:
Private cls As Collection: Set cls = New Collection
Private cls As New Collection
Trong VBA có các lỗi nghiêm trọng tiêu biểu như truy cập bộ nhớ Enumrates của Collection, chính vì đó mà khai báo hợp lý sẽ giúp các bạn không chỉ vững kinh nghiệm trong VBA mà còn với các nền tảng phát triển khác. Các lỗi viết mã cũng là điều kiện gây cho dự án phải bỏ nhiều công sức sửa lỗi, và cũng cho Hacker cơ hội xâm nhập.
6. Vấn đề về số thập phân, số dài và Hexadecimal
Các bạn nên chú ý về điều này. Các ký tự đại diện kiểu số rất quan trọng trong lập trình là !, #, @, %, &, ^.
Với Hexadecimal:
Các giá trị như sau là như nhau nhưng khác số khi lấy giá trị số nguyên:
JavaScript:
Debug.Print &HFFFF = &HFFFF& ' Có dấu &
Sẽ in ra là: -1 <> 65535
Tuy nhiên với Hexadecimal thì hiểu là &HFFFF vẫn bằng &HFFFF&, vì &HFFFF là chuyển dấu của &HFFFF& theo phép quay bit.
Nếu các bạn chưa biết phép quay bit hãy tham khảo bài viết: Phép quay bit
Trong Win64 bit, các bạn không thể nhập số Hexadecimal kiểu LongLong/LongPtr lớn nhất là: &HFFFFFFFFFFFFFFFF phải là &HFFFFFFFFFFFFFFFF^
có dấu mũ ^ sau cùng. Đồng thời phải kèm theo tiền xử lý #If với thông số Win64 để tương tích nhiều nền tảng.
Với các kiểu số Double !, Single #, Currency @
Nếu các bạn nhập là 2.777777777777 thì 1 vài số 7 phía sau bị rút ngắn lại, hãy thêm ký tự vào sau để giữ số 7
7. Thời gian trong PC của bạn khi gọi hàm Now, Date, Time, Timer là không khớp với thời gian chuẩn Quốc tế
Hãy lưu ý là thời gian trong PC không khớp với thời gian chuẩn Quốc tế, chính vì vậy việc lập trình về thời gian cũng cần chú ý. Chẳng hạn như bạn sử dụng HTTP để tải dữ liệu thời gian thực từ mạng, nếu mang so sách với thời gian của PC sẽ bị sai. PC của bạn cần đồng bộ thời gian hiện tại trước khi so sánh.
Hãy luôn luôn xử lý đặt định dạng chuẩn ngày tháng năm theo thứ tự định dạng sau: YYYY/MM/DD HH:MM:SS, dù cho bạn chuyển đổi hay ghi ra mảng.
8. Vấn đề bẫy lỗi.
- Không đặt bẫy lỗi như On Error Resume Next, On Error Goto xxxx trong vòng lặp, sẽ làm chậm mã, hãy sử dụng phương thức Err, xóa lỗi trước khi gọi phương thức cần bẫy lỗi với Err.Clear và xem Err.Number nếu có.
- Bẫy lỗi trong phương thức gọi phương thức khác trong nó, thì trong phương thức khác bắt buộc khai báo dòng mã bẫy lỗi riêng. Bẫy lỗi phương thức gọi không đồng nhất với phương thức được gọi.
- Luôn cần gọi phương thức Err.Raise để tạo ra thông báo lỗi khi mã gặp lỗi hoặc lỗi nhập đối số.
9. Hạn chế viết các khối cú pháp như If...Then ... Else, Do...Loop, While...Wend, For Next, With, ... cùng dòng
Lỗi này có thể gây ra lỗi biên dịch, và lỗi khi debug, Ví dụ:
JavaScript:
If True Then Call Procedure1
Do: I = I + 1: Loop Until i > 0: Do
For I = 1 to 10: Next
With new Collection: :End With
Lỗi này sẽ xảy ra nhiều hơn khi, mã bạn tạo có nhiều tiền xử lý #If...#Then..#ElseIf..#Else lòng nhau.
10. Thủ tục con GoSub bắt buộc phải có lệnh Return
GoSub là lệnh nhảy đến chạy qua một đoạn mã trong phương thức, gọi là hàm con trong thủ tục, nên bắt buộc phải có lệnh Return để trở lại dòng mã sau vị trí gọi GoSub.
JavaScript:
Sub Test1()
Gosub 1
Gosub ab
Exit sub
1:
Debug.Print 1
return
ab:
Debug.Print "ab"
return
End Sub
11. Viết mã tương thích đa nền tảng Window và Office
Khai báo và viết mã tương thích là yêu cầu bắt buộc để ứng dụng của bạn chỉ viết một lần mà không phải mất nhiều thời gian để sửa mã tương thích. Nhất là đối với lập trình API Win32.
Nên thay thế toàn bộ khai báo LongLong trong mã thành LongPtr, khai báo LongPtr là khai báo tương thích, nếu ở Win32 trở về thì nó là Long, Ngược lại nó được biên dịch là LongLong.
Vấn đề khai báo Long và LongPtr/LongLong là vấn đề rối nhất trong VBA, chính vì vậy hãy làm theo cách sau:
Khai báo hai Enum LongPtr và LongLong cho các nền tảng 32bit, luôn luôn đặt các dòng mã này vào dự án có lập trình API của bạn để tương thích.
JavaScript:
#If VBA7 = 0 Then
Public Enum LongLong: [_]:End Enum
Public Enum LongPtr: [_]:End Enum
#End If
Sau khi khai báo thì bạn có thể khai báo không nhất thiết cần đến các khối mã tiền xử lý #If...#Else, tùy vào một số trường hợp mà các API bắt buộc có khối tiền xử lý.
Ví dụ dưới đây không cần khai báo tiền xử lý #If...#Else vẫn tương thích khi đã khai báo như trên:
JavaScript:
Sub ProcTimer(hwnd As LongPtr, msg As Long, idEvent As LongPtr, vtimer As LongPtr)
Dim v As LongPtr
End Sub
12. Lỗi không giải phóng bộ nhớ
Lỗi này có thể gây ra tràn bộ nhớ. Bộ nhớ máy tính có giới hạn, nên tránh lỗi này, để không bị sập ứng dụng, bị lỗi đóng gói hỏng tệp.
Hãy nhớ rằng dù cho đối tượng hay chuỗi hay mảng, hãy luôn luôn chú ý giải phóng biến hợp lý, các biến toàn cục luôn luôn cần giải phóng, như đặt biến đối tượng thành Nothing, Empty với biến chuỗi và Erase với mảng.
13. Viết mã vượt giới hạn trong VBA
Mỗi hàm, phương thức, module VBA chỉ cho phép số lượng ký tự nhất định. Viết vượt giới hạn sẽ gây ra lỗi đóng gói, dẫn đến tệp của bạn bị hỏng.
14. Tham chiếu quá nhiều thư viện trong VBA
Khi tham chiếu quá nhiều thư viện sẽ gây tốn kém, chính vì vậy hãy bỏ chọn các thư viện không dùng đến, đồng thời cũng nên khai báo theo kiểu khai báo muộn (Later binding) để tiết kiệm. Tham chiếu thư viện chỉ nên tận dụng tối đa khi chương trình cần tốc độ nhanh hơn trong một vài trường hợp.
15. Quên chạy lệnh Debug Compile
Lệnh Debug Compile giúp chạy trình kiểm lỗi để xử lý lỗi nhanh chóng. Chính vì vậy luôn chạy lệnh này sau khi hoàn thành một đoạn mã nhất định, hoặc vừa chép và dán mã.
Nếu bạn quên chạy lệnh này, về sau mã bị lỗi nhiều, chạy Debug sẽ mất thời gian sửa mã.
Lưu ý: Debug Compile thì trong component nên có khai báo tùy chọn Option Explicit
16. Lỗi thiếp lập Attribute bị mất khi sửa mã trong lớp (Class Module)
Trong lớp các thiết lập Attribute rất quan trọng, các Attribute luôn luôn bị ẩn, nếu Attribute được đặt trong một phương thức, bạn sửa, dán mã, thì các Attribute này bị xóa đi nhưng bạn không biết được. Đó là lỗi cơ bản khi lập trình với Lớp.
Để xử lý được các lỗi này các bạn cần có Tools VBA để xử lý nhanh chóng.
17. Khởi chạy các API gây ra sự cố đứng và sập ứng dụng
Vì VBA chạy trên một tiến trình đồng bộ, trong khi các API gọi lại ngay lập tức, VBA không đủ thời gian để xử lý kịp thời dẫn đến sự cố, ví dụ như các API: RtlMoveMemory, SetWindowSubclass, SetTimer, SetWindowHookEx, SetWinEventHook, sự kiện cửa sổ được khởi tạo với SetWindowLong, các API Http hỗ trợ WebSocket, các API thâm nhập sau vào hệ thống, ... rất nhiều. Chính vì vậy việc xử lý và tận dụng các dạng API này tối ưu nhất là rất cần thiết.
Nếu bạn nào có đam mê theo đuổi lập trình chuyên sâu thì học lập trình Thunk Code, là một trong những cấp độ lập trình cao nhất đi sâu vào máy tính để thực hiện chạy mã máy (Assembly). Vượt qua các lỗi lập trình API như được đề cập ở đây lập trình Thunk Code có thể giải quyết được vấn đề.
18. Xử lý tệp
Các bạn nên biết rằng tập tin có nhiều dạng đóng gói mã hóa như ANSI, UTF-8, UTF-8 BOM, UTF-16, UTF-16 BOM, ... Thì các hàm trong FileSytem của VBA có nhiều hạn chế để xử lý tập tin trong nhiều trường hợp đọc và ghi. Chính vì vậy các bạn nên chọn thư viện ADODB Stream để xử lý tệp, nếu có khả năng hơn, các bạn có thể tận dụng API để tự viết mã xử lý tệp.
Việc xử lý mã hóa chuỗi trong tập tin rất quan trọng, để việc bóc tách và ghi dữ liệu được chính xác tuyệt đối, các bạn cần tận dụng các hàm, các phương thức, các thư viện bổ trợ tốt để vượt qua vấn đề xử lý tệp.
19. Không lưu các dữ liệu quan trọng vào mã VBA và Registry
Các mật khẩu, Token chữ ký số, Mã số thẻ Ngân hàng, Token tài khoản online, Mã khôi phục, ... để đề phòng các trường hợp bất trắc có khả năng xảy ra, thì không nên lưu các dữ liệu dạng này.
Nếu bạn có khả năng viết mã mã hóa giải mã và lưu trữ vào các tệp DLL, các DLL đã được chống dịch ngược. Bạn có thể làm điều này.
20. Không hiểu sâu về toán tử bitwise và phép quay bit (NOT, AND, OR và XOR)
Các toán tử NOT, AND, OR và XOR trong VBA là rất quan trọng, đa số các bạn không tận dụng toán tử để xử lý các trường hợp liên quan đến bitwise và phép quay bit.
21. Không viết các khai báo hằng số hoặc Enum có dấu gạch nối
Cách viết này có thể gây ra lỗi biên dịch, ví dụ: Const NULL_PTR = 0, Nên viết là NULLPTR hoặc NULLxPTR.
Cách tránh viết mã bị xem là mã nguy hiểm và virus1. Không gõ từ khóa VBA trước các hàm VBA
Nhiều bạn hay nhập VBA.String, VBA.TRIM, ... Không nên nhập như vậy, các bạn có thể sử dụng từ khóa thứ hai sau từ khóa VBA, nhập nên là Strings.TRIM, Interaction.CreateObject, ....
2. Nhập đường dẫn URL, để gọi trong các thư viện HTTP
Cách ghi url như sau là nên tránh:
Const url = "https://www.youtube.com/"
Vì các từ khóa như http, https, www, com sẽ bị trình quét phát hiện, chúng xem các chuỗi dạng URL này là mã tiềm tàn.
Cách ghi url phân tách nhiều ghép nối như sau tránh được trình quét nhưng bất tiện:
Const url = "htt" & "ps://ww" & "w.youtube." & "com/watch?v=lOYMPAjZSos"
Tốt nhất là tạo hàm mã hóa và giải mã:
Dim url: url = DecodeText("47>83>97>110>98>105>86>78>47>84>97>120>67>111>100>101>86>78>47>114>101>108>101>97>115>101>115>47>116>97>103>47>11")
3. Tránh sử dụng các hàm API tương tác SYSTEM trực tiếp và tránh sử dụng API tải tệp từ URL
Các API được xem là API nguy hiểm có rất nhiều, nhưng có thể sử dụng các API đó với cách sau đây.
Trong VBA có 2 cách gọi các hàm API: gọi trực tiếp vào trong mã VBA, gọi các API trong DLL với bộ nhớ của các hàm API với các API hỗ trợ cách gọi này sẽ giúp tránh trình quét phát hiện các mã bị xem là mã nguy hiểm.
Các API nhúng mã, tim DLL vào ứng dụng cũng là các mã xem là mã nguy hiểm.
API URLDownloadToFile tải tệp bị xem là hàm nguy hiểm, hãy thay thế với thư viện WinHTTP, MSXML, MSXML2 để tải và ADODB Stream để lưu.
Các phương thức truy cập và chỉnh sửa Registry cũng nên chọn giải pháp tốt nhất để tránh trình quét.
4. Tránh sử dụng các Hàm VBA như Shell, Kill trong VBA
Ví dụ bạn gọi cửa sổ dòng lệnh cmd trong Shell như sau. Là cách gọi sai cách, trình quét sẽ phát hiện bạn gọi cmd.exe:
Shell "cmd.exe"
Hãy thay thế lệnh Shell với các hàm API bổ trợ.
Hãy mã hóa hoặc thêm & ngăn các từ thành nhiều lần như đã nói ở trên nếu bạn cần gọi lệnh Shell:
Shell "cm" & "d.e" & "xe" Hoặc Shell DecodeText("xxxxxxxxxxxxxxxxx")
Hãy thay thế các lệnh FileSystem VBA với thư viện FileSystemObject trong Microsoft Scripting Runtime: với lệnh như fso.GetFile(file).delete hoặc fso.FileDelete để xóa file hoặc fso.FolderDelete để xóa thư mục.
Các bạn có thể tận dụng hai hàm này, nếu các bạn biết về API, gọi hàm trực tiếp từ bộ nhớ.
5. Hạn chế viết mã trong Module mà hãy viết mã vào Class Module
Vừa tiết kiệm bộ nhớ trong nhiều trường hợp và vừa tránh bị xem là mã nguy hiểm trong một vài trường hợp gọi các hàm thực thi hay sử dụng các thư viện HTTP để gửi yêu cầu qua mạng.
6. Có nhiều thư viện bị trình quét xem là nguy hiểm nếu khởi tạo trong mã
Các thư viện như ScriptControl, HtmlFile, ... hãy tìm cách khác thay thế nếu có. Hoặc khởi tạo chúng với cách mã hóa như ở trên. Sử dụng phương thức CallByName nếu cần thiết để gọi một số phương thức bị xem là hàm nguy hiểm. Nếu các bạn biết về API hãy tận dụng API để gọi các thư viện thông qua bộ nhớ, cách này cũng có thể tránh trình quét.
Ví dụ tách các từ khóa thành chuỗi nhỏ và gọi trong CallByName:
JavaScript:
CallByName(Application,"Ver" & "si" & "on",vbMethod)
Các cách lập trình nên ứng dụng nhiều hơn
1. Luôn luôn thiết đặt Option cho component
Các cài đặt:
Option Explicit - đặt ràng buộc khai báo biến trước khi gọi.
Option Compare Text - đặt so sánh chuỗi trong mã thành không phân biệt Hoa thường.
Option Private Module - đặt các phương thức trong Module thành cục bộ.
2. Khi viết lượng mã quá lớn hãy tận dụng Define Name để khai báo biến tổng quát
Define Name giúp định nghĩa biến toàn diện khi viết mã
Khai báo như sau sẽ hiểu là các biến bắt đầu bằng ký tự khai báo đều hiểu là kiểu Long, thì các khai báo kiểu biến không phải là Long ký tự bắt đầu trùng với Define Name thì bắt buộc khai báo rõ ràng.
JavaScript:
DefLng A-C, W, Z
Dim b As Integer ' Vì b nằm trong khoảng A-C trùng Define Name
Dim b ' là khai báo sai
3. Tận dụng khai báo Enumrates
Vì Enum là khai báo tự động đánh số tuần tự, nên luôn luôn tận dụng Enum cho các giải thuật mà có tính tuần tự, ví dụ là thứ tự cột, thứ tự hàng, chỉ thị, ...
Để khi thay đổi, thêm thứ tự, đặt chỉ thị sẽ nhanh hơn, không phải bỏ thời gian sửa mã nhiều.
JavaScript:
Public Enum DirectionValues
DVL_value1 ' Bắt đầu tự động đánh số từ 0
DVL_value2 ' Tự động tăng lên là 1
DVL_value3 ' Tự động tăng lên là 2
End Enum
Public Enum OrderNumberValues
ONV_value1 = 5 ' Bắt đầu tự động đánh số từ 5
ONV_value2 ' Tự động tăng lên là 6
ONV_value3 ' Tự động tăng lên là 7
End Enum
Enum chỉ giới hạn lưu trữ là kiểu Long, nên nếu muốn khai báo số lớn hơn phải chuyển sang Const trong Win64 bit.
4. Khai báo tên biến càng ngắn càng tốt
Tại sao tôi lại khuyên bạn điều này. Vì sẽ giúp bạn đọc hiểu mã nhanh hơn, tuy nhiên bạn cần chú thích biến đó theo mục đích và chức năng.
Bạn hãy định nghĩa trong bộ não của bạn rằng các ký tự r, k, i, c, n, m, x, y nên khai báo cho số.
Các ký tự w, t, s, v là khai báo cho chuỗi, ....
Các ký tự o, p, g, ... định nghĩa cho đối tượng.
Các bạn nên khai báo với các ký tự dấu thay thế, để dễ đọc hơn.
Dim r%, k%, i%, c#, n&, m&, x&, y&
Dim w$, t$ s$, v$
Dim o, p, g
5. Viết chú thích
Không nên viết chú thích giải thuật cho riêng từng dòng mã, mà viết vào trên phương thức hoặc component. Điều này sẽ giúp đọc hiểu mã nhanh hơn về sau.
Nếu dự án lớn viết chú thích cho mọi khai báo, giải thuật, hàm, phương thức, ... là cần thiết đề về sau việc đọc lại mã để dễ hiểu.
6. Khai báo tiết kiệm bộ nhớ
Nên khai báo Dim, Const trong thủ tục, thay vì khai báo toàn cục để tiết kiệm chi phí lưu trữ bộ nhớ. Nếu biến và các hằng số được truy cập nhiều lần, liên tục thì nên khai báo toàn cục.
7. Hãy đặt phiên bản (version) cho hàm, phương thức, module, lớp, dự án của bạn.
Bạn nên đặt version để sau này sửa mã, dễ nhận diện là đã có thay đổi mới, nhận diện được các phiên bản cũ cần thay thế và nâng cấp.
Cách đặt tên phiên bản như v1.21, 1.2.0, 1.2.0a, 1.2.0b
8. Tổng quát khai báo các từ khóa tiếp đầu ngữ chung các thư viện thường dùng, các biến hay dùng
Nếu khai báo sẵn các thư viện như sau thì sau này có gặp lại giải thuật tương tự, dễ dàng tận dụng lại.
Mã dưới đây tôi sử dụng tiếp đầu ngữ các từ khóa hàm là 'glb' viết tắt cho Global, khi tận dụng hàm chỉ cần nhớ và gõ glb là hiểu đang cần truy cập thư viện toàn cục.
Định nghĩa các tiếp đầu ngữ rất quan trọng trong lập trình, nên hãy tận dụng tối đa sự thông thái của bộ não để định nghĩa.
Các tiếp đầu ngữ: glb - Global, chx - CheckBox, tbx - TextBox, rg - Range, sh - Sheet, ...
JavaScript:
Function glbFSO() As Object
Set glbFSO = CreateObject("Scripting.FileSystemObject")
End Function
Function glbDict(Optional ByVal CompareMode As Boolean) As Object
Set glbDict = CreateObject("Scripting.Dictionary")
glbDict.CompareMode = -CompareMode
End Function
Function glbADOStream() As Object
Set glbADOStream = CreateObject("ADODB.Stream")
End Function
Function glbADOConnect() As Object
Set glbADOConnect = CreateObject("ADODB.Connection")
End Function
Function glbADOCommand() As Object
Set glbADOCommand = CreateObject("ADODB.Command")
End Function
Function glbADORecordset() As Object
Set glbADORecordset = CreateObject("ADODB.Recordset")
End Function
Function glbADOCatalog() As Object
Set glbADOCatalog = CreateObject("ADOX.Catalog")
End Function
Function glbADOTable() As Object
Set glbADOTable = CreateObject("ADOX.Table")
End Function
9. Tận dụng tối đa lập trình mã trong lớp (Class Module)
- Lớp trong VBA hỗ trợ thiết lập Attribute cho hàm, cho biến và cho lớp, các thiết lập Attribute hữu dụng trong nhiều trường hợp khác nhau, module thì không hỗ trợ nhiều các thiết lập này.
- Lớp cho phép tạo một hàm với Property Gán, Đặt đối tượng và truy cập với một từ khóa duy nhất, thay vì phải bỏ ra 3 tên hàm khác nhau để đạt Gán, Đặt đối tượng và truy cập.
- Lớp hỗ trợ khai báo Event để trả về sự kiện cho lớp truy cập và hàm bổ trợ là RaiseEvent.
- Lớp hỗ trợ tạo sự kiện lớp, thư viện với WithEvents.
- Lớp hỗ trợ Implements để nhúng một lớp vào lớp.
- Lớp hỗ trợ tạo hàm Friend để khai báo các khai báo Type.
10. Tham khảo hàm, phương thức, thư viện và thuật toán được chia sẻ qua mạng
Hãy tìm kiếm Google, Github để tìm những dự án, phương pháp cần thiết hỗ trợ cho lập trình. Chớ bỏ nhiều công sức viết ra dự án mới tương đương các dự án đó. Về sau các bạn có thể đọc hiểu và phát triển thêm.
Trên đây tôi chỉ đề cập qua các điều nên biết liên quan đến VBA, không đề cập đến lỗi lập trình ứng dụng Excel, Word, Access, PowerPoint, có thời gian tôi sẽ mở chủ đề mới nếu được.
Chúc các bạn thành công!
Các bạn có thể tham khảo Tools liên quan đến lập trình mã VBA để học và viết mã nhanh chóng hơn
VBA_FastCode v2.22 - Công cụ học và viết mã VBA một cách nhanh nhất (*27/10/2023)
***** CẬP NHẬT MỚI v2.2 ***** -------------------------------------------------------------------------- Add-in được chia sẻ dưới đây, đó là những gì tôi hiểu biết về VBA và đã viết ra nó. Một Add-in Tools chỉnh sửa code VBA rất đơn giản nhưng có thể giúp các bạn học VBA và viết code nhanh...
giaiphapexcel.com
(Bài viết sẽ còn tiếp tục cập nhật thêm)
Dưới đây là hai tệp đính kèm lớp StringBuilder để ghép chuỗi. Và JsonConvert để tách và tạo dữ liệu json mà tôi đã tối ưu và cải tiến, các bạn có thể tải về để tham khảo. Tải về và đổi tên .txt thành .cls để import vào VBA.
File đính kèm
Lần chỉnh sửa cuối: