Professional Documents
Culture Documents
com/site/exl2lab/vba-in-excel
Contents
Bài 0. Kiến thức chung về VBA ....................................................................................... 2
Bài 1. Tạo macro ............................................................................................................... 4
Bài 2. Ghi macro ............................................................................................................... 5
Bài 3. Hộp thoại thông báo .............................................................................................. 6
Bài 5. Workbook, worksheet ........................................................................................... 8
Bài 6. Range, Cells .......................................................................................................... 13
Bài 7. Hàm trong VBA ................................................................................................... 18
Bài 8. Events, Application Object ................................................................................. 25
Bài 9. Function and Sub ................................................................................................. 29
Bài 10. Array ................................................................................................................... 34
Bài 11. Dictionary ........................................................................................................... 40
Bài 12. FileSystemObject ............................................................................................... 46
Bài 13. Collection ............................................................................................................ 63
Bài 14. Hashtable ............................................................................................................ 67
Bài 15. Stack .................................................................................................................... 71
Bài 16. Queue .................................................................................................................. 77
Bài 17. SortedList ........................................................................................................... 81
Bài 18. ArrayList ............................................................................................................ 91
P a g e 1 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
P a g e 2 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
4. Macro setting
Thiết lập bảo mật cho macro:
Trên menu Developer, click Macro Security (hoặc Excel Options > Trust Center > Trust Center
Settings... > Macro Settings).
Ở mục Macro Setting có 4 lựa chọn:
1/ Vô hiệu hóa mọi macro và không thông báo.
2/ Vô hiệu hóa mọi macro và kèm theo thông báo.
3/ Vô hiệu hóa mọi macro ngoại trừ những macro được ký điện tử.
4/ Cho phép tất cả các macro (không được khuyến cáo, các mã nguy hiểm có thể được chạy).
5. Protect macro
Để bảo vệ code được bí mật, bạn thiết lập mật khẩu bảo vệ cho Project của VBA.
Tại giao diện của VBA, vào Tools, VBAProject Properties...
Cửa sổ VBAProject Properties, tới tab Protection:
- Check dòng Lock project for viewing
- Nhập mật khẩu vào khung Password và Confirm password.
Click OK
6. Nhận biết thuộc tính và phương thức của một đối tượng.
7. Một số thủ thuật
- Dùng MsgBox để kiểm tra kết quả tại dòng code bất kỳ.
- Dùng chức năng Step Into (nhấn phím F8) để kiểm tra từng dòng code.
- Dùng cửa sổ Immediate (Ctrl + G) để kiểm tra nhanh kết quả của một dòng code.
P a g e 3 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
P a g e 4 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Ghi macro (Record Macro) là một công cụ rất hữu ích trong Excel VBA, nó ghi lại mọi thao
tác của bạn trên bảng tính Excel.
Bạn chỉ cần ghi lại một tác vụ (một hoặc nhiều thao tác) thực hiện với bảng tính Excel. Tiếp
đó, bạn gán nó (assign macro) vào một nút lệnh rồi click nút lệnh đó để lặp lại tác vụ vừa được
ghi.
Mặt khác, khi bạn không rõ, không biết tạo một chương trình (tác vụ) cụ thể trong VBA thì
bạn hãy sử dụng chức năng ghi macro. Sau khi bạn ghi macro xong, bạn có thể vào cửa sổ
VBA để xem chi tiết macro đó.
Tuy nhiên, macro được tạo ra bởi việc ghi macro cũng có nhược điểm. Đó là, macro đó áp
dụng cụ thể với trường hợp bạn vừa thao tác và ghi lại, câu lệnh chưa tối ưu, không áp dụng
được vùng dữ liệu khác... nên cần phải hiệu chỉnh với mục đích cụ thể.
Cách thực hiện:
- Trên menu Developer, click nút Record Macro.
- Cửa sổ Record Macro hiện ra. Đặt tên cho macro, thiết lập phím tắt để chạy (Run) macro,
thiết lập nơi hiệu lực của macro, miêu tả...
Rồi click OK.
- Khi đó chức năng Record Macro bắt đầu hoạt động, nhiệm vụ của bạn khi đó là thực hiện các
thao tác cần ghi lại trên bảng tính Excel.
Sau khi thao tác xong, bạn click nút Stop Recording trên menu Developer để kết thúc việc ghi
macro.
(Ví dụ ở đây, ta nhập số thứ tự từ 1 tới 5 vào các ô [A2:A6])
- Để xem code mà macro vừa được ghi lại, bạn vào cửa sổ VBA (nhấn Alt+F11)
- Để gán macro vừa được ghi vào nút lệnh, ta chèn một shape hình chữ nhật rồi assign macro
"Macro1" vào.
- Chạy thử Macro1: Xóa vùng dữ liệu ở [A2:A6] rồi click vào nút lệnh vừa tạo)
(Tham khảo file đính kèm ở cuối bài viết).
P a g e 5 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Buttons: Không bắt buộc. Là hằng số quy định cụ thể số lượng và loại các nút hiển thị. Nếu
không sử dụng, giá trị mặc định là số 0.
Title: Không bắt buộc. Là chuỗi được hiển thị trên thanh tiêu đề của hộp thoại. Nếu bỏ qua, tên
ứng dụng được đặt trong thanh tiêu đề (ở đây, cụ thể ở đây là "Microsoft Excel").
HelpFile: Không bắt buộc. Chuỗi xác định tên tập tin trợ giúp sử dụng để cung cấp các trợ giúp
theo ngữ cảnh cho các hộp thoại.
Context: Không bắt buộc. Là số thứ tự tình huống trong HelpFile. Nếu HelpFile có thì Context
phải có.
VbMsgBoxResult:
Có thể nối nội dung thông báo với nội dung trên bảng tính.
Ví dụ 2: Với [A1]="Exl2Lab"
Sub msgbox2()
MsgBox "Xin chào! " & Sheet1.Range("A1")
End Sub
Để tạo thông báo có nhiều dòng (xuống dòng trong bảng thông báo) ta dùng từ
khóa vbNewLine.
Ví dụ 3:
Sub msgbox3()
MsgBox "Xin chào! " & Sheet1.Range("A1") & vbNewLine & "Email: " &
Sheet1.Range("A2")
End Sub
Ngoài ra, msgbox thường hay dùng để kiểm tra kết quả từng đoạn code khi viết, để tạo thông
báo nhắc người dùng xác nhận trước một tác vụ quan trọng (như xóa dữ liệu, in ấn...).
Ví dụ 4:
P a g e 6 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Sub mgbDelete()
Dim ans As Integer
ans = MsgBox("Ban muon xoa du lieu tren sheet nay?", vbYesNo + vbQuestion, "Xoa du lieu")
If ans = vbYes Then
'Chọn Yes thì thực hiện tác vụ
Cells.ClearContents
Else
'không làm gì
End If
End Sub
2. InputBox:
P a g e 7 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
- Mỗi chương trình ứng dụng thường xử lý nhiều dữ liệu, ta dùng khái niệm "biến" để lưu trữ dữ
liệu trong bộ nhớ máy tính, mỗi biến lưu trữ một dữ liệu của chương trình.
- Mặc dù VBA không yêu cầu (*), nhưng ta nên định nghĩa rõ ràng từng biến trước khi truy xuất
nó để code của chương trình được rõ ràng, dễ hiểu, dễ bảo trì và phát triển.
Ví dụ:
Tên biến hợp lệ Tên biến không hợp lệ
Bien1_dong Bien-1: Vì có dấu gạch ngang
KhoiLuong Bien&1: Vì có ký tự &
1Bien_dong: Vì có ký tự số ở đầu
- Khi viết tên biến ta nên viết hoa chữ đầu tiên của một từ có ý nghĩa.
Ví dụ: Đặt tên biến xác định khối lượng, số tiền: Kluong, SoTien
P a g e 8 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
- Không được dùng tên biến trùng với các từ khoá như: Print, Sub, End… (từ khóa là những từ mà
ngôn ngữ VBA đã dùng cho những thành phần xác định của ngôn ngữ).
+ As: Từ khóa, gán với kiểu dữ liệu nào cho biến.
+ Type: Kiểu dữ liệu cần gán cho biến đang khai báo. Nếu bỏ qua [As Type] thì biến đó mặc định
nhận kiểu dữ liệu Variant.
Chú thích (*): Có hay không bắt buộc khai báo biến trong VBA
- Khi ở trên cùng trong các môi trường VBA Project (Worksheet, Workbook, Module, Class
module, UserForm) có dòng Option Explicit thì các biến phải được khai báo trước khi sử dụng.
- Hai cách thiết lập Option Explicit:
Một là nhập trực tiếp ở trên cùng của môi trường viết code.
Hai là thiết lập Options trong VBA, yêu cầu khai báo biến (mục Require Variable Declaration
được chọn) thì ở trên cùng trong các môi trường VBA Project (Worksheet, Workbook, Module,
Class module, UserForm) sẽ tự động thêm dòng Option Explicit.
Chú thích (**): Giải thích các từ khóa đứng trước tên biến trong cú pháp khai báo biến.
[Static|Public|Private|Dim] AVariable [As Type]
Public, Private, Static là các từ khoá dùng để xác định phạm vi (tầm vực) của một vật thể
(variable, sub, or function).
Phạm vi/ tầm vực có hai tính chất: tính chất "có thể thấy được" và tính chất "tồn tại".
- Tồn tại: Chỉ áp dụng cho biến (variable), không tồn tại có nghĩa là chưa được thiết lập, hoặc đã
bị huỷ.
- Có thể thấy được: Áp dụng cho mọi loại (variable, sub, or function). Tùy theo cách khai báo mà
vật thể có thể thấy được trong một phạm vi nhưng lại bị che khuất trong phạm vi khác. Lưu ý là
vật thể có thể vẫn tồn tại, chỉ ở ngoài phạm vi thì không chạm được tới nó mà thôi.
Ở nội dung phần này, ta chỉ xét tới variable.
• Public: phạm vi toàn cục, ở đâu trong workbook cũng có thể thấy / dùng được. Tuy nhiên, nếu nó
được khai báo trong module mức thấp thì qua mức cao hơn có thể phải thêm tên của module vào
đầu để VBA biết nó ở đâu mà tìm.(TenModule.TenBien)
- Cấu trúc:
Public AVariable [As Type]
- Tồn tại: Biến chỉ giải phóng khi thoát file.
- Vị trí:
Để ngoài Sub/Function, trên cùng của môi trường VBA Project (Worksheet, Workbook, Module,
Class module, UserForm).
• Private: phạm vi nội bộ khi xét cả VBAProject, nó khai báo trên cùng module thì nó là toàn cục
của module đó, các code trong module đó đều thấy nó.
- Cấu trúc:
Private AVariable [As Type]
- Tồn tại: Biến chỉ giải phóng khi thoát file.
- Vị trí:
Để ngoài Sub/Function, trên cùng của môi trường VBA Project (Worksheet, Workbook, Module,
Class module, UserForm).
• Dim: Khai báo biến ở phạm vi toàn cục trong môi trường được khai báo (để ở ngoài Sub/
Function, trên cùng module) nhưng là phạm vi nội bộ khi xét cả VBAProject, hoặc nội bộ trong
Sub/ Function.
P a g e 9 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
- Cấu trúc:
Dim AVariable [As Type]
- Tồn tại: Biến giải phóng khi thoát file (phạm vi toàn cục của module), giải phóng khi thoát
Sub/Function (phạm vi nội bộ của Sub/Function).
- Vị trí:
+ Để ở ngoài Sub/ Function: Khai báo biến ở phạm vi toàn cục của môi trường khai báo.
+ Khai báo trong Sub/ Function: Phạm vi nội bộ của Sub/Function.
- Trong chương trình có 2 vùng bộ nhớ, vùng heap và vùng stack. Biến khai báo toàn cục thuộc về
heap và biến khai báo nội bộ Sub/Function là biến thuộc về stack. Các vật thể nằm trong vùng
stack sẽ bị huỷ sau khi Sub/Function Exit hoặc End. Riêng biến Static thì luôn thuộc về heap bất
kể nó là Public hay Private. Vì vậy biến Static không bị huỷ khi Sub/Function thoát.
- Tất cả các kiểu khai báo biến, kể cả Public hay Static thì biến đều được giải phóng khi code bị
bất cứ lỗi nào và dừng chương trình.
P a g e 10 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Sơ đồ dạng phả hệ (dạng cây - TreeView) các đối tượng trong VBA:
Workbooks.Open(filepath): Mở workbook mới, với filepath là đường dẫn của file cần mở.
Ví dụ: Workbooks.Open("C:\Users\Administrator\Desktop\Vidu.xlsx")
ThisWorkbook.Close True '(SaveChanges = True): Đóng workbook và lưu các thay đổi đã tác
động lên workbook.
ThisWorkbook.Close False '(SaveChanges = False): Đóng workbook và không lưu các thay đổi
đã tác động lên workbook.
(Tham khảo file đính kèm ở cuối bài viết).
2. Đối tượng Worksheet
Trong VBA, khi xét tới đối tượng Worksheet thì nó là đối tượng cấp 3 (sau Workbook).
(Xem lại ví dụ ở phần đối tượng workbook ở trên.)
P a g e 11 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Cách 1: Sử dụng worksheet name – Là tên của bảng tính nhìn thấy ở dưới thanh trạng thái
(Sheet Tab).
Sub wsName()
Worksheets("Ten sheet 1").Range("A1").Value = "Xin chao!"
'Hoac co the viet sheets thay cho worksheets
Sheets("Ten sheet 1").Range("A2").Value = "Xin chao!"
End Sub
# Cách 2: Sử dụng thứ tự sắp xếp của worksheet ở sheet tab, tính từ trái qua phải, vị trí đầu tiên
là 1
Sub wsIndex()
Sheets(1).Range("B1").Value = Sheets(1).Name & "-Vi tri=" & Sheets(1).Index
Sheets(2).Range("B1").Value = Sheets(2).Name & "-Vi tri=" & Sheets(2).Index
End Sub
# Cách 3: Sử dụng CodeName của worksheet, là tên của worksheet trong VBA
Sub wsCodeName()
Sheet1.Range("B2").Value = Sheets(1).Name
Sheet2.Range("B2").Value = Sheets(2).Name
Sheet1.Range("C1").Value = Sheet1.CodeName
Sheet2.Range("C1").Value = Sheet2.CodeName
End Sub
P a g e 12 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Range, cells là 2 đối tượng của worksheets (cells cũng là đối tượng của Range).
1. Đối tượng Range
+ Cấu trúc:
Worksheets.Range(Cell1, [Cell2])
Cell1 là cell đầu tiên trong vùng được gọi tới, tham số bắt buộc.
Cell2 là cell cuối cùng trong vùng được gọi tới, tham số không bắt buộc.
- Range có thể gồm một hoặc nhiều cells.
- Range có thể gồm một hoặc nhiều dòng/ cột, vùng không liên tục:
Ví dụ:
Set Rng1 = Sheet1.Range("A5", "B10")
Set Rng2 = Sheet1.Columns("B:D")
Set Rng3 = Sheet1.Rows("2:5")
+ Các cách viết gọi một range trong VBA:
Range("A5", "B10")
OR:
Range("A5:B10")
OR:
[A5:B10]
*Lưu ý:
- Khi gọi một range ta viết chỉ định cho một worksheet nào đó: Sheet1.Range("A5:B10")
Nếu không viết chỉ định Range("A5:B10") cho một worksheet cụ thể thì sẽ được hiểu Range
đang gán cho worksheet hiện hành ActiveSheet.Range("A5:B10"). Khi Run (khởi chạy) một
Sub (thủ tục) nào đó trong cửa sổ VBA phải đảm bảo worksheet muốn thực hiện Sub đó phải
đang được Active, nếu không sẽ chạy nhầm worksheet; hoặc ta có thể gán Sub đó vào nút lệnh
trên worksheet muốn thực hiện và kích hoạt Sub bằng cách click vào nút lệnh.
2. Đối tượng Cells
+ Cấu trúc:
Worksheets.Cells([RowIndex], [ColumnIndex])
Range.Cells([RowIndex], [ColumnIndex])
- RowIndex: Địa chỉ dòng của cell cần gọi, nếu bỏ qua thì mặc định tham số nhận giá trị là 1.
- ColumnIndex: Địa chỉ cột của cell cần gọi, nếu bỏ qua thì Cells trả về có chỉ số trong Range
được tính từ trái sang phải, từ trên xuống dưới.
- Nếu bỏ qua cả 2 tham số thì trả về toàn bộ Cells trong Range.
Ví dụ:
Sub RngObject()
Dim Rng As Range, Cll As Range, Cll1 As Range
Set Rng = Sheet1.Range("A5:B10")
Set Cll = Sheet1.Cells(1, 1)
Set Cll1 = Rng.Cells(1, 1)
MsgBox Rng.Address & vbNewLine & Cll.Address & vbNewLine & Cll1.Address
End Sub
3. Một số thuộc tính, phương thức thường dùng
3.1. Thuộc tính:
Value / .Value2 / .Text
Xét ví dụ cụ thể bên dưới:
P a g e 13 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Formula / Hasformula
Sub Set_Formula()
Dim Cll As Range, i As Long
Set Cll = Sheet1.Range("C5")
For i = 0 To 5
Cll.Offset(i, 0).Value = i + 10
Next i
Cll.Offset(6, 0).Formula = "=Sum(C5:C10)"
MsgBox Cll.Offset(6, 0).HasFormula
End Sub
Offset
Cú pháp:
Range.Offset([RowOffset],[ColumnOffset])
RowOffset: Số dòng giữa vùng tham chiếu gốc và vùng đích, hướng về phía trên Range
thì RowOffset mang giá trị âm.
Nếu không nhập thì RowOffset=0, cú pháp khi đó: Range.Offset(, ColumnOffset)
ColumnOffset: Số cột giữa vùng gốc và vùng đích, hướng về bên trái Range thì ColumnOffset
mang giá trị âm.
Nếu không nhập thì ColumnOffset=0, cú pháp khi đó: Range.Offset(RowOffset)
Ví dụ:
Sub Offset()
'Range.Offset([RowOffset],[ColumnOffset])'
Dim Cll As Range, Rng As Range
Set Cll = Sheet1.Range("B2")
Set Rng = Sheet1.Range("A5:A10")
MsgBox Cll.Offset(1, 1).Address '$C$3'
MsgBox Cll.Offset(, 2).Address '$D$2'
MsgBox Cll.Offset(2).Address '$B$4'
MsgBox Rng.Offset(1, 1).Address '$B$6:$B$11'
MsgBox Rng.Offset(, 1).Address '$B$5:$B$10'
MsgBox Rng.Offset(2).Address '$A$7:$A$12'
End Sub
Resize
Cú pháp:
Range.Resize([RowSize],[ColumnSize])
RowSize: Số dòng dãn ra so với cell đầu tiên của vùng tham chiếu gốc.
- Nếu không nhập thì RowSize=Range.Rows.Count, cú pháp khi đó: Range.Resize(,
ColumnSize)
ColumnSize: Số cột dãn ra so với cell đầu tiên của vùng tham chiếu gốc.
- Nếu không nhập thì ColumnSize=Range.Columns.Count, cú pháp khi
đó: Range.Offset(RowSize)
Ví dụ:
Sub Resize()
'Range.Resize([RowSize],[ColumnSize])'
Dim Cll As Range, Rng As Range
Set Cll = Sheet1.Range("B2")
P a g e 14 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
P a g e 15 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
'Tra vê cell ngoài cùng bên phai trên dòng 20 có du liêu liên tuc, tinh tu G20
'Press: Ctrl + Arrow Right from cell G20
End Sub
# Ứng dụng thuộc tính End() để xác định dòng cuối cùng có dữ liệu:
Sub LastRow1()
'Tra vê dòng trên cùng có du liêu dâu tiên, xet tu cell duoi cùng bang tinh tro lên
Dim lRow As Long
lRow = Sheet1.Range("A" & Sheet1.Rows.Count).End(xlUp).Row
'Voi Excel 2003-97: Rows.Count=65,536
'Voi Excel 2007 tro len: Rows.Count=1,048,576
MsgBox lRow
End Sub
Sub LastRow2()
'Tra vê dòng duoi cùng có du liêu liên tuc, xet tu cell chi dinh tro xuong
Dim lRow As Long
lRow = Sheet1.Range("A5").End(xlDown).Row
MsgBox lRow
End Sub
3.2. Phương thức:
Select: Chọn vùng
Range("A2:C10").Select
Activate: Kích hoạt cell chỉ định hiện hành
Cells(2,5).Activate
Cells(2,5).Select
Copy: Sao chép vùng dữ liệu, bằng với thao tác chọn vùng dữ liệu rồi nhấn Ctrl + C
Range("A2:C10").Copy
Paste: Dán dữ liệu sau khi sao chép, bằng với thao tác nhấn Ctrl + V
Sub CopyRange()
Range("A1:A3").Select
Selection.Copy
Range("C15").Select
ActiveSheet.Paste
End Sub
'Viêt gon:
Sub CopyRange2()
Range("A1:A3").Copy Range("C15")
End Sub
Clear: Xóa nội dung và định dạng của vùng chỉ định
ClearContents: Chỉ xóa nội dung
ClearFormats: Chỉ xóa định dạng
Sub Clear()
Dim Rng As Range
Set Rng = Sheet1.Range("A1:C30")
Rng.Clear 'Xoa nôi dung va dinh dang
Rng.ClearContents 'Chi xóa nôi dung
Rng.ClearFormats 'Chi xoa dinh dang
End Sub
P a g e 16 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Delete: Xóa vùng, xóa dòng/cột, xóa ô (bằng với thao tác nhấn tổ hợp phím Ctrl và dấu trừ -)
Sub Delete()
Sheet1.Rows("25:30").Delete
Sheet1.Columns("H:K").Delete
End Sub
P a g e 17 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
P a g e 18 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Trả về vị trí xuất hiện đầu tiên của chuỗi con trong chuỗi đang xét tính từ cuối
chuỗi.
LCASE LCase(String) 'As String
Chuyển chuỗi từ chữ in hoa thành chữ thường.
UCASE UCase(String) 'As String
Chuyển chuỗi từ chữ thường thành chữ in hoa.
LEFT Left(String,Length As Long) 'As String
Trích xuất một chuỗi con từ một chuỗi, bắt đầu từ ký tự đầu tiên bên trái.
LEN Len(Expression) As Long 'As Long
Trả về số ký tự của chuỗi.
LTRIM Ltrim(String) 'As String
Loại bỏ khoảng trắng ở đầu (bên trái) chuỗi đưa vào.
MID Mid(String,Start As Long,[Length]) 'As String
Trích xuất một chuỗi con từ một chuỗi (bắt đầu ở bất kỳ vị trí nào).
REPLACE Replace(Expression As String, Find As String, Replace As String, [Start As
Long = 1], [Count As Long=-1],[Compare As VbComapareMethod =
VbBinaryCompare]) 'As String
Thay thế một chuỗi ký tự trong một chuỗi bởi một tập hợp các ký tự khác.
RIGHT Right(String,Length As Long) 'As String
Trích một chuỗi con từ một chuỗi bắt đầu từ ký tự đầu tiên bên phải.
RTRIM Rtrim(String) 'As String
Loại bỏ khoảng trắng ở cuối (bên phải) chuỗi đưa vào.
SPACE SPACE(Number As Long) 'As String
Trả về chuỗi là các ký tự khoảng trắng, với số lượng ký tự chỉ định đưa vào.
SPLIT Split(Expression As String, [Delimiter], [Limit As Long = -1], [Compare As
VbCompareMethod = vbBinaryCompare]) 'Array1D() As String
Trả về một mảng 1 chiều, gồm các phần tử là các chuỗi con được tách ra từ
chuỗi đưa vào bởi dấu phân cách, chỉ mục cận dưới của mảng luôn bằng 0 cho
dù Option Base 1.
JOIN Join(SourceArray,[Delimiter]) 'As String'
Trả về một chuỗi được ghép từ các phần từ của mảng một chiều SourceArray
bởi dấu phân cách Delimiter.
STR STR(Numer) 'As String
Trả về dạng chuỗi của một số.
STRCOMP StrComp(String1, String2, [Compare As VbCompareMethod =
vbBinaryCompare]) 'As Integer
Trả về kết quả là một số nguyên đại diện cho kết quả so sánh 2 chuỗi.
STRCONV StrConv(String,Conversion As VbStrConv,[LocaleID as Long]) 'As String
Trả về một chuỗi được chuyển sang chữ hoa, chữ thường, in hoa ký tự đầu mỗi
từ hoặc Unicode.
STRREVERSE STRREVERSE(Expression As String) 'As String
Trả về chuỗi mới với các ký tự có thứ tự đảo ngược.
TRIM Trim(String) 'As String
Loại bỏ khoảng trắng ở đầu và cuối của chuỗi.
VAL Val(String as String) 'As Double
Trả về các số được tìm thấy trong một chuỗi.
P a g e 19 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
P a g e 20 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Trả về trị số năm có bốn chữ số (một số từ năm 1900 đến 9999) ứng với ngày
đang xét.
Math/Trig Hàm về Toán học
Functions
ABS Abs(Number) 'As Double
Trả về giá trị tuyệt đối của một số.
ATN Atn(Number As Double) 'As Double
Trả về giá trị của phép tính ATAN trong Toán, từ -Pi/2 tới Pi/2.
COS Cos(Number As Double) 'As Double
Trả về giá trị của phép tính Cosine của một góc trong Toán (-1 tới 1).
EXP Exp(Number As Double) 'As Double
Trả về giá trị lũy thừa của cơ số e (e là hằng số toán học, xấp xỉ 2.718).
FIX Fix(Number)
Trả về phần số nguyên của một số.
FORMAT Format (Expression, [Format ]) 'As String
NUMBERS
Định dạng một số dưới dạng chuỗi.
INT Int(Number) 'As Double
Trả về phần số nguyên của một số.
LOG Log(Number As Double) 'As Double
Trả về giá trị của phép tính Logarit tự nhiên của một số (Log cơ số e hay
Ln(x)).
RANDOMIZE Randomize([Number])
Được sử dụng để thay đổi giá trị nguồn được sử dụng bởi máy tạo số ngẫu
nhiên cho hàm RND.
RND RND
Để tạo ra một số ngẫu nhiên giữa 0-1.
ROUND Round(Number, [NumDigitsAfterDecimail As Long]) 'As Double
Làm tròn một số đưa vào.
SGN Sgn(Number) 'As Integer
Trả về dấu của một số.
SIN Sin(Number As Double) 'As Double
Trả về giá trị của phép tính Sine của một góc trong Toán, từ -1 tới 1.
SQR Sqr(Number As Double) 'As Double
Trả về kết quả của phép toán căn bậc 2 của số cần tính.
TAN Tan(Number As Double) 'As Double
Trả về giá trị của phép tính Tan của một góc trong Toán.
Logical Functions Hàm logic, cấu trúc lệnh trong VBA
AND Conditions_1 And conditions_2 [… And conditions_n]
Trả về kết quả True nếu tất cả các điều kiện đưa vào là True.
OR Conditions_1 Or conditions_2 [… Or conditions_n]
Trả về TRUE nếu cos bất kỳ điều kiện nào là TRUE.
CASE Select Case Expression
Case condition_1
P a g e 21 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
result_1
Case condition_2
result_2
...
Case condition_n
result_n
Case Else
result_else
End Select
Tương tự cấu trúc lệnh If Then Else, trả về một giá trị nếu một điều kiện trả về
TRUE.
IF-THEN-ELSE If condition_1 Then
result_1
result_2
...
result_n
Else
result_else
End If
Trả về một giá trị nếu một điều kiện trả về TRUE hoặc một giá trị khác nếu nó
trả về FALSE.
FOR...NEXT FOR counter = start TO end [Step increment]
{...statements...}
NEXT [counter]
Vòng lặp duyệt qua biến đếm.
DO Do While condition
WHILE…LOOP
{...statements...}
P a g e 22 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Loop
Vòng lặp duyệt qua điều kiện đưa vào.
WHILE...WEND WHILE condition
{...statements...}
END
Vòng lặp duyệt qua điều kiện đưa vào. Giống cấu trúc lệnh DO
WHILE…LOOP.
SWITCH Switch(ParamArray VarExpr() As Variant)
Switch (expr1, value1, expr2, value2, ... expr_n, value_n)
Xét một danh sách các biểu thức và trả về giá trị tương ứng cho biểu thức đầu
tiên trong danh sách có kết quả TRUE.
Information Hàm xử lý thông tin
Functions
ENVIRON Environ(Expression) 'As String
Trả về giá trị ứng biến của môi trường hệ điều hành cần xác định.
ISDATE IsDate(Expression) 'As Boolean
Trả về TRUE nếu biểu thức là một giá trị ngày hợp lệ.
ISEMPTY IsEmpty(Expression) 'As Boolean
Kiểm tra các ô trống hoặc các biến rỗng (chưa có giá trị), nếu đúng thì trả về
True, ngược lại trả về False.
ISERROR IsError(Expression) 'As Boolean
Trả về kết quả True nếu điều kiện cần kiểm tra là một lỗi, ngược lại trả về
False.
ISNULL IsNull(Expression) 'As Boolean
Kiểm tra giá trị NULL.
ISNUMERIC IsNumeric(Expression) 'As Boolean
Kiểm tra một giá trị là dạng số hay không. Trả về True nếu là dạng số, ngược
lại trả về False.
ISARRAY IsArray(VarName) 'As Boolean'
Kiểm tra một biến (VarName) là dạng mảng (Array) hay không. Trả về True
nếu là dạng mảng, ngược lại trả về False.
TYPENAME TypeName(VarName) 'As String'
Trả về kiểu dữ liệu của biến chỉ định.
Data Type Conv. Hàm chuyển đổi kiểu dữ liệu
Functions
CBOOL CBool(Expression) 'As Boolean
Chuyển giá trị về kiểu dữ liệu Boolean.
CBYTE CByte(Expression) 'As Byte
Chuyển giá trị về kiểu dữ liệu Byte (0-255).
CCUR CCur(Expression) 'As Currency
Chuyển giá trị về kiểu dữ liệu Currency.
CDATE CDate(Expression) 'As Date
Chuyển giá trị về kiểu dữ liệu Date.
CDBL CDbl(Expression) 'As Double
Chuyển giá trị về kiểu dữ liệu Double.
CDEC CDbl(Expression) 'As Decimal
P a g e 23 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
P a g e 24 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Ví dụ:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'Hight light row and column from activecell:'
For i = 1 To iRow
Cells(i, iCol).Interior.ColorIndex = 6 'Tô màu ô cùng dòng'
Next i
For j = 1 To iCol
Cells(iRow, j).Interior.ColorIndex = 6 'Tô màu ô cùng côt'
Next j
P a g e 25 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Application.ScreenUpdating = True
End Sub
1.4. Workbook_BeforeClose
Sự kiện trước khi đóng Workbook.
Ví dụ:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
'Hide sheets:'
Sheets("Temp").Visible = xlSheetHidden
Ví dụ:
Private Sub Workbook_BeforePrint(Cancel As Boolean)
'Luu bang tinh truoc khi in:'
ThisWorkbook.Save
End Sub
1.6. Workbook_Open
Sự kiện khi mở Workbook.
Ví dụ:
Private Sub Workbook_Open()
'Gioi han ngay su dung file:
Dim dkNgay As Long
dkNgay = Sheet1.Range("A1").Value2 'Nhâp ngày diêu kiên vào [A1] cua sheets "Data"
If CLng(Date) > dkNgay Then 'Nêu ngày hiên tai > ngày diêu kiên
MsgBox "Quá han su dung!" & vbNewLine & "Liên hê tác gia:...", , "Thông báo"
Else
MsgBox "Xin chào!", , "Thông báo"
End If
End Sub
2. Application Object
2.1. ScreenUpdating
Điều khiển cập nhật màn hình: Khi điều khiển các đối tượng (sheets, range, cells), việc vô hiệu
hóa cập nhật màn hình (tránh nhấp nháy) giúp tốc độ code nhanh hơn.
2.2. Calculation
Mặc định thiết lập bảng tính tự động tính toán (CalculationAutomatic), khi điều khiển các đối
tượng (sheets, range, cells), ví dụ gán kết quả xuống bảng tính, các công thức thực hiện tính
toán với giá trị vừa được gán, máy tính phải xử lý thêm tác vụ, làm giảm tốc độ code thực hiện
lệnh. Vậy, để tăng tốc độ cho code ta sẽ chuyển thiết lập về dạng thủ công (CalculationManual).
Xem 2 ví dụ để so sánh:
Sub ScreenAndCal_ON()
'Vô hiêu hóa câp nhât màn hình
Application.ScreenUpdating = False
P a g e 26 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Sub Alert_Close()
Application.DisplayAlerts = False
ActiveWorkbook.Close
Application.DisplayAlerts = True
End Sub
Khi đó, Excel đóng mà không lưu bảng tính, tương ứng với chọn “Don’t Save”.
2.4. WorksheetFunction
Sử dụng thuộc tính WorksheetFunction để gọi các hàm trong bảng tính.
Cấu trúc:
Application.WorksheetFunction.Formula
Với Formula là một hàm trong bảng tính (sum, countA, Match…)
P a g e 27 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Ví dụ:
Sub Worksheet_Function()
Dim WF As WorksheetFunction
Set WF = Application.WorksheetFunction
Dim aCount As Long
aCount = WF.CountIf(Sheet1.Range("A2:A10"), ">0")
MsgBox aCount
Ví dụ:
Sub GetFileName_Any()
Dim FilePath As String
FilePath = Application.GetOpenFilename()
MsgBox FilePath
End Sub
'--------------'
Sub GetFileName_Excel()
Dim FilePath As String
FilePath = Application.GetOpenFilename("Excel file (*.xlsx), *.xlsx")
MsgBox FilePath
'Workbooks.Open (OpenFile)
End Sub
P a g e 28 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Line(s) code
'Module2:
Sub CallPublicSub()
Call Vidu
'Hoac:'
Module1.Vidu
End Sub
- Private: phạm vi nội bộ, các Function/ Sub khác trong cùng môi trường VBA Project mới
thấy/ dùng được.
Ví dụ:
'Module1:
Private Sub Vidu()
MsgBox "Day la mot private_sub."
End Sub
'Module2:
Sub CallPrivateSub1()
Call Vidu
'Hoac:'
'Module1.Vidu'
'Ket qua: Xay ra loi - "Sub or Function not defined" '
End Sub
Tuy nhiên, có cách để gọi một Function/ Sub từ một Module khác được khai báo Private.
Tiếp ví dụ trên:
'Module2:
Sub CallPrivateSub2()
'Cach goi toi mot Private Sub'
Run "Module1.Vidu"
End Sub
- Static: Phạm vi toàn cục, ở đâu trong môi trường VBA Project cũng có thể thấy / dùng được.
Đặc biệt, các biến được khai báo trong Static Sub/ Function được lưu giá trị cho tới khi thoát
ứng dụng.
Ví dụ:
P a g e 29 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
'Module1:
Static Sub Vidu()
Dim a As Long
a = a + 10
MsgBox a
'Chay sub nay 3 lan, bien a van duoc luu gia tri sau cac lan chay sub:'
'Lan 1: a=10'
'Lan 2: a=20'
'Lan 3: a=30'
End Sub
'Module2:
Sub CallStaticSub()
Call Vidu
'Chay sub nay sau khi chay sub Module1.Vidu'
'Hoac:'
Module1.Vidu
End Sub
2. Function
Cấu trúc:
[Public | Private | Static] Function([ByVal / ByRef | Arguments As type of variables]) [As type
of variables]
Line(s) code
End Function
Function/ End Function: Bắt đầu/ kết thúc một hàm.
Public | Private | Static: Không bắt buộc. Các từ khóa để xác định phạm vi (tầm vực) của
Function.
ByVal / ByRef: Không bắt buộc. Kiểu truyền đối số cho hàm. Mặc định là ByRef (kiểu tham
chiếu).
Arguments As type of variables: Không bắt buộc. Các đối số của hàm, và kiểu dữ liệu khai báo
tương ứng với đối số.
[As type of variables]: Không bắt buộc. Kiểu dữ liệu của kết quả trả về của hàm. Không khai
báo thì kết quả của hàm có kiểu dữ liệu được gán vào.
Ví dụ:
'//Hàm tách ho tên
Function TachHoTen(ByVal chuoi As String) As Variant
'Loai khoang trang dâu và cuôi chuôi:'
chuoi = Trim(chuoi)
Dim arrTmp As Variant, mangKQ()
'Cat chuoi hoten bang dâu phân cách: khoang trang'
arrTmp = Split(chuoi, " ") 'Ket qua tra ve là môt mang 1 chiêu gôm các chu phân cach boi
khoang trang'
ReDim mangKQ(1 To 3)
mangKQ(1) = arrTmp(LBound(arrTmp)) 'Ho'
mangKQ(3) = arrTmp(UBound(arrTmp)) 'Ten'
P a g e 30 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Ví dụ:
'//Tính thê tích khôi hôp
Function TheTichHop(ByVal x As Double, ByVal y As Double, ByVal z As Double) As
Double
TheTichHop = x * y * z
End Function
Công thức trên bảng tính:
=TheTichHop(10,20,34)
=TheTichHop(B9, B10, B11)
3. Sub
Cấu trúc:
Line(s) code
End Sub
Sub/ End Sub: Bắt đầu/ kết thúc một Sub.
Public | Private | Static: Không bắt buộc. Các từ khóa để xác định phạm vi (tầm vực) của Sub.
ByVal / ByRef | Arguments As type of variables: Không bắt buộc. Các đối số của Sub. ByVal /
ByRef là các kiểu truyền đối số.
Ví dụ:
Sub TachHoVaTen() 'Tách ho và tên'
Dim chuoi, Tmp
chuoi = Trim(Sheet1.Range("A5").Value)
Tmp = Split(chuoi, " ") 'Ket qua tra ve là môt mang 1 chiêu gôm các chu phân cach boi
khoang trang'
Sheet1.Range("F5").Value = Tmp(LBound(Tmp))
Sheet1.Range("H5").Value = Tmp(UBound(Tmp))
Sheet1.Range("G5").Value = Mid(chuoi, Len(Tmp(LBound(Tmp))) + 2, Len(chuoi) -
Len(Tmp(LBound(Tmp)) & Tmp(UBound(Tmp))) - 2)
End Sub
'----------------'
Sub TheTich() 'Tính thê tích khôi hôp'
Dim x As Double, y As Double, z As Double
x = Sheet1.Range("B9").Value
P a g e 31 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
y = Sheet1.Range("B10").Value
z = Sheet1.Range("B11").Value
MsgBox "Thê tích khôi hôp: " & x * y * z & " dvtt."
End Sub
'----------------'
Sub ScreenAndCal_ON()
Dim i As Long, T As Double
'Lây gôc thoi gian chay code:'
T = Timer
Ví dụ:
Sub Test_ByValRef()
Dim x As Long, y As Long
x = 50
y = 50
MsgBox "By_Ref = " & By_Ref(x) & vbNewLine & "x = " & x 'By Ref_1 = 500 | x =
500
P a g e 32 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
MsgBox "By_Val = " & By_Val(y) & vbNewLine & "y = " & y 'By Val_2 = 500 | y = 50
End Sub
'-------------'
FFunction By_Ref(ByRef n As Long) As Long
n = 10 * n
By_Ref = n
End Function
'-------------'
Function By_Val(ByVal n As Long) As Long
n = 10 * n
By_Val = n
End Function
Chú thích:
- Với Function By_Ref():
Truyền đối số bằng tham chiếu (ByRef), tức là ta đang tham chiếu tới giá trị gốc. Giá trị của n
(giá trị ban đầu) được thay đổi trong hàm. (Ví dụ trên: Sau khi truyền đối số thì x = 500).
- Với Function By_Val():
Truyền đối số bằng giá trị, tức là ta chỉ lấy giá trị của đối số (copy value), chứ không làm thay
đổi giá trị ban đầu của đối số. Giá trị của n (giá trị ban đầu) vẫn giữ nguyên không đổi. (Ví dụ
trên: Sau khi truyền đối số thì y =50).
5. Ví dụ
Hàm trả về dòng cuối dùng có dữ liệu tương ứng với cell tham chiếu.
'//Function tra vê dòng cuôi cùng có du liêu'
Function LastRow(ByVal ws As Worksheet, ByVal sCol As String) As Long
If ws.FilterMode = True Then ws.ShowAllData 'Nêu dang filter thi clear'
ws.Cells.EntireRow.Hidden = False 'Unhide toan bô rows'
LastRow = ws.Cells(ws.Rows.Count, sCol).End(xlUp).Row 'Tra vê dòng cuôi cùng có du
liêu'
End Function
Hàm rút ngắn họ và tên với trường hợp có từ 2 tên đệm trở lên.
'//Function rut ngan ho và tên (nêu có 2 tên dêm)'
Function ShortName(ByVal sName As String) As String '//Công thuc o bang tinh Excel
=ShortName("ho và tên")'
Dim arrTmp, i As Long
sName = WorksheetFunction.Trim(sName)
arrTmp = Split(sName, " ")
If UBound(arrTmp) > 2 Then
For i = LBound(arrTmp) + 1 To UBound(arrTmp) - 1
arrTmp(i) = Left(arrTmp(i), 1) & "."
Next i
ShortName = Join(arrTmp, " ")
Else
ShortName = sName
End If
End Function
P a g e 33 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
UBound(ArrayName, Dimension
ArrayName: Tên mảng.
Dimension: Chiều của mảng cần xác định.
Kích thước của một chiều thứ i của mảng Arr = UBound(Arr,i) – Lbound(Arr,i) + 1.
Kích thước lớn nhất mỗi chiều của mảng là 2^31 – 1. Tuy nhiên, mảng đó có hoạt động được
hay không còn phụ thuộc vào bộ nhớ của máy tính, nếu mảng có kích thước vượt quá bộ nhớ
khả dụng của máy tính sẽ gặp lỗi “Out of memory”.
Tham khảo thêm Array Size.
Ví dụ:
P a g e 34 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Sub L_UBound()
Dim Arr(1 To 10, 1 To 4)
MsgBox LBound(Arr, 1) & " - " & UBound(Arr, 1) 'Result: 1 - 10
MsgBox LBound(Arr, 2) & " - " & UBound(Arr, 2) 'Result: 1- 4
End Sub
Ứng dụng của mảng trong viết code: Tăng tốc cho code.
Theo tính chất khi sử dụng, ta xét mảng tĩnh và mảng động.
1. Mảng tĩnh
Một mảng tĩnh là mảng có số chiều, kích thước của chiều được khai báo cụ thể ngay từ đầu.
Dim StaticArr (1 đến 20) As Long
Không thể thay đổi kích thước hoặc kiểu dữ liệu của mảng tĩnh (Redim / Redim Preserve).
Khi thực hiện xóa một mảng tĩnh (Erase StaticArr), không có bộ nhớ nào được giải phóng. Khi
đó, việc xóa đó đơn giản là đặt lại tất cả các phần tử của mảng về giá trị mặc định của chúng (0,
vbNullString, Empty hoặc Nothing, tùy thuộc vào kiểu dữ liệu của mảng đó đã được khai báo).
Ví dụ:
Dim Arr(1 To 8) 'Mảng 1 chiều có 8 phần từ (1-8)
Dim Arr2(1 to 9, 1 To 1) 'Mảng 2 chiều, chiều 1 có 9 phần tử (1-9), chiều 2 có 1 phần từ (1-1)
Kích thước khai báo phải là một hằng số cụ thể, không thể khai báo thông qua một biến.
Đúng:
Dim A(1 to 3)
Dim A1( 1 to 4, 1 to 9)
Không đúng:
Sub KhaiBaoLoi()
Dim n As Long
n=5
Dim Arr(1 To n) 'Error: Constant expression required
End Sub
2. Mảng động
Khi chưa xác định được số chiều và kích thước chiều của mảng cần khai báo, ta dùng mảng
động. Mảng động cho phép khai báo số chiều, kích thước mỗi chiều của mảng sau.
Ví dụ:
'Ta mới chỉ khai báo biến mảng nhưng chưa biết số chiều, kích thước của chiều.'
Mảng động cho phép thay đổi kích thước của mảng, nhưng không thể thay đổi kiểu dữ liệu của
mảng.
Khi thực hiện xóa (Erase) một mảng động, bộ nhớ được phân bổ cho mảng đó được giải phóng.
Để sử dụng mảng động sau khi Erase cần thực hiện ReDim mảng động đó.
Khi đã xác định được số chiều và kích thước của chiều ta tiến hành khai báo lại cho mảng, với
từ khóa Redim
Ví dụ:
P a g e 35 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Sub Arr_Dynamic_1()
Dim Arr1() As Long, Arr2() As Long, m As Long, n As Long, i As Long
m = 50
n = 60
ReDim Arr1(1 To m) '1.1'
ReDim Arr2(1 To m, 1 To 1) '1.2'
For i = 1 To m 'Vòng lap gán giá tri vào mang'
Arr1(i) = i
Arr2(i, 1) = i
Next i
ReDim Arr1(1 To n) '2.1'
ReDim Arr2(1 To m, 1 To n) '2.2'
MsgBox "Arr1(1) = " & Arr1(1) & vbNewLine & "Arr2(1,1) = " & Arr2(1, 1)
'Result: Arr1(1) = 0 | Arr2(1,1) = 0'
End Sub
Trong ví dụ trên, ban đầu ta khai báo 2 biến mảng Arr1(), Arr2() nhưng chưa khai báo số chiều
và kích thước của chiều.
Tiếp đó, ta khai báo lại lần thứ nhất (1.1 và 1.2) 2 mảng đó với số chiều và kích thước cụ thể:
ReDim Arr1(1 To m): mảng có 1 chiều, có m -1 +1 = 50 phần tử.
ReDim Arr2(1 To m, 1 To 1): mảng 2 chiều, chiều 1 có kích thớc m -1 +1 = 50, chiều 2 có kích
thớc là 1.
Tiếp theo, ta gán các giá trị cho các phần tử trong mảng (vòng lặp For Next).
Sau đó, ta khai báo lại lần thứ hai (2.1 và 2.2) 2 mảng đó với số chiều và kích thước cụ thể:
ReDim Arr1(1 To n): mảng có 1 chiều, có n -1 +1 = 60 phần tử.
ReDim Arr2(1 To m, 1 To n): mảng 2 chiều, chiều 1 có kích thớc m -1 +1 = 50, chiều 2 có kích
thước n -1 +1 = 60.
Lưu ý ở đây:
- Sau khi Redim để khai báo thay đổi số chiều và kích thước của chiều thì các phần tử trong
mảng trước đó đều bị xóa.
- Khi cần khai báo lại để thay đổi kích thước của mảng mà vẫn giữ các phần từ đã có thì ta
dùng Redim Preserve. Tuy nhiên, cần chú ý rằng Redim Preserve chỉ áp dụng được để thay đổi
kích thước chiều cuối cùng của mảng.
Ví dụ:
Sub Arr_Dynamic_2()
Dim Arr1() As Long, Arr2() As Long, m As Long, n As Long, i As Long
m = 50
n = 60
ReDim Arr1(1 To m) '1.1'
ReDim Arr2(1 To m, 1 To 1) '1.2'
For i = 1 To m 'Vòng lap gán giá tri vào mang'
Arr1(i) = i
Arr2(i, 1) = i
Next i
ReDim Preserve Arr1(1 To n) '2.1'
ReDim Preserve Arr2(1 To m, 1 To n) '2.2'
MsgBox "Arr1(1) = " & Arr1(1) & vbNewLine & "Arr2(1,1) = " & Arr2(1, 1)
'Result: Arr1(1) = 1 | Arr2(1,1) = 1'
End Sub
P a g e 36 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Để ý (2.2) ở ví dụ trên: ReDim Preserve Arr2(1 To m, 1 To n), chỉ có thể thay đổi kích thước
chiều cuối (chiều thứ 2) của mảng Arr2.
3. Chép trị từ range của bảng tính vào array và gán các phần tử của array xuống range
của bảng tính
(Range – Array – Range)
3.1. Range – Array:
Theo hình học giải tích ta có chia ra 1 chiều (đường thẳng), 2 chiều (mặt phẳng), 3 chiều (dạng
khối), và n chiều.
Một range trên bảng tính Excel luôn luôn có 2 chiều (row và column), vậy range sẽ thuộc dạng
mặt phẳng.
Khi chép giá trị của một range cho mảng (mảng động), VBA dùng một hàm copy. Hàm này
mặc định cho kết quả là mảng 2 chiều, row của range tương ứng với chiều thứ nhất của mảng,
column tương ứng với chiều thứ hai của mảng.
P a g e 37 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Function tạo trả về một mảng 2 chiều, chiều thứ nhất có số phần từ bằng số dòng của range,
chiều thứ hai có kích thước bằng 1 phần tử.
Function ArrSeries(ByVal Rng As Range) As Variant
Dim aTmp(), i As Long
ReDim aTmp(1 To Rng.Rows.Count, 1 To 1)
For i = 1 To UBound(aTmp, 1)
aTmp(i, 1) = i
Next i
ArrSeries = aTmp
End Function
Sub gọi function ArrSeries() rồi gán giá trị mảng trả về từ function ArrSeries() xuống range:
Sub SetSeries_Array()
Dim Rng As Range, T As Double
T = Timer
Set Rng = Sheet1.Range("A1:A100000")
Rng.Value = ArrSeries(Rng)
MsgBox Round(Timer - T, 2) & " giây" 'T=0.12 giây'
End Sub
Sub thực hiện gán số thứ xuống range theo phương thức gán xuống từng cell của range:
Sub SetSeries_Range()
Application.ScreenUpdating = False
P a g e 38 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Application.Calculation = xlCalculationManual
Dim i As Long, T As Double
T = Timer
For i = 1 To 100000
Sheet1.Range("A1").Offset(i - 1, 0).Value = i
Next i
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
MsgBox Round(Timer - T, 2) & " giây" 'T=2.75 giây'
End Sub
Nhận xét: Tốc độ code khi sử dụng mảng nhanh hơn rất nhiều sử dụng phương thức sử dụng
range.
P a g e 39 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Ví dụ:
Sub AddMethod()
'Dic.Add Key, Item'
Dim Dic As Object
Set Dic = CreateObject("Scripting.Dictionary")
Dic.Add "KeyA", 10
Dic.Add "KeyB", "Item2"
Dic.Add "KeyC", ""
Dic.Add "KeyD", Array(20, 50)
End Sub
2.2. Exists
Dic.Exists(Key)
Kiểm tra sự tồn tại của một Key trong Dic. Trả về True nếu Key đó tồn tại trong Dic, ngược lại
trả về False.
Ví dụ:
Sub ExistsMethod()
'Dic.Exists(Key) '
Dim Dic As Object
Set Dic = CreateObject("Scripting.Dictionary")
Dic.Add "KeyA", 10
P a g e 40 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Ví dụ:
Sub RemoveMethod()
'Dic.Remove(Key) '
Dim Dic As Object
Set Dic = CreateObject("Scripting.Dictionary")
Dic.Add "KeyA", 10
Dic.Remove ("KeyA")
MsgBox Dic.Exists("KeyA") 'False'
End Sub
2.4. RemoveAll
Dic.RemoveAll
Xóa tất cả các Items có trong Dic.
Ví dụ:
Sub RemoveAllMethod()
'Dic.RemoveAll'
Dim Dic As Object
Set Dic = CreateObject("Scripting.Dictionary")
Dic.Add "KeyA", 10
Dic.Add "KeyB", 20
Dic.RemoveAll
MsgBox Dic.Count '0'
End Sub
2.5. Items
Dic.Items
Trả về một mảng một chiều gồm toàn bộ Items có trong Dic.
Mảng một chiều này luôn có cận dưới bằng 0, dù khai báo Option Base 1
Ví dụ:
Sub ItemsMethod()
'Dic.Items'
Dim Dic As Object, Arr()
Set Dic = CreateObject("Scripting.Dictionary")
Dic.Add "KeyA", 10
Dic.Add "KeyB", 20
Arr = Dic.Items 'LBound(Arr) = 0'
End Sub
2.6. Keys
Dic.Keys
Trả về một mảng một chiều gồm toàn bộ Keys tồn tại trong Dic.
Mảng một chiều này luôn có cận dưới bằng 0, dù khai báo Option Base 1
P a g e 41 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Ví dụ:
Sub KeysMethod()
'Dic.Keys'
Dim Dic As Object, Arr()
Set Dic = CreateObject("Scripting.Dictionary")
Dic.Add "KeyA", 10
Dic.Add "KeyB", 20
Arr = Dic.Keys 'LBound(Arr) = 0'
End Sub
3. Thuộc tính
3.1. Item
Dic.Item(Key)
'Hoặc:'
Dic(Key)
- Gọi Item theo Key chỉ định. Nếu Key chỉ định chưa tồn tại trong Dic, thì Dic sẽ tự động thêm
(Add) Key đó vào, và Item ứng với Key đó là rỗng.
- Thay đổi giá trị của Item theo Key chỉ định. Nếu Key chỉ định chưa tồn tại trong Dic, thì Dic
sẽ tự động thêm (Add) key đó vào, và Item ứng với Key đó có giá trị vừa đưa vào.
Ví dụ:
Sub ItemProperty()
'Dic.Item(Key)'
'Dic(Key) '
Dim Dic As Object, x, y, z
Set Dic = CreateObject("Scripting.Dictionary")
Dic.Add "KeyA", 10
Dic.Add "KeyB", 20
x = Dic.Item("KeyA") '10'
y = Dic("KeyA") '10'
z = Dic("KeyC")
Dic("KeyC") = 100
MsgBox Dic.Item("KeyC") '100'
MsgBox Dic.Count '3'
End Sub
3.2. Key
Dic.Key(Key) = NewKey
Dùng để thay đổi giá trị mới của một Key chỉ định đã tồn tại trong Dic. Yêu cầu:
- Key chỉ định phải đã tồn tại trong Dic
- Giá trị mới của Key đó phải là duy nhất trong Dic (tức là có thể vẫn là giá trị cũ).
Ví dụ:
Sub KeyProperty()
'Dic.Key(Key)=NewKey'
Dim Dic As Object
Set Dic = CreateObject("Scripting.Dictionary")
Dic.Add "KeyA", 10
P a g e 42 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Dic.Key("KeyA") = "KeyB"
End Sub
3.3. Count
Dic.Count
Trả về số Items có trong Dic.
Ví dụ:
Sub CountProperty()
'Dic.Count '
Dim Dic As Object, i As Long
Set Dic = CreateObject("Scripting.Dictionary")
For i = 1 To 5
Dic.Add "Key" & i, ""
Next i
MsgBox Dic.Count '5'
End Sub
3.4. CompareMode
Dic.CompareMode = BinaryCompare
Dic.CompareMode = TextCompare
Thiết lập thuộc tính phân biệt chữ hoa chữ thường cho giá trị của Key.
BinaryCompare: (Giá trị mặc định của Dic) Phân biệt chữ hoa chữ thường
TextCompare: Không phân biệt chữ hoa chữ thường
Lưu ý: Thiết lập CompareMode cho Dic khi Dic rỗng (chưa có item nào trong Dic).
Ví dụ:
Sub CompareModeProperty()
'Dic.CompareMode = vbBinaryCompare'
'Dic.CompareMode = vbTextCompare '
Dim Dic As Object, i As Long
Set Dic = CreateObject("Scripting.Dictionary")
With Dic
.CompareMode = vbBinaryCompare
'.CompareMode = vbTextCompare '
.Add "code", "lower"
.Add "CODE", "UPPER"
End With
End Sub
4. Ứng dụng
- Lọc loại trùng.
- Tạo dãy số ngẫu nhiên không trùng.
-…
4.1. Một số hàm
Hàm lọc loại trùng cột đầu tiên của một Range:
'//Loc loai trung mot cot'
Function UniqueColumn1D(ByVal Rng As Range) As Variant
If Rng.Count = 1 Then UniqueColumn1D = Rng.Value: Exit Function
P a g e 43 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Hàm lọc loại trùng cột đầu tiên cho mảng 2 chiều:
'//Loc loai trung mang 2 chieu'
Function UniqueArray(ByVal arr As Variant) As Variant
If IsArray(arr) = False Then Exit Function
Dim Dic As Object, i As Long
Set Dic = CreateObject("Scripting.Dictionary")
For i = LBound(arr, 1) To UBound(arr, 1)
If arr(i, 1) <> "" And Dic.Exists(arr(i, 1)) = False Then
Dic.Add arr(i, 1), ""
End If
Next i
UniqueArray = Dic.Keys
End Function
4.2. Ví dụ
Cho bảng dữ liệu như dưới. Yêu cầu, căn cứ vào cột [B] – Code để loại loại trùng, kết quả trả
về gồm 4 cột dữ liệu:
[No.] là thứ tự danh mục Code,
[Code] là danh mục Code sau khi loại trùng,e
[Date] là ngày ứng với Code đầu tiên tìm thấy, xét từ trên xuống,
[Quantity] là tổng ứng với mỗi [Code] lọc được.
P a g e 44 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
'Khai bao cu the so chieu va kich thuoc chieu cho bien mang Result'
For i = 1 To lRow
'Xet vong lap bien i chay tu 1 toi lRow
iTmp = ArrData(i, 1)
'Gan phan tu (i,1) cua mang ArrData vao bien iTmp
If iTmp <> "" Then
'Xet iTmp, neu khac rong thi
If Not Dic.Exists(iTmp) Then
'Xet iTmp, neu chua ton tai trong Dic thi
j=j+1
'Tang gia tri cua j len 1 don vi
Dic.Add iTmp, j
'Them item co gia tri = j ung voi key = iTmp
'Truyen ket qua vao bien mang Result:
Result(j, 1) = j
Result(j, 2) = iTmp
Result(j, 3) = ArrData(i, 2)
Result(j, 4) = ArrData(i, 3)
Else
'Nguoc lai: iTmp da ton tai trong Dic thi
Result(Dic.Item(iTmp), 4) = Result(Dic.Item(iTmp), 4) + ArrData(i, 3)
'Cong don so luong vao phan tu cua mang Result co chi so (Dic.Item(iTmp), 4)
End If
End If
Next i
If j > 0 Then
'Xet j >: Tuc la co ket qua loc
.Range("H2").Resize(100, 4).ClearContents
'Xoa du lieu trong vung gan ket qua
.Range("H2").Resize(j, 4) = Result
'Gan ket qua xuong bang tinh
End If
End With
End Sub
P a g e 45 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
FileSystemObject (FSo) là một phần trong thư viện Microsoft Scripting Runtime (scrrun.dll), là
công cụ chuyên xử lý về Drive, Folder, File.
1. Khai báo
2.1. BuildPath
FSo.BuildPath(Path As String, Name As String) As String
Phương thức BuildPath gán một tên vào một đường dẫn (trả về một chuỗi là đường dẫn).
Path: Bắt buộc. Đường dẫn để nối tên vào.
Name: Bắt buộc. Tên cần nối vào đường dẫn chỉ định.
Ví dụ:
Sub BuildPath()
' Dim Fso As Scripting.FileSystemObject
' Set Fso = New Scripting.FileSystemObject
Dim FSo As Object
Set FSo = CreateObject("Scripting.FileSystemObject")
Dim NewPath As String
NewPath = FSo.BuildPath(ThisWorkbook.Path, "NewFolder")
MsgBox NewPath
End Sub
2.2. CopyFile
FSo.CopyFile(Source As String, Destination As String, [OverWriteFiles As Boolean = True])
Source: Bắt buộc. Đường dẫn của một hoặc nhiều tập tin cần sao chép (Có thể sử dụng ký tự
đại diện “*?”).
Destination: Bắt buộc. Nơi để dán tập tin đã sao chép (ký tự đại diện không thể được sử dụng).
OverWrite: Không bắt buộc. Một giá trị Boolean xác định một tập tin đã tồn tại có thể bị ghi đè
P a g e 46 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
hay không. True cho phép các tập tin đã có được ghi đè lên và False ngăn ngừa các tập tin đã có
bị ghi đè lên. Mặc định là True.
Ví dụ:
Sub CopyFile()
' Dim Fso As Scripting.FileSystemObject
' Set Fso = New Scripting.FileSystemObject
Dim FSo As Scripting.FileSystemObject
Set FSo = New Scripting.FileSystemObject
Dim sPath As String, dPath As String
sPath = ThisWorkbook.Path & "\*.xlsx"
dPath = "D:\Vidu"
FSo.CopyFile sPath, dPath, True
End Sub
2.3. CopyFolder
FSo.CopyFolder(Source As String, Destination As String, [OverWriteFiles As Boolean =
True])
Source: Bắt buộc. Đường dẫn của một hoặc nhiều thư mục cần sao chép (Có thể sử dụng ký tự
đại diện “*?”).
Destination: Bắt buộc. Nơi để dán thư mục đã sao chép (ký tự đại diện không thể được sử
dụng).
OverWriteFiles: Không bắt buộc. Một giá trị Boolean xác định một thư mục đã tồn tại có thể bị
ghi đè hay không. True cho phép các thư mục đã có được ghi đè lên và False ngăn ngừa các thư
mục đã có bị ghi đè lên. Mặc định là True.
Ví dụ:
Sub CopyFolders()
'Copy all the folders in "D:\Example"
'to the folder "D:\Vidu"
' Dim Fso As Scripting.FileSystemObject
' Set Fso = New Scripting.FileSystemObject
Dim FSo As Object
Set FSo = CreateObject("Scripting.FileSystemObject")
Dim sPath As String, dPath As String
sPath = "D:\Example\*"
dPath = "D:\Vidu"
FSo.CopyFolder sPath, dPath, True
End Sub
'-----------------'
Sub CopyFolder()
'Copy only the folder "OldFolder" in "D:\Example"
'to the folder "D:\Vidu"
' Dim Fso As Scripting.FileSystemObject
' Set Fso = New Scripting.FileSystemObject
Dim FSo As Object
Set FSo = CreateObject("Scripting.FileSystemObject")
Dim sPath As String, dPath As String
sPath = "D:\Example\OldFolder"
dPath = "D:\Vidu"
P a g e 47 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
2.4. CreateFolder
FSo.CreateFolder(Path As String) As Folder
Path: Bắt buộc. Là đường dẫn của thư mục cần tạo.
Nếu thư mục cần tạo đã tồn tại thì sẽ gặp lỗi, cần kiểm tra sự tồn tại trước khi tạo mới.
Ví dụ:
Sub CreateFolder()
'FSo.CreateFolder(Path As String) As Folder
Dim FSo As Scripting.FileSystemObject
Set FSo = New Scripting.FileSystemObject
FSo.CreateFolder (ThisWorkbook.Path & "\NewFolder")
'Gap loi neu thu muc da ton tai, can kiem tra su ton tai cua thu muc do truoc khi dung
.CreateFolder
End Sub
2.5. CreateTextFile
FSo.CreateTextFile(FileName As String, [OverWrite As Boolean = True], [Unicode As
Boolean = False]) As TextStream
Tạo một tập tin văn bản dạng TextStream trong một thư mục chỉ định, có thể đọc và viết vào
tập tin đó.
FileName: Bắt buộc. Là đường dẫn đầy đủ của tập tin cần tạo.
OverWrite. Không bắt buộc. Thiết lập cho phép có ghi đè tập tin đã tồn tại hay không. Mặc
định là True, tức là cho phép ghi đè tập tin đã tồn tại. Ngược lại, False tức là không cho phép
ghi đè.
Unicode: Không bắt buộc. Thiết lập tập tin văn bản được tạo dưới định dạng Unicode (ứng với
True) hay ASCII (ứng với False). Mặc định là False.
Ví dụ:
Sub CreateTextFile()
'FSo.CreateTextFile(FileName As String, [OverWrite As Boolean = True], [Unicode As
Boolean = False]) As TextStream
Dim FSo As Scripting.FileSystemObject
Set FSo = New Scripting.FileSystemObject
Dim nameText As String, TxtFile As TextStream
nameText = ThisWorkbook.Path & "\NewText.txt"
Set TxtFile = FSo.CreateTextFile(nameText, True, True)
TxtFile.WriteLine ("Hello World!")
TxtFile.WriteLine ("This is a example!")
TxtFile.Close
End Sub
2.6. DeleteFile
FSo.DeleteFile(FileSpec As String, [Force As Boolean = False])
FileSpec: Bắt buộc. Đường dẫn của một hoặc nhiều tập tin cần xóa, cho phép dùng ký tự đại
diện (*?).
P a g e 48 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Force: Không bắt buộc. Thiết lập cho phép tập tin có thuộc tính Read-Only có bị xóa hay
không. True cho phép tập tin Read-Only bị xóa, False thì chúng không bị xóa. Mặc định là
False.
Lưu ý: Gặp lỗi nếu tập tin không tồn tại.
Ví dụ:
Sub DeleteFile()
'FSo.DeleteFile(FileSpec As String, [Force As Boolean = False])
Dim FSo As Scripting.FileSystemObject
Set FSo = New Scripting.FileSystemObject
Dim nameText As String
nameText = ThisWorkbook.Path & "\NewText.txt"
FSo.CreateTextFile nameText, True, False
'nameText = ThisWorkbook.Path & "\*.txt"
FSo.DeleteFile nameText, True
'Gap loi neu tap tin can xoa khong ton tai
End Sub
2.7. DeleteFolder
FSo.DeleteFolder(FolderSpec As String, [Force As Boolean = False])
FolderSpec: Bắt buộc. Là đường dẫn của một hoặc nhiều thư mục cần xóa, cho phép dùng ký tự
đại diện.
Force: Không bắt buộc. Thiết lập cho phép thư mục có thuộc tính Read-Only có bị xóa hay
không. True cho phép thư mục Read-Only bị xóa, False thì chúng không bị xóa. Mặc định là
False.
Lưu ý: Gặp lỗi nếu thư mục không tồn tại.
Ví dụ:
Sub DeleteFolder()
'FSo.DeleteFolder(FolderSpec As String, [Force As Boolean = False])
Dim FSo As Scripting.FileSystemObject
Set FSo = New Scripting.FileSystemObject
FSo.DeleteFolder (ThisWorkbook.Path & "\NewFolder")
'FSo.DeleteFolder (ThisWorkbook.Path & "\?")
End Sub
2.8. DriveExists
FSo.DriveExists(DriveSpec As String) As Boolean
Kiểm tra sự tồn tại của một ổ đĩa. Trả về True nếu nó tồn tại, ngược lại trả về False.
DriveSpec: Bắt buộc. Tên ổ đĩa cần kiểm tra.
Ví dụ:
Sub DriveExists()
'FSo.DriveExists(DriveSpec As String) As Boolean
Dim FSo As Scripting.FileSystemObject
Set FSo = New Scripting.FileSystemObject
MsgBox FSo.DriveExists("C:\")
End Sub
2.9. FileExists
P a g e 49 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Kiểm tra sự tồn tại của một tập tin. Trả về True nếu nó tồn tại, ngược lại trả về False.
FileSpec: Bắt buộc. Đường dẫn đầy đủ của tập tin cần kiểm tra.
Ví dụ:
Sub FileExists()
'FSo.FileExists(FileSpec As String) As Boolean
Dim FSo As Scripting.FileSystemObject
Set FSo = New Scripting.FileSystemObject
MsgBox FSo.FileExists(ThisWorkbook.FullName)
End Sub
2.10. FolderExists
FSo.FolderExists(FolderSpec As String) As Boolean
Kiểm tra sự tồn tại của một thư mục. Trả về True nếu nó tồn tại, ngược lại trả về False.
FolderSpec: Bắt buộc. Đường dẫn đầy đủ của thư mục cần kiểm tra.
Ví dụ:
Sub FolderExists()
'FSo.FolderExists(FolderSpec As String) As Boolean
Dim FSo As Scripting.FileSystemObject
Set FSo = New Scripting.FileSystemObject
MsgBox FSo.FolderExists(ThisWorkbook.Path)
End Sub
2.11. GetAbsolutePathName
FSo.GetAbsolutePathName(Path As String) As String
Trả về đường dẫn đầy đủ từ ổ đĩa cho đường dẫn đưa vào.
Path: Bắt buộc. Là đường dẫn gợi ý để trả về đường dẫn đầy đủ.
Ví dụ:
Sub GetAbsolutePathName()
'FSo.GetAbsolutePathName(Path As String) As String
Dim FSo As Scripting.FileSystemObject
Set FSo = New Scripting.FileSystemObject
Dim sPath As String
sPath = FSo.GetAbsolutePathName(ThisWorkbook.Name)
MsgBox sPath
End Sub
2.12. GetBaseName
FSo.GetBaseName(Path As String) As String
Trả về tên cơ sở của một tập tin (tên của tập tin không gồm phần mở rộng) hoặc tên của thư
mục cho thành phần cuối cùng trong một đường dẫn chỉ định đưa vào.
Path: Bắt buộc. Là đường dẫn của tập tin hay thư mục đưa vào.
Lưu ý: Path có thể là đường dẫn của tập tin hoặc thư mục.
Ví dụ:
P a g e 50 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Sub GetBaseName()
'FSo.GetBaseName(Path As String) As String
Dim FSo As Scripting.FileSystemObject
Set FSo = New Scripting.FileSystemObject
Dim sPath As String
sPath = FSo.GetBaseName(ThisWorkbook.Name)
'sPath = FSo.GetBaseName(ThisWorkbook.Path)
MsgBox sPath
End Sub
2.13. GetDrive
FSo.GetDrive(DriveSpec As String) As Drive
Trả về đối tượng Drive (ổ đĩa) tương ứng với ổ đĩa trong đường dẫn chỉ định đưa vào.
DriveSpec: Bắt buộc. Có thể ở dạng tên ổ đĩa (C,D,E), hoặc ở dạng (C:, D: ), ở dạng (C:\, D:\ ),
hoặc ở dạng chia sẻ trong LAN (\\Computer\Folder2).
Đối tượng Drive có 12 thuộc tính.
Ví dụ:
Sub GetDrive()
'FSo.GetDrive(DriveSpec As String) As Drive
Dim FSo As Scripting.FileSystemObject
Set FSo = New Scripting.FileSystemObject
Dim dDrive As Drive
Set dDrive = FSo.GetDrive("C:\")
MsgBox GetDriveProperties(dDrive)
End Sub
2.14. GetDriveName
P a g e 51 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
2.15. GetExtensionName
FSo.GetExtensionName(Path As String) As String
2.16. GetFile
FSo.GetFile(FilePath As String) As File
P a g e 52 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Các phương thức của đối tượng File: Copy, Delete, Move, OpenTextStream
Sub FileMethods()
Dim FSo As Scripting.FileSystemObject
Set FSo = New Scripting.FileSystemObject
Dim oFile As File
Set oFile = FSo.GetFile(ThisWorkbook.FullName)
'oFile.Copy (Destination As String, [OverWriteFiles As Boolean = True])
'oFile.Delete([Force As Boolean = False])
'oFile.Move(Destination As String)
'oFile.OpenAsTextStream([IOMode As IOMode = ForReading],[Format As Tristate =
TristateFalse]) As TextStream
2.17. GetFileName
FSo.GetFileName(Path As String) As String
Trả về tên của tập tin gồm cả phần mở rộng hoặc tên của thư mục cho thành phần cuối cùng
trong một đường dẫn chỉ định đưa vào.
Path: Bắt buộc. Là đường dẫn của tập tin hoặc thư mục chỉ định.
Phương thức GetFileName trả về một chuỗi chứa tên tệp tin hoặc tên thư mục cho thành phần
cuối cùng trong một đường dẫn được chỉ định.
Lưu ý:
- Nếu Path là đường dẫn của File thì:
GetFileName = GetBaseName & "." & GetExtensionName
GetFileName = oFile.Name
Ví dụ:
Sub GetFileName()
'FSo.GetFileName(Path As String) As String
P a g e 53 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
2.18. GetFolder
FSo.GetFolder(FolderPath As String) As Folder
P a g e 54 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Các phương thức của đối tượng Folder: Copy, CreateTextFile, Delete, Move
Sub FolderMethods()
Dim FSo As Scripting.FileSystemObject
Set FSo = New Scripting.FileSystemObject
Dim oFolder As Folder
Set oFolder = FSo.GetFolder(ThisWorkbook.Path)
'oFolder.Copy(Destination As String, [OverWriteFiles As Boolean = True])
'oFolder.CreateTextFile(FileName As String, [OverWrite As Boolean = True], [Unicode As
Boolean = False]) As TextStream
'oFolder.Delete(Force As Boolean = False])
'oFolder.Move(Destination As String)
2.19. GetParentFolderName
FSo.GetParentFolderName(Path As String) As String
Trả về đường dẫn của thư mục chính (thư mục cha) của thành phần cuối cùng trong một đường
dẫn chỉ định đưa vào.
Path: Bắt buộc. Là đường dẫn của một tập tin hoặc một thư mục chỉ định.
Ví dụ:
Sub GetParentFolderName()
'FSo.GetParentFolderName(Path As String) As String
Dim FSo As Scripting.FileSystemObject
Set FSo = New Scripting.FileSystemObject
Dim sFolder As String
sFolder = FSo.GetParentFolderName(ThisWorkbook.FullName)
'sFolder = FSo.GetParentFolderName(ThisWorkbook.Path)
MsgBox sFolder
End Sub
2.20. GetSpecialFolder
FSo.GetSpecialFolder(SpecialFolder as SpecialFolderConst) As Folder
Trả về đối tượng Folder (thư mục) đặc biệt của hệ điều hành Windows.
SpecialFolder: Bắt buộc. Là hằng số tương ứng với thư mục đặc biệt của Windows.
0 = WindowsFolder - Contains files installed by the Windows operating system
1 = SystemFolder - Contains libraries, fonts, and device drivers
2 = TemporaryFolder - Used to store temporary files
Ví dụ:
P a g e 55 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Sub GetSpecialFolder()
'FSo.GetSpecialFolder(SpecialFolder as SpecialFolderConst) As Folder
'SpecialFolderConst:
'0=WindowsFolder - Contains files installed by the Windows operating system
'1=SystemFolder - Contains libraries, fonts, and device drivers
'2=TemporaryFolder - Used to store temporary files
Dim FSo As Scripting.FileSystemObject
Set FSo = New Scripting.FileSystemObject
Dim specFolder As Folder
Set specFolder = FSo.GetSpecialFolder(0)
MsgBox specFolder.Name 'Windows
End Sub
2.21. GetTempName
FSo.GetTempName
Ví dụ:
Sub GetTempName()
'FSo.GetTempName
Dim FSo As Scripting.FileSystemObject
Set FSo = New Scripting.FileSystemObject
Dim tmpFile As String, specFolder As Folder
Set specFolder = FSo.GetSpecialFolder(2)
tmpFile = FSo.GetTempName
MsgBox tmpFile
'specFolder.CreateTextFile (tmpFile) 'Create a temp file in the "Temp" folder.
End Sub
2.22. MoveFile
FSo.MoveFile(Source As String, Destination As String)
Di chuyển một hoặc nhiều tập tin (Files) tới địa chỉ chỉ định.
Sourve: Bắt buộc. Tên của môt hoặc nhiều tập tin cần di chuyển, có thể sử dụng ký tự đại diện
(*?).
Destination: Đường dẫn địa chỉ cần di chuyển tới. Không thể sử dụng ký tự đại diện.
Ví dụ:
Sub MoveFile()
'FSo.MoveFile(Source As String, Destination As String)
Dim FSo As Scripting.FileSystemObject
Set FSo = New Scripting.FileSystemObject
Dim sFiles As String, dPath As String
sFiles = "D:\Example\*.txt"
dPath = "E:\NewFolder"
FSo.MoveFile sFiles, dPath
End Sub
2.23. MoveFolder
P a g e 56 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Di chuyển một hoặc nhiều thư mục (Folders) tới địa chỉ chỉ định.
Sourve: Bắt buộc. Tên của môt hoặc nhiều thư mục cần di chuyển, có thể sử dụng ký tự đại
diện (*?).
Destination: Đường dẫn địa chỉ cần di chuyển tới. Không thể sử dụng ký tự đại diện.
Ví dụ:
Sub MoveFolder()
'FSo.MoveFolder(Sourve As String, Destination As String)
Dim FSo As Scripting.FileSystemObject
Set FSo = New Scripting.FileSystemObject
Dim sFolders As String, dPath As String
sFolders = "D:\Example2\*"
dPath = "E:\NewFolder2"
FSo.MoveFolder sFolders, dPath
End Sub
2.24. OpenTextFile
FSo.OpenTextFile(FileName As String, [IOMode As IOMode = ForReading], [Create As
Boolean = False], [Format As Tristate = TristateFalse]) as TextStream
Mở ra một tệp được chỉ định và trả về một đối tượng TextStream có thể được sử dụng để truy
cập tập tin đó.
FileName: Bắt buộc. Là đường dẫn của tập tin cần mở.
IOMode: Không bắt buộc. Thiết lập kiểu mở tập tin. Mặc định là ForReading.
1 = ForReading - Mở một tập tin để đọc. Không thể ghi thêm nội dung vào tập tin
2 = ForWriting - Mở một tập tin để ghi thêm nội dung.
8 = ForAppending - Mở một tập tin và ghi vào cuối của tập tin.
Create: Không bắt buộc. Thiết lập liệu một tập tin mới có thể được tạo ra nếu tên tập tin đưa
vào không tồn tại. True tức là tạo một tập tin mới, False không tạo một tập tin mới. Mặc định là
False.
Format: Không bắt buộc. Là định dạng mở tập tin.
0 = TristateFalse - Mở tệp dưới dạng ASCII. Đây là giá trị mặc định.
-1 = TristateTrue - Mở tập tin dưới dạng Unicode.
-2 = TristateUseDefault - Mở tập tin bằng cách sử dụng hệ thống mặc định.
Ví dụ:
Sub OpenTextFile()
'FSo.OpenTextFile(FileName As String, [IOMode As IOMode = ForReading], [Create As
Boolean = False], [Format As Tristate = TristateFalse]) as TextStream
Dim FSo As Scripting.FileSystemObject
Set FSo = New Scripting.FileSystemObject
Dim txtFile As TextStream, sText As String
Set txtFile = FSo.OpenTextFile("D:\Test1.txt", ForReading, False, TristateUseDefault)
sText = txtFile.ReadAll
txtFile.Close
MsgBox sText
End Sub
P a g e 57 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
3. Thuộc tính
Trả về một Collection, cung cấp chi tiết về tất cả các ổ đĩa (Drives) được gắn vào hệ thống,
hoặc là vật lý hoặc là logic. Có 2 thuộc tính: Count và Item
Count: Trả về số ổ đĩa được gắn vào hệ thống.
FSo.Drives.Count
Item: Trả về đối tượng ổ đĩa (Drive) theo Key chỉ định.
FSo.Drives.Item(Key) As Drive
Hoặc
FSo.Drives(Key) As Drive
Tương đương với phương thức GetDrive của FSo: FSo.GetDrive(DriveSpec As String) As
Drive
Ví dụ:
Sub Drives()
'FSo.Drives:
'1:
'FSo.Drives.Count 'Tra ve so luong o dia gan vao he thong
'2:
'FSo.Drives.Item(Key) As Drive 'Tra ve doi tuong o dia theo key chi dinh
'FSo.Drives(Key) As Drive 'Tra ve doi tuong o dia theo key chi dinh
'= FSo.GetDrive(DriveSpec As String) As Drive 'Phuong thuc GetDrive cua FSo
P a g e 58 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Trả về một Collection, cung cấp tất cả các tập tin (Files) có trong thư mục đó.
Có 2 thuộc tính: Count và Item
Count: Trả về số lượng tập tin có trong thư mục đó.
objFolder.Files.Count
Tương đương với phương thức GetFile của FSo: FSo.GetFile(FilePath As String) As File
Ví dụ:
Sub FolderProperties_Files()
'objFolder.Files:
'1:
'objFolder.Files.Count 'Tra ve so luong Files trong Folder
'2:
'objFolder.Files.Item(Key) As File 'Tra ve duoi tuong File theo Key chi dinh
'objfolder.Files(Key) As File 'Tra ve duoi tuong File theo Key chi dinh
'= FSo.GetFile(FilePath As String) As File 'Phuong thuc GetFile cua FSo
Trả về một Collection, cung cấp tất cả các thư mục (Folders) có trong thư mục đó.
- Có 1 phương thức: Add
Tạo mới một Folder:
objFolder.SubFolders.Add(Name As String) As Folder
Tương đương với phương thức CreateFolder của FSo: FSo.CreateFolder(Path As String) As
Folder
- Có 2 thuộc tính: Count và Item
Count: Trả về số lượng Folders có trong Folder chỉ định đưa vào.
P a g e 59 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
objFolder.SubFolders.Count
Tương đương với phương thức GetFolder của FSo: FSo.GetFolder(FolderPath As String) As
Folder
Ví dụ:
Sub FolderProperties_SubFolders()
'objFolder.SubFolders:
'1:
'objFolder.SubFolders.Add(Name As String) As Folder 'Tao mot Folder
'= FSo.CreateFolder(Path As String) As Folder 'Tuong duong voi phuong thuc
CreateFolder cua FSo
'2:
'objFolder.SubFolders.Count 'Tra ve so luong Folders co trong Folder dang
xet
'3:
'objFolder.SubFolders.Item(Key) As Folder 'Tra ve duoi tuong Folder theo Key chi
dinh
'objFolder.SubFolders(Key) As Folder 'Tra ve duoi tuong Folder theo Key chi
dinh
'= FSo.GetFolder(FolderPath As String) As Folder 'Tuong duong voi phuong thuc
GetFolder cua FSo
Dim FSo As Scripting.FileSystemObject
Set FSo = New Scripting.FileSystemObject
Dim objFolder As Folder, countFolders As Long, oFolder As Folder, sFolder As String
Set objFolder = FSo.GetFolder(ThisWorkbook.Path)
sFolder = "NewFolder2"
countFolders = objFolder.SubFolders.Count
If FSo.FolderExists(objFolder.Path & "\" & sFolder) = False Then
objFolder.SubFolders.Add sFolder
End If
Set oFolder = objFolder.SubFolders.Item(sFolder)
If objFolder.SubFolders.Count > countFolders Then
MsgBox "The new folder is: " & oFolder.Name
End If
End Sub
P a g e 60 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
ReadTextFile = sText
End Function
'// Tra ve danh sach Files trong mot Folder chi dinh, theo kieu loai File chi dinh (co the su dung
ky tu dai dien *?)
'typeName=0: Tra ve danh sach ten cua File (File.Name, gom phan mo rong cua File)
'typeName=1: Tra ve danh sach ten co so cua File (BaseName, khong gom phan mo rong cua
File)
'typeName=2: Tra ve danh sach duong dan day du cua File (File.Path)
'typeName=3: Tra ve danh sach duong dan rut gon cua File (File.ShortPath)
Public Function GetFilesInFolder(ByVal pathFolder As String, ByVal extensionFile As String,
Optional ByVal typeName As Byte = 0)
Dim FSo As Object, objFolder As Folder, objFile As File, Result(), i As Long
Set FSo = CreateObject("Scripting.FileSystemObject")
Set objFolder = FSo.GetFolder(pathFolder)
extensionFile = VBA.UCase(extensionFile)
For Each objFile In objFolder.Files
If VBA.UCase(FSo.GetExtensionName(objFile)) Like extensionFile Then
i=i+1
ReDim Preserve Result(1 To i)
Select Case typeName
Case 0
Result(i) = objFile.Name
Case 1
Result(i) = FSo.GetBaseName(objFile.Path)
Case 2
Result(i) = objFile.Path
Case 3
Result(i) = objFile.ShortPath
End Select
End If
Next objFile
GetFilesInFolder = Result
End Function
'// Tra ve duong dan day du cua Folder duoc chon. Neu khong chon thi tra ve chuoi rong
(len(chuoi)=0)
Public Function GetPathFolder(ByVal pathFolder As String) As String
Dim fDlog As FileDialog, sItem As String
Set fDlog = Application.FileDialog(msoFileDialogFolderPicker)
With fDlog
.Title = "Select a Folder"
.AllowMultiSelect = False
.InitialFileName = pathFolder
If .Show <> -1 Then GoTo NextCode
sItem = .SelectedItems(1)
End With
NextCode:
GetPathFolder = sItem
P a g e 61 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
'// Xoa Files trong Folder chi dinh, loai File chi dinh (co the su dung ky tu dai dien *?)
'=== Ghi chu: Can trong khi su dung ===
Public Sub DeleteFiles(ByVal pathFolder As String, ByVal extensionFile As String, Optional
ByVal Force As Boolean = False)
Dim FSo As Object, objFile As File
Set FSo = CreateObject("Scripting.FileSystemObject")
extensionFile = VBA.UCase(extensionFile)
With FSo.GetFolder(pathFolder)
For Each objFile In .Files
If VBA.UCase(FSo.GetExtensionName(objFile)) Like extensionFile Then
FSo.DeleteFile objFile, Force
End If
Next objFile
End With
End Sub
P a g e 62 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
2.1. Add
myCol.Add (Item, [Key], [Before], [After])
2.2. Count
myCol.Count
P a g e 63 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
myCol.Add i
Next i
MsgBox myCol.Count
End Sub
2.3. Item
myCol.Item (Index)
'Hoặc:
myCol(Index)
'Hoặc:
myCol(Key)
Gọi tới Item của collection theo chỉ số của Item hoặc theo Key ứng với Item đó.
Ví dụ:
Sub ItemMethod()
Dim myCol As Collection
Set myCol = New Collection
myCol.Add "A", "KeyA"
MsgBox myCol.Item(1)
MsgBox myCol(1)
MsgBox myCol("KeyA")
End Sub
2.4. Remove
mycol.Remove(Index)
'Hoặc
mycol.Remove(Key)
Xóa một Item trong collection theo chỉ số của Item hoặc Key ứng với Item đó.
Ví dụ:
Sub Remove()
Dim myCol As Collection
Set myCol = New Collection
myCol.Add "A", "KeyA"
myCol.Add 10, "2"
myCol.Add 20, "Key3"
myCol.Remove (2)
myCol.Remove ("Key3")
MsgBox myCol.Count
End Sub
3. Ứng dụng
- Lọc loại trùng
- Sắp xếp dữ liệu
'// Kiem tra su ton tai cua mot key trong Collection'
Public Function KeyExists(myCol As Collection, ByVal keyCheck As String) As Boolean
KeyExists = False
On Error GoTo EndFunction
myCol.Item keyCheck
P a g e 64 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
KeyExists = True
EndFunction:
End Function
P a g e 65 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
End If
Loop
If firstIndex < valMax Then SortingCollection myCol, firstIndex, valMax
If valMin < lastIndex Then SortingCollection myCol, valMin, lastIndex
End Sub
P a g e 66 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
2.1. Add
HTbl.Add Key, Item
Ví dụ:
Sub AddMethod()
Dim HTbl As Object
Set HTbl = CreateObject("System.Collections.Hashtable")
'HTbl.Add Key, Item'
'Key: number + string, Duy nhat. Gap loi khi Key da ton tai trong HTbl'
'Item: number + string'
HTbl.Add 10, 100
HTbl.Add "KeyA", 200
HTbl.Add "KeyB", "TextB"
HTbl.Add 20, 5
HTbl.Add "KeyC", ""
HTbl.Add "KeyD", Array(20, 25)
End Sub
P a g e 67 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
2.2. Count
HTbl.Count
2.3. Item
HTbl.Item (Key)
'Hoặc:'
HTbl(Key)
2.4. Remove
HTbl.Remove(Key)
Xóa một Item trong Hashtable theo Key chỉ định ứng với Item đó.
Ví dụ:
Sub RemoveMethod()
Dim HTbl As Object
Set HTbl = CreateObject("System.Collections.Hashtable")
'HTbl.Remove(Key)'
Dim i As Long
For i = 1 To 10
P a g e 68 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
2.5. ContainsKey
HTbl.ContainsKey(Key)
Kiểm tra sự tồn tại của một Key trong Hashtable. Trả về True nếu Key đó tồn tại, ngược lại trả
về False.
Ví dụ:
Sub ContainsKeyMethod()
Dim HTbl As Object
Set HTbl = CreateObject("System.Collections.Hashtable")
'HTbl.ContainsKey(Key)'
HTbl.Add 10, 100
HTbl.Add "KeyA", 200
MsgBox HTbl.Containskey(10) 'True'
MsgBox HTbl.Containskey("KeyA") 'True'
MsgBox HTbl.Containskey("KeyX") 'False'
End Sub
2.6. ContainsValue
HTbl.ContainsValue(Value)
Kiểm tra sự tồn tại giá trị của Item trong Hashtable. Trả về True nếu giá trị đó đã tồn tại, ngược
lại trả về False.
Ví dụ:
Sub ContainsValueMethod()
Dim HTbl As Object
Set HTbl = CreateObject("System.Collections.Hashtable")
'HTbl.ContainsValue(Value)'
HTbl.Add 10, 100
HTbl.Add "KeyA", "TextA"
MsgBox HTbl.ContainsValue(100) 'True'
MsgBox HTbl.ContainsValue("TextA") 'True'
MsgBox HTbl.ContainsValue("TextB") 'False'
End Sub
3. Ứng dụng
- Lọc loại trùng
-…
P a g e 69 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
P a g e 70 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
2.1. Push
oStack.Push Item
Thêm một Item vào vị trí trên cùng (top) của Stack.
Item nhận kiểu dữ liệu bất kỳ (kiểu số hoặc chuỗi), giá trị đơn hoặc một mảng (array).
Ví dụ:
Sub PushMethod()
'Dim oStack As New Stack'
Dim oStack As Object
Set oStack = CreateObject("System.Collections.Stack")
'oStack.Push Item'
oStack.Push 5
oStack.Push "TextA"
oStack.Push ""
End Sub
2.2. Count
oStack.Count
P a g e 71 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
'oStack.Count'
oStack.Push 5
oStack.Push "TextA"
MsgBox oStack.Count '2'
End Sub
2.3. Peek
oStack.Peek
Trả về Item trên cùng của Stack và không xóa Item đó.
Ví dụ:
Sub PeekMethod()
Dim oStack As Object, i As Long
Set oStack = CreateObject("System.Collections.Stack")
'oStack.Peek'
For i = 1 To 10
oStack.Push "Value-" & i
Next i
MsgBox oStack.Peek 'Value-10'
End Sub
2.4. Pop
oStack.Pop
2.5. Contains
oStack.Contains
Kiểm tra sự tồn tại của một Item trong Stack. Trả về True nếu Item đó tồn tại, ngược lại trả về
False.
Ví dụ:
Sub ContainsMethod()
Dim oStack As Object
Set oStack = CreateObject("System.Collections.Stack")
'oStack.Contains'
oStack.Push 5
P a g e 72 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
oStack.Push "TextA"
MsgBox oStack.Contains(5) 'True'
MsgBox oStack.Contains("TextA") 'True'
MsgBox oStack.Contains("TextB") 'False
End Sub
2.6. ToArray
oStack.ToArray
Sao chép các Item trong Stack vào một mảng (Array). Mảng trả về là mảng một chiều, chỉ số
cận dưới của mảng luôn bằng 0, cho dù thiết lập Option Base 1.
Ví dụ:
Sub ToArrayMethod()
Dim oStack As Object, i As Long, arr()
Set oStack = CreateObject("System.Collections.Stack")
'oStack.ToArray Mang 1 chieu,cac phan tu trong mang xep nguoc, khong phu thuoc
Option Base 1'
For i = 1 To 10
oStack.Push i
Next i
arr = oStack.ToArray
MsgBox arr(0) '10'
End Sub
2.7. Clear
oStack.Clear
2.8. Clone
oStack.Clone
P a g e 73 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
oStack.push 20
Set newStack = oStack.Clone
MsgBox newStack.Peek '20'
End Sub
2.9. ToString
oStack.ToString
2.10. GetHashCode
oStack.GetHashCode
...
3. Ứng dụng
- Lọc loại trùng
-…
3.2. Hàm truyền các Items của Stack sang mảng 2 chiều
P a g e 74 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
3.3. Ví dụ so sánh tốc độ Add Keys với kiểu dữ liệu là kiểu số:
Stack:
Sub AddKeys_Stack()
Dim TT As Double
TT = Timer
Dim oStack As Object
Set oStack = CreateObject("System.Collections.Stack")
Dim x As Long, y As Long, i As Long
x = 1000000000
y = 1000020000
For i = x To y
If oStack.Contains(i) = False Then
oStack.push i
End If
Next i
Set oStack = Nothing
MsgBox Round(Timer - TT, 2) '1.64-1.78 giây'
End Sub
Hashtable:
Sub AddKeys_Hashtable()
Dim TT As Double
TT = Timer
Dim HTbl As Object
Set HTbl = CreateObject("System.Collections.Hashtable")
P a g e 75 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Dictionary:
Sub AddKeys_Dictionary()
Dim TT As Double
TT = Timer
Dim Dic As Object
Set Dic = CreateObject("Scripting.Dictionary")
Dim x As Long, y As Long, i As Long
x = 1000000000
y = 1000020000
For i = x To y
If Dic.Exists(i) = False Then
Dic.Add i, ""
End If
Next i
Set Dic = Nothing
MsgBox Round(Timer - TT, 2) '5.96-6.09 giây'
End Sub
P a g e 76 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Queue là một thư viện nằm trong “System.Collections.” của .NET Framework. cùng.
Đây là cấu trúc dữ liệu dựng theo hàng để thực hiện tính chất FIFO (First In - First Out / Vào
trước - Ra trước).
Cho phép lưu trữ dữ liệu (items) có kích cỡ lớn, rất hữu ích trong các tình huống muốn lưu trữ
các Items theo thứ tự chỉ định.
Yêu cầu: Hệ thống phải cài đặt .NET Framework
2.2. Enqueue
oQueue.Enqueue Item
Thêm một Item vào vị trí cuối cùng (end) của Queue.
Item nhận kiểu dữ liệu bất kỳ (kiểu số hoặc chuỗi), giá trị đơn hoặc một mảng (array).
Ví dụ:
Sub EnqueueMethod()
Dim oQueue As Object
P a g e 77 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
2.3. Peek
oQueue.Peek
Trả về Item đầu tiên của Queue và không xóa Item đó.
Ví dụ:
Sub PeekMethod()
Dim oQueue As Object, i As Long
Set oQueue = CreateObject("System.Collections.Queue")
'oQueue.Peek'
For i = 1 To 10
oQueue.Enqueue "Value-" & i
Next i
MsgBox oQueue.Peek 'Value-1'
End Sub
2.4. Dequeue
oQueue.Dequeue
2.5. Contains
oQueue.Contains
Kiểm tra sự tồn tại của một Item trong Queue. Trả về True nếu Item đó tồn tại, ngược lại trả về
False.
Ví dụ:
Sub ContainsMethod()
Dim oQueue As Object
Set oQueue = CreateObject("System.Collections.Queue")
'oQueue.Contains'
P a g e 78 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
oQueue.Enqueue 5
oQueue.Enqueue "TextA"
MsgBox oQueue.Contains(5) 'True'
MsgBox oQueue.Contains("TextA") 'True'
MsgBox oQueue.Contains("TextB") 'False
End Sub
2.6. ToArray
oQueue.ToArray
Sao chép các Item trong Queue vào một mảng (Array). Mảng trả về là mảng một chiều, chỉ số
cận dưới của mảng luôn băng 0, cho dù thiết lập Option Base 1.
Ví dụ:
Sub ToArrayMethod()
Dim oQueue As Object, i As Long, arr()
Set oQueue = CreateObject("System.Collections.Queue")
'oQueue.ToArray Mang 1 chieu, khong phu thuoc Option Base 1'
For i = 1 To 10
oQueue.Enqueue "Value-" & i
Next i
arr = oQueue.ToArray
MsgBox arr(0) 'Value-1'
End Sub
2.7. ToString
oQueue.ToString
2.8. Clear
oQueue.Clear
P a g e 79 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
oQueue.Clear
MsgBox oQueue.Count '0'
End Sub
2.9. Clone
oQueue.Clone
3. Ứng dụng
- Lọc loại trùng
-…
P a g e 80 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
SortedList là một thư viện nằm trong “System.Collections” của .NET Framework.
SortedList lưu trữ các Items theo Keys tương ứng thành cặp, được sắp xếp theo các Keys, cho
phép truy cập tới Item theo Key hoặc chỉ mục (index) ứng với Item đó.
Yêu cầu: Hệ thống phải cài đặt .NET Framework v1.1 trở lên.
2.1. Count
oSList.Count
2.2. Capacity
oSList.Capacity
Trả về số lượng các phần tử hoặc đặt (thiết lập) số lượng các phần tử mà SortedList có thể lưu
trữ.
+ Các lỗi xảy ra đặt số lượng các phần tử cho SortedList:
- Khi giá trị của Capacity nhỏ hơn số lượng phần từ đã tồn tại trong SortedList (count).
P a g e 81 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
- Khi giá trị của Capacity trả về SortedList có kích thước vượt dung lượng bộ nhớ có thể dùng
của hệ thống (OutOfMemoryException).
+ Capacity luôn luôn lớn hơn hoặc bằng Count. Nếu Count vượt quá Capacity trong khi thêm
các phần tử, Capacity sẽ tự động tăng lên bằng cách tái phân bổ lại mảng nội bộ trước khi sao
chép các phần tử cũ và thêm các phần tử mới.
+ Có thể giảm Capacity bằng cách dùng phương thức TrimToSize hoặc bằng cách thiết lập giá
trị Capacity cụ thể (nhưng phải đảm bảo >= Count, nếu không sẽ xảy ra lỗi). Khi giá trị của
Capacity được xác định cụ thể, mảng nội bộ cũng được phân bổ lại để đáp ứng dung lượng đã
xác định.
Ví dụ:
Sub CapacityProperty()
'oSList.Capacity'
Dim oSList As Object, vCnt As Long, vCty As Long, i As Long
Set oSList = CreateObject("System.Collections.SortedList")
For i = 1 To 5
oSList.Add "Key-" & i, i
Next i
vCnt = oSList.Count '5'
vCty = oSList.capacity '16'
oSList.capacity = 5
MsgBox oSList.capacity '5'
End Sub
2.3. Item
oSList.Item(Key)
'Hoặc:'
oSList(Key)
Trả về giá trị của Item theo Key chỉ định trong SortedList, hoặc gán giá trị mới cho Item theo
Key của Item đó.
- Nếu gán một giá trị cho một Item theo một Key chưa tồn tại trong SortedList thì SortedList tự
động thêm Key đó, và Item đó có giá trị vừa đưa vào.
Ví dụ:
Sub ItemProperty()
'oSList.Item(Key) '
'oSList(Key) '
Dim oSList As Object, i As Long
Set oSList = CreateObject("System.Collections.SortedList")
For i = 1 To 5
oSList.Add "Key-" & i, ""
Next i
oSList.Item("Key-1") = 100
MsgBox oSList("Key-1") '100'
oSList("KeyA") = 20
MsgBox oSList.Count '6'
End Sub
P a g e 82 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
3.1. Add
oSList.Add Key, Item
Ví dụ:
Sub AddMethod()
'oSList.Add Key, Item '
'Key: OR number OR string, <>null'
'Item: number, string, array'
'First index = 0 '
Dim oSList As Object
Set oSList = CreateObject("System.Collections.SortedList")
oSList.Add "5", 20
oSList.Add "KeyA", "Item2"
oSList.Add "KeyB", ""
oSList.Add "KeyC", Array(12, 40)
End Sub
3.2. Clear
oSortedList.Clear
3.3. Clone
oSortedList.Clone
P a g e 83 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Sub CloneMethod()
'oSList.Clone'
Dim oSList As Object, i As Long, newSList As Object
Set oSList = CreateObject("System.Collections.SortedList")
For i = 1 To 5
oSList.Add i, ""
Next i
Set newSList = oSList.Clone
MsgBox newSList.Count '5'
End Sub
Kiểm tra sự tồn tại của một Key trong SortedList. Trả về True nếu Key đã tồn tại trong
SortedList, ngược lại trả về False.
Lưu ý: Key chỉ định kiểm tra phải cùng kiểu dữ liệu (số hoặc chuỗi) với kiểu dữ liệu của Key
đã có trong SortedList, nếu không xảy ra lỗi.
Ví dụ:
Sub ContainsMethod()
'oSList.Contains(Key)'
Dim oSList As Object, i As Long, sKey As String
Set oSList = CreateObject("System.Collections.SortedList")
For i = 1 To 5
oSList.Add "Key-" & i, i
Next i
sKey = "Key-2"
MsgBox oSList.Contains(sKey) 'True'
End Sub
Sub ContainsKeyMethod()
'oSList.ContainsKey(Key)'
Dim oSList As Object, i As Long, sKey As String
Set oSList = CreateObject("System.Collections.SortedList")
For i = 1 To 5
oSList.Add "Key-" & i, i
Next i
sKey = "Key-5"
MsgBox oSList.ContainsKey(sKey) 'True'
End Sub
3.5. ContainsValue
oSList.ContainsKey(Key)
Kiểm tra sự tồn tại giá trị của một Item trong SortedList. Trả về True nếu giá trị đó đã tồn tại
trong SortedList, ngược lại trả về False.
Ví dụ:
P a g e 84 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Sub ContainsValueMethod()
'oSList.ContainsKey(Key)'
Dim oSList As Object
Set oSList = CreateObject("System.Collections.SortedList")
oSList.Add "KeyA", 2
oSList.Add "KeyB", ""
oSList.Add "KeyC", "Item3"
MsgBox oSList.ContainsValue(2) 'True'
MsgBox oSList.ContainsValue("") 'True'
MsgBox oSList.ContainsValue("Item4") 'False'
End Sub
3.6. GetByIndex
oSList.GetByIndex(Index)
Trả về giá trị của một Item trong SortedList theo chỉ mục (Index) chỉ định.
Ví dụ:
Sub GetByIndexMethod()
'oSList.GetByIndex(Index) //Index = 0 : Count-1 / Return: Item'
Dim oSList As Object, i As Long, sKey
Set oSList = CreateObject("System.Collections.SortedList")
For i = 1 To 5
oSList.Add "Key-" & i, "Value-" & i
Next i
sKey = oSList.GetByIndex(0)
MsgBox sKey '"Value-1"'
End Sub
3.7. GetKey
oSList.GetKey(Index)
Trả về một Key có trong SortedList theo chỉ mục (Index) chỉ định.
Index: Có giá trị từ 0 tới Count-1.
Ví dụ:
Sub GetKeyMethod()
'oSList.GetKey(Index) //Index = 0 : Count-1 '
Dim oSList As Object, i As Long, sKey
Set oSList = CreateObject("System.Collections.SortedList")
For i = 1 To 5
oSList.Add "Key-" & i, i
Next i
sKey = oSList.GetKey(0)
MsgBox sKey '"Key-1"'
End Sub
3.8. GetKeyList
oSList.GetKeyList
P a g e 85 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Trả về một đối tượng IList (System.Collections.IList) chứa toàn bộ Keys có trong SortedList.
Ví dụ:
Sub GetKeyListMethod()
'oSList.GetKeyList '
'Return an IList object (System.Collections.IList) containing the keys in the SortedList
object.'
Dim oSList As Object, i As Long, KeyList As Object
Set oSList = CreateObject("System.Collections.SortedList")
For i = 1 To 5
oSList.Add "Key-" & i, i
Next i
Set KeyList = oSList.GetKeyList
MsgBox KeyList.Item(0) '"Key-1"'
End Sub
3.9. GetValueList
oSList.GetValueList
Trả về một đối tượng IList (System.Collections.IList) chứa toàn bộ Items có trong SortedList.
Ví dụ:
Sub GetValueListMethod()
'oSList.GetValueList '
'Return an IList object (System.Collections.IList) containing the values in the SortedList
object.'
Dim oSList As Object, i As Long, ValueList As Object
Set oSList = CreateObject("System.Collections.SortedList")
For i = 1 To 5
oSList.Add "Key-" & i, i
Next i
Set ValueList = oSList.GetValueList
MsgBox ValueList.Item(4) '5'
End Sub
3.10. IndexOfKey
oSList.IndexOfKey(Key)
Trả về vị trí của Key chỉ định trong SortedList (FirstIndex = 0).
Nếu Key chỉ định không có trong SortedList thì kết quả trả về -1.
Các phần tử trong SortedList được sắp xếp chính xác theo Keys. Khi một phần tử được thêm,
nó được chèn vào SortedList theo thứ tự sắp xếp chính xác, và lập chỉ mục (Index) điều chỉnh
cho phù hợp. Khi một phần tử được loại bỏ, việc lập chỉ mục cũng điều chỉnh cho phù hợp. Do
đó, chỉ mục của cặp Key/ Item cụ thể có thể thay đổi khi các phần tử được thêm vào hoặc xoá
khỏi SortedList.
Ví dụ:
Sub IndexOfKeyMethod()
'oSList.IndexOfKey(Key)
Dim oSList As Object, idex As Long
P a g e 86 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
3.11. IndexOfValue
oSList.IndexOfValue(Item)
Trả về vị trí của Item chỉ định trong SortedList (FirstIndex = 0).
Nếu Item chỉ định không có trong SortedList thì kết quả trả về -1.
Ví dụ:
Sub IndexOfValueMethod()
'oSList.IndexOfValue(Item)'
Dim oSList As Object, idex As Long
Set oSList = CreateObject("System.Collections.SortedList")
oSList.Add "1", 20
oSList.Add "Z", 20
oSList.Add "A", "Item3"
idex = oSList.IndexOfValue(20) 'idex=0'
MsgBox idex
idex = oSList.IndexOfValue("Item3") 'idex=1'
MsgBox idex
idex = oSList.IndexOfValue("Item4")
MsgBox idex 'idex=-1'
End Sub
3.12. Remove
oSList.Remove Key
Xóa một phần tử trong SortedList theo Key chỉ định. Nếu Key chưa tồn tại trong SortedList thì
không xảy ra lỗi.
Khi một phần tử được loại bỏ, việc lập chỉ mục (Index) của các phần tử được điều chỉnh cho
phù hợp. Do đó, chỉ mục của cặp Key/ Item cụ thể có thể thay đổi khi các phần tử được thêm
vào hoặc xoá khỏi SortedList.
Ví dụ:
Sub RemoveMethod()
'oSList.Remove Key'
Dim oSList As Object
Set oSList = CreateObject("System.Collections.SortedList")
oSList.Add "Key-1", ""
oSList.Add "Key-2", ""
P a g e 87 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
oSList.Remove "Key-1"
MsgBox oSList.GetKey(0) ' "Key-2" '
End Sub
3.13. RemoveAt
oSList.RemoveAt Index
Xóa một Item trong SortedList theo chỉ số Index chỉ định.
Index: Có giá trị từ 0 tới Count-1.
Ví dụ:
Sub RemoveAtMethod()
'oSList.RemoveAt Index //Index = 0 : Count-1 '
Dim oSList As Object
Set oSList = CreateObject("System.Collections.SortedList")
oSList.Add "1", ""
oSList.Add "Z", ""
oSList.Add "A", ""
oSList.RemoveAt 1
MsgBox oSList.GetKey(1) ' "Z" '
End Sub
3.14. SetByIndex
oSList.SetByIndex Index, Item
Thay đổi giá trị của Item trong SortedList theo chỉ mục (Index) chỉ định.
Ví dụ:
Sub SetByIndexMethod()
'oSList.SetByIndex Index, Item //Index = 0 : Count-1 '
Dim oSList As Object
Set oSList = CreateObject("System.Collections.SortedList")
oSList.Add 0, 100
oSList.Add 1, 500
oSList.Add 2, 10
oSList.SetByIndex 0, "Item-1"
MsgBox oSList.GetByIndex(0)
End Sub
3.15. ToString
oSList.ToString
P a g e 88 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
3.16. TrimToSize
oSList.TrimToSize
Để thiết lập lại SortedList về trạng thái ban đầu, ta sử dụng phương thức Clear trước khi gọi
TrimToSize. Việc cắt một SortedList trống sẽ đặt Capacity của SortedList về giá trị mặc định.
Ví dụ:
Sub TrimToSizeMethod()
'oSList.TrimToSize '
Dim oSList As Object
Set oSList = CreateObject("System.Collections.SortedList")
oSList.Add "Key-1", 1
oSList.Add "Key-2", 2
MsgBox "Count = " & oSList.Count & vbNewLine & _
"Capacity = " & oSList.capacity '2-16'
oSList.TrimToSize
MsgBox "Count = " & oSList.Count & vbNewLine & _
"Capacity = " & oSList.capacity '2-2'
End Sub
4. Ứng dụng
Lọc loại trùng, sort mảng, …
4.1. Một số hàm
Hàm lọc loại trùng 1 cột của Range
'// Loc loai trung mot cot'
Function UniqueColumnSortedList(ByVal Rng As Range) As Variant
If Rng.Count = 1 Then UniqueColumnSortedList = Rng.Value: Exit Function
Dim oSList As Object, i As Long, j As Long, Arr(), Result(), sKey As Variant
Set oSList = CreateObject("System.Collections.SortedList")
Arr = Rng.Value
For i = LBound(Arr, 1) To UBound(Arr, 1)
sKey = Arr(i, 1)
If sKey <> "" Then
If oSList.ContainsKey(sKey) = False Then
oSList.Add sKey, ""
j=j+1
ReDim Preserve Result(1 To j)
Result(j) = sKey
End If
End If
Next i
UniqueColumnSortedList = Result
End Function
P a g e 89 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
P a g e 90 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
ArrayList là một thư viện nằm trong “System.Collections” của .NET Framework. Cho phép lưu
trữ dữ liệu (items) có kích cỡ lớn, kích thước của mảng lưu trữ tự động tăng theo yêu cầu, cho
phép truy xuất tới các items, sắp xếp các items đã nạp vào ArrayLis.
Yêu cầu: Hệ thống phải cài đặt .NET Framework v1.1 trở lên.
2.1. Count
oArrList.Count
2.2. Capacity
oArrList.Capacity
Trả về số lượng các phần tử hoặc đặt (thiết lập) số lượng các phần tử mà ArrayList có thể lưu
trữ.
+ Các lỗi xảy ra đặt số lượng các phần tử cho ArrayList:
P a g e 91 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
- Khi giá trị của Capacity nhỏ hơn số lượng phần từ đã tồn tại trong ArrayList (count).
- Khi giá trị của Capacity trả về ArrayList có kích thước vượt dung lượng bộ nhớ có thể dùng
của hệ thống (OutOfMemoryException).
+ Capacity luôn luôn lớn hơn hoặc bằng Count. Nếu Count vượt quá Capacity trong khi thêm
các phần tử, Capacity sẽ tự động tăng lên bằng cách tái phân bổ lại mảng nội bộ trước khi sao
chép các phần tử cũ và thêm các phần tử mới.
+ Có thể giảm Capacity bằng cách dùng phương thức TrimToSize hoặc bằng cách thiết lập giá
trị Capacity cụ thể (nhưng phải đảm bảo >= Count, nếu không sẽ xảy ra lỗi). Khi giá trị của
Capacity được xác định cụ thể, mảng nội bộ cũng được phân bổ lại để đáp ứng dung lượng đã
xác định.
Ví dụ:
Sub CapacityProperty()
'oArrList.Capacity'
Dim oArrList As Object, vCnt As Long, vCty As Long
Set oArrList = CreateObject("System.Collections.ArrayList")
For i = 1 To 5
oArrList.Add i
Next i
vCnt = oArrList.Count '5'
vCty = oArrList.Capacity '8'
oArrList.Capacity = 5
MsgBox oArrList.Capacity '5'
End Sub
2.3. Item
oArrList.Item(Index)
Trả về giá trị của Item theo chỉ số (index) chỉ định trong ArrayList, hoặc gán giá trị mới cho
Item theo chỉ số của Item đó.
Lưu ý: Chỉ số (index) của Item có giá trị từ 0 tới Count-1.
Ví dụ:
Sub ItemProperty()
'oArrList.Item(Index) -FirstIndex = 0'
Dim oArrList As Object
Set oArrList = CreateObject("System.Collections.ArrayList")
For i = 1 To 5
oArrList.Add "Value-" & i
Next i
oArrList.Item(4) = 100
MsgBox oArrList.Item(0) 'Value-1'
MsgBox oArrList.Item(4) '100'
End Sub
3.1. Add
oArrayList.Add Item
Thêm một Item vào vị trí cuối cùng (end) của ArrayList.
P a g e 92 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
3.2. AddRange
oArrList.AddRange ICollection
Thêm một đối tượng ICollection vào vị trí cuối cùng của ArrayList.
Icollection: Có thể là Stack, Queue, Hashtable, SortList, ArrayList
Ví dụ:
Sub AddRangeMethod()
'Adds the elements of an ICollection to the end of the ArrayList.'
'oArrList.AddRange ICollection'
Dim oArrList As Object, ArList1 As Object, itemList
Set oArrList = CreateObject("System.Collections.ArrayList")
Set ArList1 = CreateObject("System.Collections.ArrayList")
ArList1.Add 10
ArList1.Add 20
oArrList.Addrange ArList1
For Each itemList In oArrList
MsgBox itemList
P a g e 93 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Next
'Result: 10, 20'
End Sub
3.3. Clear
oArrayList.Clear
3.4. Clone
oArrayList.Clone
3.5. Contains
oArrList.Contains(Item)
Kiểm tra sự tồn tại của một Item trong ArrayList. Trả về True nếu Item đã tồn tại trong
ArrayList, ngược lại trả về False.
Ví dụ:
Sub ContainsMethod()
'oArrList.Contains(Item)'
Dim oArrList As Object, i As Long, valItem
Set oArrList = CreateObject("System.Collections.ArrayList")
For i = 1 To 5
oArrList.Add "Value-" & i
Next i
P a g e 94 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
valItem = oArrList(0)
MsgBox oArrList.Contains(valItem) 'True'
End Sub
3.6. IndexOf
oArrList.IndexOf(Item, index)
Trả về vị trí đầu tiên tìm thấy Item chỉ định, dò tìm từ vị trí Index chỉ định so với vị trí đầu tiên
trong ArrayList (FirstIndex = 0).
Ví dụ:
Sub IndexOf()
'oArrList.IndexOf(Item, index)'
Dim oArrList As Object, i As Long
Set oArrList = CreateObject("System.Collections.ArrayList")
oArrList.Add "Value-1"
oArrList.Add "Value-2"
oArrList.Add "Value-3"
oArrList.Add "Value-1"
oArrList.Add "Value-2"
oArrList.Add "Value-1"
i = oArrList.IndexOf("Value-1", 0) 'i=0'
i = oArrList.IndexOf("Value-1", 1) 'i=3'
i = oArrList.IndexOf("Value-1", 4) 'i=5'
End Sub
3.7. Insert
oArrList.Insert Index, Item
Chèn thêm một Item vào ArrayList theo vị trí (Index) chỉ định.
Index: Nhận giá trị từ 0 tới oArrList.Count. Gặp lỗi khi Index < 0 hoặc Index > Count.
Ví dụ:
Sub InsertMethod()
'oArrList.Insert Index, Item'
Dim oArrList As Object, i As Long
Set oArrList = CreateObject("System.Collections.ArrayList")
oArrList.Insert 0, 100
oArrList.Insert 1, 200
For i = 1 To 5
oArrList.Add i
Next i
oArrList.Insert 4, 30
oArrList.Insert oArrList.Count, 50
MsgBox oArrList.Item(oArrList.Count - 1) '50'
End Sub
3.8. InsertRange
oArrList.InsertRange Index, ICollection
Chèn thêm một đối tượng ICollection vào ArrayList theo vị trí (Index) chỉ định.
P a g e 95 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
3.9. LastIndexOf
oArrList.LastIndexOf(Item)
Trả về vị trí (Index) cuối cùng của Item tìm thấy trong ArrayList.
Ví dụ:
Sub LastIndexOfMethod()
'oArrList.LastIndexOf(Item)'
Dim oArrList As Object, i As Long
Set oArrList = CreateObject("System.Collections.ArrayList")
oArrList.Add "Value-1"
oArrList.Add "Value-2"
oArrList.Add "Value-3"
oArrList.Add "Value-1"
oArrList.Add "Value-2"
oArrList.Add "Value-1"
i = oArrList.LastIndexOf("Value-1") 'i=5'
End Sub
3.10. Remove
oArrList.Remove Item
Xóa một Item chỉ định trong ArrayList. Nếu Item chưa tồn tại trong ArrayList thì không xảy ra
lỗi.
Nếu Item có nhiều giá trị như nhau thì sẽ xóa Item xuất hiện đầu tiên.
Ví dụ:
Sub RemoveMethod()
'oArrList.Remove Item'
Dim oArrList As Object
Set oArrList = CreateObject("System.Collections.ArrayList")
oArrList.Add "Value-1"
oArrList.Add "Value-2"
P a g e 96 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
oArrList.Add "Value-3"
oArrList.Add "Value-1"
oArrList.Add "Value-2"
oArrList.Add "Value-3"
oArrList.Remove "Value-1"
MsgBox oArrList.Item(0) ' "Value-2" '
End Sub
3.11. RemoveAt
oArrList.RemoveAt Index
Xóa một Item trong ArrayList theo chỉ số Index chỉ định.
Index: Có giá trị từ 0 tới Count-1.
Ví dụ:
Sub RemoveAtMethod()
'oArrList.RemoveAt Index'
Dim oArrList As Object
Set oArrList = CreateObject("System.Collections.ArrayList")
oArrList.Add "Value-1"
oArrList.Add "Value-2"
oArrList.Add "Value-3"
oArrList.Add "Value-4"
oArrList.RemoveAt 2
MsgBox oArrList.Item(2) ' "Value-4" '
End Sub
3.12. RemoveRange
oArrList.RemoveRange IndexFrom, NumberOfItems
Xóa các Items có trong ArrayList từ vị trí chỉ định, số lượng Items cần xóa được chỉ định.
IndexFrom: Vị trí Item đầu tiên cần xóa. Index có giá trị từ 0 tới Count-1.
NumberOfItems: Số Item cần xóa. NumberOfItems có giá trị từ 0 tới (Count - Index).
Ví dụ:
Sub RemoveRangeMethod()
'oArrList.RemoveRange IndexFrom, NumberOfItems '
Dim oArrList As Object
Set oArrList = CreateObject("System.Collections.ArrayList")
oArrList.Add "Value-1"
oArrList.Add "Value-2"
oArrList.Add "Value-3"
oArrList.Add "Value-4"
oArrList.RemoveRange 0, 2
MsgBox oArrList.Item(0) ' "Value-3" '
End Sub
3.13. Reverse
oArrList.Reverse
P a g e 97 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
3.14. Sort
oArrList.Sort
3.15. ToArray
oArrList.ToArray
Sao chép các Item trong ArrayList vào một mảng (Array). Mảng trả về là mảng một chiều, chỉ
số cận dưới của mảng luôn băng 0, cho dù thiết lập Option Base 1.
Ví dụ:
Sub ToArrayMethod()
'oArrList.ToArray '
Dim oArrList As Object, Arr()
Set oArrList = CreateObject("System.Collections.ArrayList")
oArrList.Add "Value-1"
oArrList.Add Array(15, 40)
P a g e 98 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
oArrList.Add 200
Arr = oArrList.ToArray
End Sub
3.16. ToString
oArrList.ToString
3.17. TrimToSize
oArrList.TrimToSize
Sử dụng để giảm vùng nhớ của Collection nếu không có Item mới sẽ được thêm vào.
Khi sử dụng phương thức TrimToSize thì Capacity = Count.
Để thiết lập lại ArrayList về trạng thái ban đầu, ta sử dụng phương thức Clear trước khi gọi
TrimToSize. Việc cắt một ArrayList trống sẽ đặt Capacity của ArrayList về giá trị mặc định.
Ví dụ:
Sub TrimToSizeMethod()
'oArrList.TrimToSize '
Dim oArrList As Object
Set oArrList = CreateObject("System.Collections.ArrayList")
oArrList.Add "Value-1"
oArrList.Add "Value-2"
MsgBox "Count = " & oArrList.Count & vbNewLine & _
"Capacity = " & oArrList.Capacity '2-4'
oArrList.TrimToSize
MsgBox "Count = " & oArrList.Count & vbNewLine & _
"Capacity = " & oArrList.Capacity '2-2'
End Sub
4. Ứng dụng
Lọc loại trùng, sort mảng, tạo số ngẫu nhiên không trùng...
P a g e 99 | 100
https://sites.google.com/site/exl2lab/vba-in-excel
Arr = Rng.Value
For i = LBound(Arr, 1) To UBound(Arr, 1)
sKey = Arr(i, 1)
If sKey <> "" Then
If oArrList.Contains(sKey) = False Then
oArrList.Add sKey
j=j+1
ReDim Preserve Result(1 To j)
Result(j) = sKey
End If
End If
Next i
UniqueColumnArrayList = Result
End Function
P a g e 100 | 100