Khái niệm và cách sử dụng biến số từ cơ bản tới nâng cao

Trạng thái
Không mở trả lời sau này.

Euler

Administrator
Thành viên BQT
===========
PHẦN CƠ BẢN
===========
Bài 1: Cách sử dụng biến số
Cách sử dụng biến số nhìn chung có 3 bước như sau:
1. Khai báo biến số
2. Nạp giá trị cho biến số
3. Sử dụng giá trị của biến số

Biến số nhất định phải khai báo. Một lần nữa tôi xin nhấn mạnh, nhất định phải khai báo biến số.
Khi cài Excel, ở chế độ mặc định, trong VBA, dù bạn không khai báo biến số, VBA vẫn có thể hoạt động. Tuy nhiên, bạn cần ý thức rằng, việc khai báo biến số là rất quan trọng. Ở các bài viết sau, diễn đàn sẽ giới thiệu các bạn cách thiết định Excel để bắt buộc phải khai báo đầy đủ biến số.

Nạp giá trị cho biến số
Ví dụ ta viết như thế này:
Mã:
tmp = 100
Đây là phép gán, biến số tmp sẽ được nạp dữ liệu là 100. Đây không phải là phép so sánh, mà ở đây ta gán giá trị 100 cho biến số tmp.
Tương tự như thế, ta viết:
Mã:
tmp = tmp + 1
Điều này có nghĩa là, giá trị hiện tại của tmp nếu đang là 100 thì với cách viết trên, tmp sẽ tăng lên 1 đơn vị, tức là nó sẽ mang giá trị là 101.

Sử dụng giá trị của biến số
Ta có ví dụ như thế này:
Mã:
tmp = 100
Range("A1") = tmp
Dòng code thứ nhất ta thực hiện phép gán, tmp sẽ mang giá trị là 100.
Ở dòng code thứ hai, ta sử dụng dữ liệu của biến số, ô A1 được gán bằng tmp tức là ô A1 sẽ mang giá trị 100.

Ta có một ví dụ tiếp theo:
Mã:
tmp = "tuhocvba.net"
Range("A1") = "tmp"
Ô A1 lúc này không phải là chuỗi ký tự tuhocvba.net mà ô A1 là ký tự tmp.
Các bạn chú ý "tmp" là chuỗi ký tự tmp. Khi nó được viết trong dấu ngoặc kép như trên thì đó là chuỗi ký tự tmp chứ không phải là biến số tmp.
Bài viết trên được dịch và tham khảo từ:
 
Sửa lần cuối:

tuhocvba

Administrator
Thành viên BQT
===========
PHẦN CƠ BẢN
===========
Bài 2: Khai báo biến số
Làm thế nào để chương trình của chúng ta luôn khai báo biến số đầy đủ. Để làm điều đó, chúng ta hãy thiết định VBE (nơi soạn thảo viết code macro trên excel) để làm sao nếu mà không khai báo biến số đầy đủ thì chương trình không chạy được.

Cưỡng chế bắt buộc phải khai báo biến số
Chúng ta khởi động VBE, vào Tool -> Option -> Editor
Tích chọn vào dòng Require Variable Declaration (dòng thứ hai từ trên xuống)
Bạn cần đăng nhập để thấy đính kèm


Bây giờ, khi chúng ta thêm mới Module, ở trên đầu sẽ tự động được chèn dòng lệnh “Option Explicit

Bạn cần đăng nhập để thấy đính kèm



Lý do khai báo biến số

Sẽ có người phàn nàn rằng: Không khai báo biến số đầy đủ thì chương trình vẫn chạy được. Vậy tự mình làm khó mình làm gì? Tại sao phải cưỡng chế khai báo biến số?

Có rất nhiều lý do về việc nên khai báo biến số nhưng quan trọng hơn tất cả, đó chính là vì bản thân chính chúng ta. Ở ví dụ trên, nếu chúng ta không khai báo biến số đầy đủ, thì VBA vẫn hiểu và chạy được chương trình.

Bây giờ ta hãy xem xét ví dụ dưới đây:

Mã:
Sub Sample1()
    giatri = 100
    N = giatri * 2
    Message = "Cau tra loi la: " & N & " dung chua nao? ^_^"
    MsgBox Mesaag
End Sub
[giatri],[N],[Message] không hề được khai báo trong chương trình, và khi biên dịch, VBA cứ lặng lẽ tự hiểu và chạy. Bạn hãy thử copy đoạn code trên và tự kiểm nghiệm kết quả xem nào.

Kết quả chắc chắn là ngoài màn hình chẳng hiển thị ra cái gì.
Bạn cần đăng nhập để thấy đính kèm

Hãy nhìn rõ đi, ở đoạn code trên ta đã ghi rằng: Message = "Cau tra loi la: " & N & " dung chua nao? ^_^"

Và thứ mà Msgbox hiển thị ra chính là biến số có tên là Mesaag.

Đây là lỗi, tuy nhiên, chương trình trên bất chấp lỗi, vẫn chạy và kết thúc bình thường. Tại thời điểm thực thi dòng code “Msgbox Mesaag”, VBA đã hiểu rằng Mesaag là một biến số mới.

Ở ví dụ trên ta thấy rằng, vì nó là macro, cho nên nó không thể nào hiểu được đâu là lỗi sai đánh máy của con người. Đấy là mới chỉ vài dòng code thôi, khi chương trình lên tới vài trăm dòng code, nếu xảy ra lỗi đánh máy sai tên biến số, thì sẽ như thế nào đây?

Chẳng có lỗi nào xuất hiện, cho nên việc phát hiện ra lỗi đánh máy sai tên biến là rất khó, có lẽ là chỉ có thể căng mắt ra và nhìn chăm chú từng ly từng tý vào mỗi dòng code để mà kiểm tra!

Chúng ta thay đổi cách nghĩ một chút, không phải là làm thế nào để không có lỗi, mà ngược lại, làm thế nào để khi có lỗi thì dễ phát hiện ra để còn sửa?

Và khi chúng ta cưỡng chế bắt buộc khai báo tên biến, thì chúng ta dễ dàng phát hiện ra lỗi sai đánh máy tên biến ngoài ý muốn như dưới đây:

Bạn cần đăng nhập để thấy đính kèm


Cũng có trường hợp chúng ta không khai báo tên biến, mà thay vào đó sử dụng các chú giải chú thích biến này là gì, dùng làm gì… Nhất là khi có nhiều biến, các chú giải chú thích có khi kéo dài lê thê, và lúc ấy ta thấy viêc khai báo biến sao mà phiền hà đến thế. Và điều này trở thành lý do cho việc không xây dựng môi trường cưỡng chế phải khai báo biến! Tuy nhiên, tôi vẫn khuyên các bạn hãy thực hiện khai báo biến đầy đủ.

Lý do người mới học VBA không khai báo biến

Một số người thắc mắc: Này, tại sao chúng ta không khai báo biến đi nhỉ! Là vì, thỉnh thoảng chính vì khai báo biến mà sinh ra lỗi đấy nhé. Mà không khai báo biến thì chương trình lại chạy được!

Họ đúng là chẳng hiểu gì cả, nguyên nhân lỗi thật ra không phải là vì bạn đã khai báo biến, mà là vì, bạn đã chỉ định sai kiểu dữ liệu cho biến khi khai báo biến.

Đối với biến số, tùy thuộc vào kiểu dữ liệu mà nó chứa, kiểu dữ liệu sẽ được định nghĩa khác nhau. Tôi ví dụ, nếu là số nguyên, thì nó phải là kiểu integer hoặc Long. Chú ý phạm vi của integer chỉ khoảng hơn 30.000, trong khi Long là hơn 2 triệu. Nếu là ký tự thì kiểu của nó phải là String…

  • Thử khai báo kiểu dữ liệu cho biến số xem sao


  • Có lỗi xảy ra, mình chẳng hiểu gì cả


  • Không hiểu nguyên nhân lỗi là do chỉ định sai kiểu dữ liệu cho biến số


  • Thôi được rồi, không khai báo biến số nữa cho khỏi lỗi nhé, hihi <= Đây là hiện trạng


Đúng là khó nhỉ. Việc chỉ định kiểu dữ liệu cho biến số không dễ chút nào. Nhưng đó không phải là vì bạn khai báo biến số mà chương trình bị lỗi. Bạn không hiểu kiểu biến nên chỉ định kiểu dữ liệu nào cho biến số nên dẫn tới sai. Việc giản lược khai báo kiểu giá trị cho biến số trong trường hợp này thật ra là hơi thô nhưng rất hiệu quả!

Bạn chỉ cần giản lược chỉ định kiểu dữ liệu cho biến số là được.

Mã:
Option Explicit
Sub tuhocvba()

    Dim s ‘Khai báo đầy đủ phải là:

              ‘Dim s as string

              ‘Nhưng giản lược đi kiểu biến thì cũng không sao đâu

    s = "tuhocvba.net"

    MsgBox s

End Sub
Cách khai báo biến

Mã:
Dim tên_biến As kiểu_biến
Nếu như bạn phân vân không biết khai báo kiểu biến như thế nào mới là phù hợp, hãy giản lược đi, không sao đâu.

Mã:
 Dim tên_biến
Khi khai báo nhiều biến số, bạn có thể viết cùng một dòng và dùng dấu phẩy “,” để phân cách.

Mã:
 Dim X As Long, Y As Long
Nó tương đương với cách viết sau:

Mã:
Dim X As Long

Dim Y As Long
Cả hai cách viết trên, VBA đều hiểu là X,Y có kiểu là Long.

Bây giờ hãy chú ý cách viết dưới đây:

Mã:
Dim A,B,C As Long
Với khai báo này, VBA hiểu chỉ có C là Long, còn A,B là các biến bị giản lược khi khai báo kiểu, cho nên mặc định VBA hiểu A,B có kiểu là Variant.

Bạn đọc lưu ý, khai báo biến không chỉ có Dim, ta còn có những khai báo khác như:

Public X As Long

Private X As Long

Static X As Long

Và những nội dung này sẽ được trình bày sau. Bài học hôm nay đến đây là kết thúc rồi.

Nguồn tham khảo:
 

giaiphapvba

Administrator
Thành viên BQT
===========
PHẦN CƠ BẢN
===========
Bài 3: Không khai báo kiểu dữ liệu cũng được
Trước hết chúng ta nhắc lại các kiểu dữ liệu hay được dùng trong VBA
TênKiểu dữ liệu khai báo trong VBAVùng giá trị
LogicBooleanTrue, False
ByteByteSố nguyên 0 đến 255
Số nguyênIntegerSố nguyên -32,768~32,767
Số nguyênLongSố nguyên -2,147,483,648~2,147,483,647
Tiền tệCurrencySố thập phân -922,337,203,685,477.5808 ~ 922,337,203,685,477.5807
Số thập phânSingleSố âm nằm trong khoảng-3.4×10(E38)~-1.4×10(E-45)
Số dương nằm trong khoảng 1.4×10(E-45)~1.8×10(E38)
Số thựcDoubleSố âm nằm trong khoảng -1.8×10(E308)~-4.0×10(E-324)
Số dương nằm trong khoảng 4.9×10(E-324)~1.8×10(E308)
Ngày thángDateNgày tây lịch Năm 100 tháng 1 ngày 1~Năm 9999 tháng 12 ngày 31
Giờ 0:00:00 ~ 23:59:59
Ký tựStringĐộ dài tùy ý
Đối tượngObjectĐối tượng
VariantVariantTất cả các kiểu dữ liệu bất kỳ

Kiểu dữ liệu mà chúng ta hay dùng:
Hai kiểu dữ liệu mà các bạn hay dùng nhất là LongString.

Ta hãy xem ví dụ sau:
Mã:
Sub Sample2()
    Dim tmp As Long
    tmp = 10 / 4
    MsgBox tmp
End Sub
Bạn cần đăng nhập để thấy đính kèm

10 chia cho 4, kết quả phải là 2.5 mới đúng, tuy nhiên trong trường hợp trên, do tmp khai báo là số nguyên (Long) vì vậy mà Excel đã tự ý làm tròn và trả về kết quả là 2.
Bây giờ nếu ta sửa lại khai báo kiểu dữ liệu cho tmp:
Mã:
Sub Sample2()
    Dim tmp As Single
    tmp = 10 / 4
    MsgBox tmp
End Sub
Bạn cần đăng nhập để thấy đính kèm


Không khai báo kiểu biến cũng được
Với người mới học, đây quả là điều phiền não. Làm thế nào để khai báo đúng kiểu biến bây giờ?
Bây giờ nếu chúng ta nhin lại bảng biểu ở trên, ta thấy rằng kiểu biến variant thích hợp cho mọi loại dữ liệu. Vậy thì cứ khai báo Variant là xong, việc gì phải đau đầu nữa.
Nếu bạn không biết phải khai báo kiểu biến nào thì phù hợp, trong trường hợp đó khai báo là variant cũng được, không sao đâu.
Cũng có người nói một cách thô bạo, thế thì khác gì là không khai báo biến. Quả đúng là nó mang ý nghĩa như vậy. Tuy nhiên, thay vì nghĩ như thế, ta thay đổi một chút, là ta sẽ khai báo biến nhưng để kiểu biến là Variant.
Dim tên_biến As Variant
Các viết trên và cách viết dưới đây là tương đương nhau.
Dim tên_biến
Chúng ta cố gắng khai báo kiểu dữ liệu cho biến trong khả năng mà chúng ta biết, với các biến mà chúng ta chưa định hình được kiểu dữ liệu nào là thích hợp, thì bạn có thể chỉ định cho nó là Variant, không sao cả. Chúng ta tiếp tục học VBA để mở rộng kiến thức, đừng vì việc này mà làm nản lòng việc học tập của các bạn, nhé.

Một số phiền muộn về variant
Có hai điểm dưới đây mà mọi người hay phàn nàn về variant:
-Làm cho tốc độ chương trình chạy chậm.
-Có thể là nguyên nhân dẫn tới thao tác sai.
Về tốc độ, chúng ta sẽ làm rõ trong bài test dưới đây:
Mã:
Declare Function GetTickCount Lib "kernel32" () As Long
Sub Sample6()
    Dim i As Long, ST As Long
    ST = GetTickCount
    For i = 1 To 10000
        Cells(i, 1) = i
    Next i
    MsgBox (GetTickCount - ST) / 1000
End Sub
Sub Sample7()
    Dim i As Variant, ST As Long
    ST = GetTickCount
    For i = 1 To 10000
        Cells(i, 1) = i
    Next i
    MsgBox (GetTickCount - ST) / 1000
End Sub
Kết quả Sample6:
Bạn cần đăng nhập để thấy đính kèm

Kết quả Sample7:
Bạn cần đăng nhập để thấy đính kèm

Thế hệ máy tính bây giờ làm việc với biến variant rất tốt, chúng ta nhận thấy không có khác biệt về tốc độ.

Tóm lại, chỉ định chính xác kiểu biến thì tốt, nhưng không biết khai báo kiểu biến nào phù hợp, thì cũng không cần phải làm việc quá sức của bạn, cứ khai báo Variant. Rồi mai này kiến thức VBA của bạn nhiều hơn, bạn sẽ biết mình khai báo kiểu biến nào thì tốt hơn. Đừng lo lắng gì nhé.
Tham khảo thêm kiểu biến ở đây:
Nguồn tham khảo:
 

tuhocvba

Administrator
Thành viên BQT
===========
PHẦN CƠ BẢN
===========
Bài 4: Trường hợp nào phải dùng Set?
Khi gán giá trị cho biến số, ta sử dụng ký hiệu “=”, ở macro dưới đây ta sẽ thực hiện phép gán giá trị “tuhocvba.net” cho biến số tmp như sau:
Mã:
Sub Sample13()
    Dim tmp As String
    tmp = "tuhocvba.net"
    MsgBox tmp
End Sub
Giốn như trên, ta đi đến định nghĩa là, để gán giá trị cho biến số, ta sử dụng dấu “=” và giá trị nằm bên phải của dấu “=” là giá trị sẽ được nạp cho biến số.
Thế nhưng, khi chúng ta sử dụng mệnh lệnh Set tên_biến_số = giá trị, thì nó có nghĩa gì?
Mã:
Sub Sample14()
    Dim ws As Worksheet
    Set ws = Sheets("Sheet1")
    MsgBox ws.Name
End Sub
Set ws = Sheets("Sheet1") có nghĩa là chúng ta ra lệnh gán giá trị của ws là Sheet1. Biến số ws được chỉ định khai báo là As Worksheet, kiểu biến này khác với kiểu chúng ta thường thấy như Long, String, biến số ws ở đây như là một đối tượng (Object), do đó chúng ta gán giá trị cho nó thì giá trị ấy cũng phải là một đối tượng (Object). Với biến số Object thì ta sẽ sử dụng cấu trúc khai báo kiểu As Object Name . Worksheet là một đối tượng Object, nơi có rất nhiều thuộc tính và phương thức, do đó ta khai báo là As Worksheet, tương tự như thế nếu là Workbook thì ta khai báo là As Workbook, nếu là cells hay Range thì ta khai báo là As Range, một cách tổng quát, khi nào sử dụng một đối tượng (Object), không cần biết nó là loại đối tượng gì, bất cứ đối tượng nào thì bạn cũng có thể khai báo một cách chung nhất là As Object.
Và trong trường hợp làm việc với đối tượng (Object) thì ta phải sử dụng Set để gán giá trị cho nó.
Đối với biến số Object, chúng ta sẽ có bài viết trình bày kỹ hơn, diễn đàn sẽ giới thiệu sau.
Nguồn tham khảo và dịch từ:
 

vbano1

SMod
Thành viên BQT
===========
PHẦN CƠ BẢN
===========
Bài 5: Phạm vi sử dụng của biến số
Tùy thuộc vào cách khai báo biến số mà phạm vi sử dụng của biến số sẽ bị giới hạn khác nhau, ta gọi đó là phạm vi sử dụng của biến số.
Để hiểu phạm vi sử dụng của biến số, ta cần hiểu rõ khái niệm thủ thục và Module.
Thủ tục là đơn vị nhỏ nhất của macro có thể thực thi một nhiệm vụ nào đó một cách độc lập, được khai báo như là
Sub ○○~End Sub hoặc là Function ○○~End Function.
Nếu tôi không nhầm, trong sách VBA cơ bản của tác giả Phan Tự Hướng có đặt hai cái tên khác nhau:
Với Sub... End Sub thì được gọi là thủ tục.
Với Function.... End Function thì được gọi là hàm.
Trong bản dịch này của chúng tôi, thì chúng được gọi chung là thủ tục mà không có sự phân biệt thủ tục và hàm, và chúng tôi (diễn đàn tuhocvba.net) thấy điều này không ảnh hưởng tới kiến thức trong bài dịch này và cũng không ảnh hưởng tới kiến thức VBA cơ bản nói chung.


Mã:
''Ta có hai thủ tục 「Sample1」「Sample2」
''và thủ tục Function「myCalc」
Sub Sample1()
    ''Xử lý gì đó ở đây
End Sub
Sub Sample2
    ''Xử lý gì đó ở đây
End Sub
Function myCalc(n As Long)
    ''Xử lý gì đó ở đây
End Function
Module là nơi để viết các thủ tục. Thông thường chúng ta thường viết các thủ tục trên Module Standard (sau đây gọi là Module tiêu chuẩn).
Module tiêu chuẩn là Module mà bạn tạo ra bằng cách Insert Module. Ngoài Module tiêu chuẩn, chúng ta thấy còn có rất nhiều loại Module khác nhau.
Bạn cần đăng nhập để thấy đính kèm

Module của sheet, Module của Book... : các Module mà ta có thể viết code theo sự kiện cho sheet hoặc cho Book, ta gọi chung chúng là Document Module. Ngoài ra chúng ta có tên gọi khác như là Module sheet, Module book.
Ngoài ra đối với UserForm ta còn có Module Form.

Biến số chỉ được dùng bên trong thủ tục:
Mã:
Sub Sample15()
    Dim buf As String
    buf = "tuhocvba.net"
End Sub
Đối với khai báo như trên, thì biến số buf chỉ được sử dụng bên trong thủ tục Sample15.
Mã:
Sub Sample16()
    Dim buf As String
    buf = "tuhocvba.net xin chao cac ban"
End Sub
Sub Sample17()
    MsgBox buf  ''Không thể sử dụng biến số này, sẽ sinh ra lỗi
End Sub
Biến số chỉ có thể sử dụng bên trong thủ tục, ta gọi là biến số cấp độ thủ tục.
Bạn thích gọi tên là gì cũng được, nhưng hiểu ý nghĩa của nó là quan trọng, nó chỉ có tác dụng bên trong thủ tục khai báo nó.

Tất cả các thủ tục đều có thể sử dụng chung biến số:
Vậy, trong trường hợp, cùng một biến số, nhưng tất cả các thủ tục đều có thể sử dụng nó, thì phải làm thế nào? Trong trường hợp này, chúng ta phải khai báo biến số ở trên đầu Module.
Mã:
Dim buf As String
Sub Sample18()
    buf = "tuhocvba.net"  ''Có thể sử dụng biến số này
End Sub
Sub Sample19()
    MsgBox buf  ''Có thể sử dụng biến số này
End Sub
Biến số được khai trên đầu Module A thì toàn bộ các thủ tục trong Module A có thể sử dụng biến số đó. Ta gọi là biến số cấp độ Module.
Bạn gọi tên là gì cũng được, nhưng hãy nhớ ý nghĩa này.

Tất cả các Module đều có thể sử dụng chung biến số:
Ta mở rộng quan điểm ra một chút, bây giờ, chúng ta có Module tiêu chuẩn 1, Module tiêu chuẩn 2. Chúng ta khai báo biến số cấp độ Module trên Module tiêu chuẩn 1 thì toàn bộ các thủ tục của Module tiêu chuẩn 1 đều có thể sử dụng biến số đó. Tuy nhiên Module tiêu chuẩn 2 thì lại không sử dụng được.
Bạn cần đăng nhập để thấy đính kèm

Bây giờ, chúng ta muốn sử dụng trên Module tiêu chuẩn 2, thì ta phải khai báo Public.
Bạn cần đăng nhập để thấy đính kèm

Khi khai báo như vậy thì mọi thủ tục trên tất cả các Module đều có thể sử dụng nó. Ta gọi là biến số public. Bạn gọi tên là gì cũng được, nhưng hãy nhớ ý nghĩa này của nó.

Suy nghĩ khai báo phạm vi sử dụng biến số cho thích hợp:
Khi suy nghĩ về phạm vi sử dụng biến số, hãy xem xét mức độ phù hợp để khai báo tương ứng. Nếu như biến số nào cũng khai báo Public để cho dễ sử dụng thì đó là điều không nên. Hãy xem ví dụ dưới đây:
Mã:
Sub Sample20()
    Dim i As Long, buf As String
    buf = InputBox("Tên sheet là?")
    For i = 1 To Worksheets.Count
        Worksheets(i).Name = buf & i
    Next i
End Sub
Sub Sample21()
    Dim i As Long, buf As String
    For i = 1 To 10
        buf = Cells(i, 1)
        If Left(buf, 1) = "A" Then
            Cells(i, 3) = "OK"
        End If
    Next i
End Sub
Cả hai thủ tục trên đều có các biến số là ibuf nhưng chúng chẳng liên quan gì nhau. Chúng nằm riêng rẽ và chỉ có vai trò trên các xử lý của các thủ tục mà chúng được khai báo. Nhưng bây giờ, nếu chúng ta thay đổi chúng từ biến số cấp độ thủ tục, chuyển sang biến số cấp độ Module:
Mã:
Dim i As Long, buf As String
Sub Sample22()
    buf = InputBox("Tên sheet là?")
    For i = 1 To Worksheets.Count
        Worksheets(i).Name = buf & i
    Next i
End Sub
Sub Sample23()
    For i = 1 To 10
        buf = Cells(i, 1)
        If Left(buf, 1) = "A" Then
            Cells(i, 3) = "OK"
        End If
    Next i
End Sub
Khi khai báo như trên, thì biến số của cả hai thủ tục có mối liên quan với nhau, đây sẽ là nguyên nhân nảy sinh ra những lỗi không cần thiết. Tóm lại, hãy cân nhắc trường hợp nào nên sử dụng biến dùng chung (ở cấp độ Module, hay Public), bởi vì nếu sử dụng không đúng, có thể tạo nên lỗi không mong muốn.
Tham khảo và dịch từ:
 

Euler

Administrator
Thành viên BQT
===========
PHẦN CƠ BẢN
===========
Bài 6: Đặt tên biến số
1. Qui định:

Có những qui định khác nhau về đặt tên biến số, dưới đây tôi tổng hợp các chú ý để biến số của các bạn sử dụng ở bất cứ đâu.
Chẳng hạn, người Nhật họ có thể đặt tên biến số bằng tiếng nhật, tuy nhiên, khi mang sang máy tính như của các bạn thì không sử dụng được, sẽ báo lỗi. Đối với chương trình, điều như vậy là không nên, chúng ta cố gắng làm sao để chương trình chạy được ở bất cứ máy tính nào, đó là điều lý tưởng nhất.
Một là, các bạn sử dụng các ký tự tiếng anh để đặt tên biến, tuyệt đối không sử dụng tiếng việt có dấu.
Hai là, không sử dụng dấu cách, tên biến số phải là chuỗi ký tự viết liền nhau. Các bạn có thể sử dụng dấu gạch nối. Ví dụ: chu_vi.
Chú ý, ký tự đầu tiên phải là chữ, ví dụ bạn đặt tên biến như sau là sai: _chu_vi .
Ba là, không đặt tên biến trùng nhau.
Bốn là, tên biến có độ dài tối đa là 255 ký tự.


Điều số bốn có lẽ các bạn không cần quan tâm, vì thường chúng ta không đặt tên biến dài như vậy bao giờ.
Ba điều đầu tiên, chúng ta sẽ nhận được hỗ trợ của VBE, nó sẽ báo lỗi khi bạn cố biên dịch chạy chương trình.
Ví dụ:
Tôi chưa cần chạy chương trình thì VBE đã báo lỗi khi tôi gõ khai báo tên biến.
Bạn cần đăng nhập để thấy đính kèm

Tôi sử dụng dấu gạch nối ở đầu tên biến "_buf" và lập tức VBE báo lỗi ký tự không đúng.

Lỗi dưới đây là tôi sử dụng tên biến trùng nhau. Khi chạy chương trình nó báo lỗi nội dung là tên biến đang bị trùng nhau.
Bạn cần đăng nhập để thấy đính kèm


2. Góp ý:
Nên đặt tên biến số có tính gợi nhớ, dù là tiếng việt không dấu hay tiếng anh đều được, tối thiểu là bạn hiểu nó khi xem lại, biến đó có ý nghĩa gì. Lý tưởng hơn là người khác xem, họ cũng hiểu ý nghĩa của biến đó.
buf:
Các xử lý trung gian, lưu tạm giá trị vào biến, thì người ta thường đặt tên biến là buf, nó là từ viết tắt của từ Buffer nghĩa là vật đệm, vật trung gian.
Mã:
Dim buf As String
buf = Range("A1")
tmp, temp:
Nếu dùng trong một thời điểm ngắn nào đó, không có tính lâu dài thì thường người ta sẽ đặt tên biến là tmp hoặc temp. Nó là từ viết tắt của Temporary ,nghĩa là tạm thời.
Mã:
Dim tmp As Variant
tmp = Split(buf, ",")
if tmp(1) = "" Then Exit Sub
i,j,k:
Với các biến có sự lặp đi lặp lại sử dụng trong vòng lặp, ví dụ sử dụng cho For ~ Next thì người ta thường sử dụng tên biến i,j,k. i là viết tắt của Iteration nghĩa là sự lặp đi lặp lại. j,k là các chữ cái tiếp theo sau chữ i trong bảng chữ cái.
Mã:
Dim i As Long, j As Long
For i = 1 To 10
    For j = 2 To 5
        Cells(i, j) = "tuhocvba.net"
    Next j
Next i
cnt:
Khi cần đếm sự kiện nào đó, người ta thường đặt tên biến là cnt, nó là từ viết tắt của Counter , nghĩa là đếm.
Mã:
Dim i As Long, cnt As Long
For i = 1 To 100
    If Cells(i, 1) = "tuhocvba.net" Then
        cnt = cnt + 1
    End If
Next i
MsgBox "tuhocvba.net xuat hien " & cnt & " lan."
msg:
Chúng ta lưu chuỗi ký tự muốn hiển thị thông báo tới người dùng thì sẽ đặt tên biến là msg. Nó là từ viết tắt của Message nghĩa là tin nhắn.
Mã:
Dim msg As String, buf As String
msg = "Hay nhap dia chi nha ban" & vbCrLf & _
      "Neu o Ha Noi thi chi can nhap ten Quan" & vbCrLf & _
      "O noi khac thi phai nhap ca ten Tinh, Huyen"
buf = InputBox(msg)
If buf = "" Then Exit Sub
msg = "Dia chi la " & vbCrLf & buf & " dung khong?" & vbCrLf & _
      "Ban co the thay doi dia chi nay."
MsgBox msg, vbInformation
flag:
Khi xét điều kiện logic là YES hoặc NO thì người ta thường đặt tên biến là flag. Nó có nghĩa là cờ.
Mã:
Dim flag As Boolean
If Cells(1,1) > 10 then
 flag = True
Else
 flag = False
End if
n:
Nếu chúng ta muốn sử dụng biến số để lưu giá trị là số, việc sử dụng có tính nhất thời, không phải là lâu dài, thì thường đặt tên biến là n. Nó là từ viết tắt của chữ Number nghĩa là số.
Mã:
Dim n As Long, i As Long
n = Cells(Rows.Count, 1).End(xlUp).Row
If n > 1 Then
    For i = 2 To n
        Cells(i, 1).Font.ColorIndex = 3
    Next i
End If
Sử dụng tiếp đầu ngữ khi đặt tên biến:
Có một lời khuyên rằng, nên đặt tên biến sử dụng tiếp đầu ngữ gợi nhớ kiểu dữ liệu của biến.
Ta ví dụ, nếu ta muốn đặt một biến sử dụng tạm thời là buf, và kiểu dữ liệu của biến này là String, thì khi đó tên biến nên đặt là strbuf.
Hoặc số nguyên sử dụng tạm thời, thì ta có intbuf.

Tham khảo và dịch từ:
 

Euler

Administrator
Thành viên BQT
========
PHẦN NÂNG CAO
========
Bài 7: Mảng là gì?

Với biến số thông thường, ta chỉ có thể nạp vào nó một giá trị. Ví dụ đoạn code dưới đây, chúng ta khai báo biến buf là kiểu chuỗi ký tự. Đầu tiên, tôi cất giá trị “tuhocvba.net” vào biến số buf, tiếp theo tôi cất vào đó giá trị “la website VBA” thì giá trị “tuhocvba.net” bị xóa mất đi.
Mã:
Sub Sample29()
    Dim buf As String
    buf = "tuhocvba.net"
    MsgBox buf          ''tuhocvba.net --- se duoc hien thi
    buf = "la website VBA"
    MsgBox buf          ''la website VBA --- se duoc hien thi
End Sub
Mỗi một biến số chỉ có thể nạp vào đó một giá trị. Nếu ta nạp giá trị vào biến số, thì giá trị được cất vào trước đó sẽ bị xóa đi. Ví dụ, mỗi biến số là một căn phòng, trong căn phòng có gia đình sinh sống, ví dụ “gia đình anh A”, “gia đình anh B”,…

Nếu chúng ta chỉ có một căn phòng, nếu gia đình anh B chuyển đến, thì gia đình anh A phải dọn đi.
Bạn cần đăng nhập để thấy đính kèm

Bây giờ, chúng ta muốn cất nhiều giá trị vào nhiều biến số, tương tự như nhiều gia đình có thể cùng sinh sống mà không xảy ra tình trạng phải dọn đi như trên.
Như vậy, mảng sẽ giống như một căn hộ chung cư, ở đó có rất nhiêu căn phòng. Nhiều gia đình có thể cùng sinh sống ở đó.
Bạn cần đăng nhập để thấy đính kèm

Để sử dụng mảng thì điều đầu tiên là khai báo mảng. Điều này cũng giống như biến số.

Mã:
Sub Sample30()
    Dim giadinh(3) As String
    giadinh(1) = "Gia Dinh A"
    giadinh(2) = "Gia Dinh B"
    giadinh(3) = "Gia Dinh C"
    MsgBox "Can phong so 2 la " & giadinh(2) & " sinh song."
End Sub
Ở trên ta viết [Dim giadinh(3) As String] có nghĩa là ta khai báo mảng như là biến số có tên là [giadinh], đồng thời mảng này được định nghĩa là có 3 phần tử (3 căn hộ) vì chúng ta đã viết [giadinh(3)].

Thực hiện phép gán cho mảng, ta dùng toán tử “=” giống như với biến số thông thường. Ta nhất định phải chỉ định số thứ tự trong mảng (căn hộ số bao nhiêu). Khi ta viết [giadinh(2) = "Gia Dinh B"], thì điều đó có nghĩa là căn hộ số 2 sẽ chứa “Gia Dinh B”.

Căn hộ đầu tiên trong mảng là căn hộ số 0.

Chúng ta viết [Dim giadinh(3) As String] có nghĩa là mảng giadinh sẽ có đến căn hộ số 3. Thế nhưng thực tế trong VBA, thì căn hộ đầu tiên của mảng sẽ bắt đầu từ căn hộ số 0.
Bạn cần đăng nhập để thấy đính kèm

Tóm lại [Dim giadinh(3) As String] là:

giadinh(0)

giadinh(1)

giadinh(2)

giadinh(3)

Như vậy, ở đây ta đã có tới 4 căn hộ.
Và đoạn code ở phần trên có nghĩa là căn hộ số 0 tuy tồn tại nhưng không có ai ở.
Bạn cần đăng nhập để thấy đính kèm


Như vậy khi làm việc với mảng, chúng ta hãy chú ý chỉ số bắt đầu của mảng.
Ví dụ dưới đây, chúng ta gán giá trị cells trên cột A bằng mảng buf. Nhưng vì mảng bắt đầu từ chỉ số 0, trong khi đó cells bắt đầu từ dòng 1, do đó:
Mã:
For i = 1 To 3
    Cells(i, 1) = buf(i -1)
Next i
Hoặc là:
Mã:
For i = 0 To 2
    Cells(i + 1, 1) = buf(i)
Next i
Chúng ta có thể cưỡng chế để mảng bắt đầu từ chỉ số 1 bằng cách sử dụng câu lệnh Option Base 1 ở đầu mỗi module. Tuy nhiên chú ý rằng, chúng ta không phải khai báo một lần là xong, ở đâu dùng mảng, thì ở module đó đều phải khai báo câu lệnh này. Nếu quên thì lỗi không mong muốn có thể xảy ra.
Ví dụ ở đây tôi cưỡng chế để chỉ số của mảng bắt đầu từ 1.
Bạn cần đăng nhập để thấy đính kèm

Nguồn tham khảo và dịch:
 

tuhocvba

Administrator
Thành viên BQT
========
PHẦN NÂNG CAO
========
Bài 8: Mảng động cũng giống như căn chung cư có số phòng tùy ý

Với khai báo lược bỏ số phần tử của mảng, ta sẽ có mảng động.
Mã:
Sub Sample33()
    Dim Member() As String
End Sub
Khai báo này là hoàn toàn hợp lệ, ta không chỉ định số phần tử của mảng. Trong chương trình, ta có thể khai báo lại bằng lệnh ReDim.
Ví dụ:
Mã:
Sub Sample34()
    Dim Member() As String
    Msgbox "Xin chao cac ban, sau day chuong trinh se khai bao lai mang"
    ReDim Member(3)
    Member(1) = "tuhocvba.net"
    Member(2) = "VBA"
    Member(3) = "VietNam"
    MsgBox "Phan tu thu 1 cua mang la: " & Member(1)
End Sub
Kết quả:
Bạn cần đăng nhập để thấy đính kèm


Thử chặn ở cuối chương trình để xem chi tiết hơn nhé:
Bạn cần đăng nhập để thấy đính kèm


Lệnh ReDim ta có thể sử dụng bao nhiêu lần cũng được.
Ví dụ:
Mã:
Sub Sample35()
    Dim Member() As String
    MsgBox "Chuong trinh se khai bao lai mang"
    ReDim Member(2)
    Member(1) = "tuhocvba"
    Member(2) = "VBA"
    ReDim Member(3)
    Member(3) = "VietNam"
    MsgBox "Phan tu thu 3 cua mang la: " & Member(3)
End Sub
Kết quả khi chạy chương trình:
Bạn cần đăng nhập để thấy đính kèm

Ta nhận thấy khi sử dụng lệnh ReDim, thì toàn bộ nội dung của mảng bị xóa sạch ngay khi lệnh ReDim được thực thi. Đó là lý do mà ở hình ảnh trên, chúng ta chỉ còn thấy Member(3) = "VietNam", các phần tử Member(2), Member(1) đều không có giá trị.

Để bảo lưu giá trị vốn có của mảng khi sử dụng lệnh Redim, ta có từ khóa Preserve.
Mã:
Sub Sample35()
    Dim Member() As String
    MsgBox "Chuong trinh se khai bao lai mang"
    ReDim Member(2)
    Member(1) = "tuhocvba"
    Member(2) = "VBA"
    ReDim Preserve Member(3)
    Member(3) = "VietNam"
    MsgBox "Phan tu thu 3 cua mang la: " & Member(3)
End Sub
Kết quả:
Bạn cần đăng nhập để thấy đính kèm

Các bạn đã thấy khác biệt chưa nào, các phần tử Member(1), Member(2) vẫn được bảo lưu giá trị mà không bị mất đi như ở trên.

Các chỉ số của mảng:

Đây hẳn là điều các bạn quan tâm. Chỉ số của mảng bắt đầu từ đâu tới đâu.
Chỉ số đầu ta có Lbound. Chỉ số cuối ta có Ubound. Ví dụ:
Mã:
Sub Sample38()
    Dim Member() As String
    MsgBox "Khai bao lai mang"
    ReDim Member(2)
    Member(1) = "tuhocvba"
    Member(2) = "VBA"
    ReDim Preserve Member(3)
    Member(3) = "VietNam"
    MsgBox LBound(Member) & vbCrLf & _
           UBound(Member)
End Sub
Kết quả:
Bạn cần đăng nhập để thấy đính kèm

Nguồn tham khảo và dịch:
Các bạn tham khảo thêm ở đây:
 

Euler

Administrator
Thành viên BQT
========
PHẦN NÂNG CAO
========
Bài 9: Sử dụng khai báo kiểu Variant cho mảng.

Chúng ta biết rằng Variant là kiểu dữ liệu rất biến hóa. Tất cả kiểu dữ liệu nào đi nữa cũng đều có thể khai báo là Variant. Ví dụ ngay cả đối tượng như Range, Cells, workbook, worksheet,... là các Object nhưng chúng ta cũng có thể lưu vào một biến Variant.
Và tất nhiên, ta cũng có thể lưu mảng vào một biến variant.
Mã:
Sub Sample39()
    Dim buf(3) As String, Member As Variant
    buf(1) = "tanaka"
    buf(2) = "suzuki"
    buf(3) = "yamada"
    Member = buf
    MsgBox Member(2)
End Sub
Một ví dụ khác:
Mã:
Sub Sample40()
    Dim Member As Variant, i As Long
    Member = Split("tanaka,suzuki,yamada", ",")
    For i = 0 To UBound(Member)
        MsgBox Member(i)
    Next i
End Sub
Nếu ai quên lệnh split thì có thể xem lại .
Lệnh Split ở trên sẽ tách chuỗi ký tự ra làm 3 phần tử:
(0): tanaka
(1): suzuki
(2): yamada

Nếu như có ai đó không thích Variant, họ thắc mắc rằng, tại sao không khai báo rõ ràng đi, chúng ta hãy thử xem.
Mã:
Sub Sample41()
    Dim Member(2) As String, i As Long
    Member = Split("tanaka,suzuki,yamada", ",")    Error
    For i = 0 To UBound(Member)
        MsgBox Member(i)
    Next i
End Sub
Bạn cần đăng nhập để thấy đính kèm


Vì vậy, tôi khuyên các bạn, là hãy khai báo dưới dạng Variant sẽ an toàn hơn.

Một ví dụ chúng ta hay gặp, là khi chúng ta cho người dùng chọn nhiều file, và chúng ta muốn lưu các file này vào một mảng, khi đó chúng ta cũng sẽ khai báo mảng là variant.
Mã:
Sub Sample42()
    Dim OpenFiles As Variant, i As Long
    OpenFiles = Application.GetOpenFilename(MultiSelect:=True)
    For i = 1 To UBound(OpenFiles)
        MsgBox OpenFiles(i)
    Next i
End Sub
Tham khảo và dịch từ:
 

tuhocvba

Administrator
Thành viên BQT
========
PHẦN NÂNG CAO
========
Bài 10: Biến số tĩnh Static không bị mất giá trị sau khi kết thúc chương trình.

Thông thường biến số khai báo trong chương trình, sau khi chương trình kết thúc thì biến số sẽ mất đi, giá trị không còn nữa. Tuy nhiên, trong chương trình, nếu ta khai báo biến số là static thì giá trị biến số vẫn còn lưu giữ.
Ví dụ: Biến số khai báo thông thường, khi kết thúc chương trình giá trị sẽ bị mất đi.
Mã:
Sub Sample44()
    Dim Number As Long
    MsgBox Number
    Number = Number + 1
    MsgBox Number
End Sub
Chương trình trên dù chạy bao nhiêu lần, thì kết quả luôn là:
Bạn cần đăng nhập để thấy đính kèm

Bây giờ ta sẽ khai báo biến số là static.
Mã:
Sub Sample45()
    Static Number As Long
    MsgBox Number
    Number = Number + 1
    MsgBox Number
End Sub
Kết quả:
Bạn cần đăng nhập để thấy đính kèm


Chú ý, biến số Static chỉ có cấp độ nằm trong chương trình đó mà thôi. Nếu chúng ta muốn sử dụng biến số dùng chung giá trị cho nhiều module khác nhau thì hãy khai báo là Public.
Ở trên ta khai báo Static, giá trị biến số được lưu trong lần chạy chương trình tiếp theo. Tuy nhiên điều này sẽ chấm dứt nếu như chúng ta tạo ra một thủ tục mới như thế này:
Mã:
Sub Sample46()
End Sub
Trình biên dịch VBA sẽ xóa hoàn toàn bộ nhớ để biên dịch lại, và vì vậy giá trị biến Static sẽ không còn được lưu trữ nữa.
Do đó, trong chương trình Sample45 nếu ta sửa lại như sau:
Mã:
Sub Sample46()
    Static Number As Long
    MsgBox Number
    Number = Number + 1
    If MsgBox(Number & vbCrLf & "Khong luu tru gia tri bien Static nua?", vbYesNo) = vbYes Then
        End
    End If
End Sub
Khi đó nếu chúng ta ấn YES thì biến Static sẽ kết thúc, giá trị không còn được lưu trữ nữa.
Khác với Code C, trong VBA chúng ta ít khi sử dụng biến Static. Tuy nhiên, khi chúng ta đã được học bài học này rồi, chúng ta có thể ứng dụng nó vào việc lưu trữ giá trị cells trước đây vào một biến Static.
Bài viết được dịch và tham khảo từ:
 

Euler

Administrator
Thành viên BQT
========
PHẦN NÂNG CAO
========
Bài 11: Phép gán cho biến Object.

Tùy vào kiểu giá trị mà ta cất vào biến, khi đó ta sẽ khai báo kiểu biến số tương ứng. Chẳng hạn để cất giá trị số nguyên vào một biến, thì ta cần khai báo biến đó là Long hoặc Integer. Nếu ta muốn cất một chuỗi ký tự vào biến số thì khi ấy biến số sẽ được khai báo kiểu là String.
Mã:
Sub Sample47()
    Dim N As Long, buf As String
    N = 3
    buf = "tuhocvba.net"
End Sub
Tuy nhiên nếu biến số là một đối tượng (Object), để thực hết phép gán ta phải có từ khóa là Set.
Mã:
Sub Sample48()
    Dim R As Range
    Set R = Range("A1")
    R.Font.ColorIndex = 3
End Sub
Ta biét rằng Range là một kiểu đối tượng, bao gồm nhiều thuộc tính (màu sắc, dòng, font chữ,...) và phương thức (vd: xóa giá trị), vì thế trong code trên, để thực hiện phép gán ta phải có từ khóa Set.
Tương tự như thế, worksheet cũng là một đối tượng.
Mã:
Sub Sample52()
    Dim ws As Worksheet
    Set ws = Worksheets("Sheet1")
    ws.Activate         ''Sheet1 active
    ws.Name = "Test"    '' Thay đổi tên của Sheet1
End Sub
Lược dịch và tham khảo từ:
 

tuhocvba

Administrator
Thành viên BQT
========
PHẦN NÂNG CAO
========
Bài 12: Biến số do người dùng tự định nghĩa.

Thường thì biến số chỉ có một kiểu dữ liệu, tuy nhiên đôi khi trong thực tế ta mong muốn một biến số có nhiều kiểu dữ liệu, khi đó ta có thể tự định nghĩa kiểu biến số cho riêng mình.
Mã:
Type ○○
    thuộc_tính_1 As Kiểu_dữ_liệu
    thuộc_tính_2 As Kiểu_dữ_liệu
End Type
Sub Sample()
    Dim tên_biến_số As ○○
    tên_biến_số.thuộc_tính_1 = Giá_trị
    tên_biến_số.thuộc_tính_2 = Giá_trị
End Sub
Chúng ta sẽ khai báo kiểu dữ liệu của người dùng ở đầu mỗi Module. Nơi mà chúng ta thường ghi Option Explicit hay khai báo các hàm API.
Ví dụ:
Mã:
Type Personal
    Name As String
    Age As Long
End Type
Sub Sample56()
    Dim Member As Personal
    Member.Name = "tuhocvba"
    Member.Age = 38
End Sub
Khi gõ chương trình, ta thấy trình biên dịch VBE cho chúng ta những gợi ý là những định nghĩa mà chúng ta đã khai báo.
Bạn cần đăng nhập để thấy đính kèm

Thậm chí chúng ta còn có thể lồng nhiều kiểu định nghĩa vào với nhau như ví dụ dưới đây:
Mã:
Type Personal
    Name As String
    Age As Long
End Type
Type Area
    Tokyo As Personal
    Yokohama As Personal
End Type
Sub Sample57()
    Dim Member As Area
    Member.Tokyo.Name = "suzuki"
    Member.Yokohama.Age = 28
End Sub
Cách khai báo do người dùng tự định nghĩa có ưu điểm là dễ quản lý bảo trì sửa chữa code sau này, dễ code.
Bài dịch và tham khảo:
 

giaiphapvba

Administrator
Thành viên BQT
========
PHẦN THÊM
========
Bài 13: Sự khác nhau giữa hằng số và biến số.

Để khai báo hằng số ta sử dụng từ khóa Const.
Mã:
Sub Sample59()
    Const MaxCount As Long = 100
    If Range("A1") > MaxCount Then
        MsgBox "Da vuot qua gioi han"
    Else
        MsgBox "Nam trong gioi han"
    End If
End Sub
Tất nhiên chúng ta cũng có thể dùng biến số để thực hiện điều trên. Lúc này code sẽ là:
Mã:
Sub Sample59()
    Dim MaxCount As Long
    MaxCount = 100
    If Range("A1") > MaxCount Then
        MsgBox "Da vuot qua gioi han"
    Else
        MsgBox "Nam trong gioi han"
    End If
End Sub
Với biến số, ta có thể thực hiện phép gán giá trị cho nó bao nhiêu lần cũng được. Với hằng số thì nó bị cố định một giá trị trong suốt chương trình.
Với hằng số, ta phải định nghĩa giá trị cho nó ngay khi thực hiện khai báo.

Với biến số, ta không thể vừa khai báo vừa gán giá trị, sẽ báo lỗi.
Mã:
Dim buf As Long = 100 'Khai báo sai'
Và với hằng số thì không thể thực hiện gán giá trị sau câu lệnh khai báo.
Mã:
Const Buf As Long
Buf = 100
Tham khảo và dịch:
Như vậy, qua 13 bài dịch và lược dịch, diễn đàn đã giới thiệu đầy đủ về các nguyên tắc cũng như qui định trong việc khai báo biến số. Chúng tôi hi vọng, mọi người đều thấy topic này là bổ ích, hãy chia sẻ đường link topic này cho bạn bè và đồng nghiệp của các bạn nhé.
 
Trạng thái
Không mở trả lời sau này.
Top