Có thể bạn quan tâm: Hướng Dẫn Chi Tiết Tạo Mã Vạch Code 128 Trong Excel – Từ Cơ Bản Đến Nâng Cao
Lời mở đầu
Trong môi trường làm việc hiện đại, Excel không chỉ là một công cụ tính toán đơn thuần mà còn là một nền tảng mạnh mẽ để tự động hoá quy trình, tối ưu hoá thời gian và giảm thiểu sai sót. VBA (Visual Basic for Applications) – ngôn ngữ lập trình tích hợp sẵn trong Excel – đã mở ra một kỷ nguyên mới cho người dùng, cho phép họ biến những thao tác lặp đi lặp lại thành những macro thông minh chỉ cần một cú click.
Bài viết này sẽ cung cấp cho bạn hơn 1500 chữ chi tiết về các code VBA hay cho Excel – từ những đoạn mã cơ bản, tiện lợi cho người mới bắt đầu, cho tới các mẫu mã phức tạp, chuyên sâu dành cho những nhà phân tích dữ liệu, kế toán, quản lý dự án và các chuyên gia IT. Mỗi đoạn code sẽ kèm theo giải thích rõ ràng, ví dụ thực tiễn và hướng dẫn cách tích hợp vào workbook của bạn. Hy vọng qua đây, bạn sẽ nắm bắt được sức mạnh của VBA và áp dụng chúng vào công việc hằng ngày để đạt được năng suất tối đa.
Có thể bạn quan tâm: Giãn Khoảng Cách Chữ Trong Excel 2026: Hướng Dẫn Chi Tiết Từ Cơ Bản Đến Nâng Cao
1. Tại sao nên học VBA trong Excel?
1.1. Tự động hoá công việc lặp lại
Nhiều doanh nghiệp vẫn còn phải thực hiện các công việc thủ công như nhập liệu, định dạng báo cáo, tính toán hàng nghìn dòng dữ liệu. Với một macro VBA, bạn có thể tự động hoá toàn bộ quy trình trong vài giây.
1.2. Tăng tính linh hoạt và mở rộng
VBA cho phép bạn tạo form, user interface tùy chỉnh, kết nối tới cơ sở dữ liệu, web service, thậm chí là các ứng dụng Office khác (Word, PowerPoint, Outlook). Điều này giúp Excel trở thành một công cụ đa năng, thay thế nhiều phần mềm rời rạc.
1.3. Giảm thiểu lỗi con người
Khi các công thức phức tạp được thay thế bằng macro, nguy cơ nhập sai dữ liệu hoặc công thức sai giảm đáng kể, đồng thời tăng độ tin cậy của báo cáo.
1.4. Tiết kiệm thời gian và chi phí
Thay vì thuê lập trình viên để phát triển phần mềm riêng, doanh nghiệp chỉ cần một người có kiến thức VBA là có thể xây dựng các công cụ nội bộ đáp ứng nhu cầu ngay lập tức.
Có thể bạn quan tâm: Cách Xây Dựng Và Duy Trì Định Dạng Bảng Rõ Ràng Trong Excel: Hướng Dẫn Chi Tiết Cho Người Dùng Mọi Trình Độ
2. Cài đặt môi trường VBA và những lưu ý cơ bản
2.1. Kích hoạt tab “Developer”
- Vào File → Options → Customize Ribbon.
- Đánh dấu vào Developer trong danh sách bên phải và nhấn OK.
2.2. Mở cửa sổ VBA Editor
Nhấn Alt + F11 hoặc click vào Developer → Visual Basic.
2.3. Cấu trúc một macro cơ bản
Sub TenMacro() ' Mô tả ngắn gọn công việc MsgBox "Hello, VBA!"
End Sub
- Sub: khai báo một thủ tục (procedure).
- MsgBox: hàm hiển thị hộp thoại.
2.4. Quy tắc đặt tên và bình luận
- Tên macro không được chứa dấu cách, ký tự đặc biệt (ngoại trừ dấu gạch dưới).
- Sử dụng CamelCase hoặc PascalCase để dễ đọc (VD:
TinhTongBangVong). - Luôn thêm comment (
') để giải thích logic, giúp người khác (hoặc chính bạn trong tương lai) hiểu nhanh.
2.5. Lưu file dưới định dạng hỗ trợ macro
- .xlsm (Macro‑Enabled Workbook)
- .xlsb (Binary Workbook, nhanh hơn khi dữ liệu lớn)
3. Các mẫu code VBA hay – Phần 1: Tự động hoá công việc thường ngày
3.1. Tự động lọc dữ liệu và sao chép sang một sheet mới
Sub LocVaSaoChep() Dim wsNguon As Worksheet, wsDich As Worksheet Dim rng As Range, rngCopy As Range Set wsNguon = ThisWorkbook.Sheets("Dữ liệu") Set wsDich = ThisWorkbook.Sheets("Kết quả") ' Xóa dữ liệu cũ trên sheet Kết quả wsDich.Cells.Clear ' Đặt vùng dữ liệu cần lọc (giả sử có tiêu đề ở hàng 1) Set rng = wsNguon.Range("A1").CurrentRegion ' Áp dụng AutoFilter: lọc cột C có giá trị > 1000 rng.AutoFilter Field:=3, Criteria1:=">1000" ' Đặt vùng cần sao chép (bỏ qua tiêu đề) Set rngCopy = rng.Offset(1, 0).Resize(rng.Rows.Count - 1).SpecialCells(xlCellTypeVisible) ' Sao chép sang sheet Kết quả, bắt đầu từ A1 rngCopy.Copy Destination:=wsDich.Range("A1") ' Bỏ AutoFilter wsNguon.AutoFilterMode = False MsgBox "Hoàn thành lọc và sao chép!", vbInformation
End Sub
Giải thích:
– CurrentRegion tự động mở rộng vùng dữ liệu quanh ô A1.
– AutoFilter lọc nhanh, không cần vòng lặp.
– SpecialCells(xlCellTypeVisible) chỉ lấy những ô hiển thị sau khi lọc.
3.2. Gửi email tự động qua Outlook với file đính kèm
Sub GuiMail() Dim OutlookApp As Object, MailItem As Object Dim FilePath As String, ToAddress As String ' Đường dẫn file đính kèm (có thể là file hiện tại) FilePath = ThisWorkbook.FullName ToAddress = "nhanvien@congty.com" ' Tạo đối tượng Outlook Set OutlookApp = CreateObject("Outlook.Application") Set MailItem = OutlookApp.CreateItem(0) ' 0 = olMailItem With MailItem .To = ToAddress .Subject = "Báo cáo công việc ngày " & Format(Date, "dd/mm/yyyy") .Body = "Kính gửi anh/chị," & vbCrLf & vbCrLf & _ "Xin gửi kèm báo cáo công việc ngày hôm nay. " & vbCrLf & vbCrLf & _ "Trân trọng," .Attachments.Add FilePath .Display ' Hoặc .Send để gửi ngay End With ' Giải phóng bộ nhớ Set MailItem = Nothing Set OutlookApp = Nothing
End Sub
Lưu ý:
– Khi dùng .Send, Outlook có thể yêu cầu người dùng xác nhận bảo mật.
– Đảm bảo Outlook đã được cài đặt và đăng nhập tài khoản.
3 VBA: Đánh dấu hàng trùng lặp bằng màu
Sub ĐánhDấuTrùngLặp() Dim ws As Worksheet Dim rng As Range, cell As Range Dim dict As Object Set ws = ThisWorksheet ' Hoặc ThisWorkbook.Sheets("Sheet1") Set rng = ws.Range("A2:A1000") ' Cột cần kiểm tra Set dict = CreateObject("Scripting.Dictionary") Application.ScreenUpdating = False For Each cell In rng If Not IsEmpty(cell) Then If dict.Exists(cell.Value) Then cell.Interior.Color = RGB(255, 200, 200) ' Màu hồng nhạt Else dict.Add cell.Value, 1 End If End If Next cell Application.ScreenUpdating = True MsgBox "Đánh dấu trùng lặp hoàn tất!", vbInformation
End Sub
Sử dụng: Thích hợp cho danh sách khách hàng, mã sản phẩm, … giúp nhanh chóng nhìn ra dữ liệu bị lặp.
4. Các mẫu code VBA hay – Phần 2: Xử lý dữ liệu nâng cao
4.1. Tạo PivotTable tự động từ dữ liệu nguồn
Sub TaoPivot() Dim wsNguon As Worksheet, wsPivot As Worksheet Dim ptCache As PivotCache, pt As PivotTable Dim rngNguon As Range Set wsNguon = ThisWorkbook.Sheets("Dữ liệu") Set wsPivot = ThisWorkbook.Sheets("Pivot") ' Xác định vùng dữ liệu Set rngNguon = wsNguon.Range("A1").CurrentRegion ' Xóa PivotTable cũ (nếu có) wsPivot.Cells.Clear ' Tạo PivotCache Set ptCache = ThisWorkbook.PivotCaches.Create( _ SourceType:=xlDatabase, _ SourceData:=rngNguon) ' Tạo PivotTable Set pt = ptCache.CreatePivotTable( _ TableDestination:=wsPivot.Range("A3"), _ TableName:="PivotBanHang") ' Định dạng trường With pt .PivotFields("Khu Vực").Orientation = xlRowField .PivotFields("Tháng").Orientation = xlColumnField .PivotFields("Doanh Thu").Orientation = xlDataField .PivotFields("Doanh Thu").Function = xlSum .RowAxisLayout xlTabularRow End With MsgBox "PivotTable đã được tạo thành công!", vbInformation
End Sub
Mô tả:
– PivotCaches.Create tạo bộ nhớ tạm cho dữ liệu, nhanh hơn so với tạo trực tiếp.
– Thay đổi tên trường (Khu Vực, Tháng, Doanh Thu) cho phù hợp với dữ liệu thực tế.

Có thể bạn quan tâm: Code 39 Font Cho Excel: Hướng Dẫn Chi Tiết Từ Cài Đặt Đến Ứng Dụng Thực Tiễn
4.2. Tính tổng nhanh bằng Application.WorksheetFunction.SumIfs
Function TongTheoDieuKien(rngSum As Range, _ rngCrit1 As Range, crit1 As Variant, _ Optional rngCrit2 As Range, Optional crit2 As Variant) As Double Dim args As Variant If IsMissing(rngCrit2) Then TongTheoDieuKien = Application.WorksheetFunction.SumIfs(rngSum, rngCrit1, crit1) Else TongTheoDieuKien = Application.WorksheetFunction.SumIfs(rngSum, _ rngCrit1, crit1, rngCrit2, crit2) End If
End Function
Cách dùng trong sheet:=TongTheoDieuKien(C2:C100, A2:A100, "Hà Nội", B2:B100, "2026")
4.3. Gộp dữ liệu từ nhiều workbook thành một sheet duy nhất
Sub GopDuLieu() Dim FolderPath As String, FileName As String Dim wbSrc As Workbook, wsSrc As Worksheet Dim wsDest As Worksheet Dim LastRowDest As Long FolderPath = "C:\Data\Reports\" ' Thư mục chứa các file .xlsx Set wsDest = ThisWorkbook.Sheets("Tổng hợp") wsDest.Cells.Clear FileName = Dir(FolderPath & ".xlsx") Do While FileName <> "" Set wbSrc = Workbooks.Open(FolderPath & FileName, ReadOnly:=True) Set wsSrc = wbSrc.Sheets(1) ' Giả sử dữ liệu luôn ở sheet đầu tiên LastRowDest = wsDest.Cells(wsDest.Rows.Count, "A").End(xlUp).Row If LastRowDest = 1 And wsDest.Cells(1, 1).Value = "" Then wsSrc.UsedRange.Copy wsDest.Range("A1") Else wsSrc.UsedRange.Offset(1, 0).Copy wsDest.Cells(LastRowDest + 1, 1) End If wbSrc.Close SaveChanges:=False FileName = Dir Loop MsgBox "Hoàn thành gộp dữ liệu!", vbInformation
End Sub
Lưu ý:
– Thêm kiểm tra để loại bỏ hàng tiêu đề trùng lặp khi gộp nhiều file.
– Đảm bảo các file có cấu trúc cột giống nhau.
5. Các mẫu code VBA hay – Phần 3: Giao diện người dùng (UserForm) và kiểm tra dữ liệu
5.1. Tạo UserForm nhập dữ liệu nhanh
- Tạo UserForm: Vào VBA Editor → Insert → UserForm.
- Thêm các TextBox, ComboBox, CommandButton.
- Đặt tên:
txtTen,cboPhongBan,btnLuu.
'--- Code trong UserForm ---
Private Sub UserForm_Initialize() ' Điền danh sách phòng ban vào ComboBox With cboPhongBan .AddItem "Kế toán" .AddItem "Nhân sự" .AddItem "Marketing" .AddItem "Bán hàng" End With
End Sub Private Sub btnLuu_Click() Dim ws As Worksheet Dim nextRow As Long Set ws = ThisWorkbook.Sheets("Nhân viên") nextRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row + 1 ws.Cells(nextRow, 1).Value = txtTen.Value ws.Cells(nextRow, 2).Value = cboPhongBan.Value ws.Cells(nextRow, 3).Value = Date MsgBox "Đã lưu thông tin!", vbInformation Unload Me
End Sub
Gọi UserForm từ một macro:
Sub MoFormNhap() UserForm1.Show
End Sub
5.2. Kiểm tra dữ liệu nhập vào (validation)
Function KiemTraEmail(email As String) As Boolean Dim re As Object Set re = CreateObject("VBScript.RegExp") re.Pattern = "^\w.-+@\w.-+\.A-Za-z{2,}$" re.IgnoreCase = True KiemTraEmail = re.Test(email)
End Function
Áp dụng trong UserForm:
If Not KiemTraEmail(txtEmail.Value) Then MsgBox "Địa chỉ email không hợp lệ!", vbExclamation Exit Sub
End If
6. Tối ưu hoá mã VBA – Những mẹo quan trọng
6.1. Tắt ScreenUpdating và Calculation trong vòng lặp
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual '... thực hiện các thao tác nặng ... Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
6.2. Sử dụng With...End With để giảm gọi đối tượng lặp lại
With ws.Cells(i, 1) .Value = "ABC" .Font.Bold = True .Interior.Color = RGB(220, 230, 241)
End With
6.3. Tránh Select và Activate
Thay vì:
Sheets("Data").Select
Range("A1").Select
Selection.Copy
Nên viết:
Sheets("Data").Range("A1").Copy
6.4. Dùng Scripting.Dictionary hoặc Collection cho tra cứu nhanh
Dictionary cho phép O(1) thời gian tra cứu, nhanh hơn vòng lặp For Each.
6.5. Xử lý lỗi (Error Handling)
On Error GoTo ErrHandler
'... code ...
Exit Sub ErrHandler: MsgBox "Lỗi: " & Err.Description, vbCritical Resume Next ' Hoặc Resume CleanUp
7. Ứng dụng thực tế: Xây dựng hệ thống quản lý dự án trong Excel
7.1. Yêu cầu
- Danh sách công việc (Task ID, Tên công việc, Người chịu trách nhiệm, Ngày bắt đầu, Ngày kết thúc, Trạng thái).
- Tự động tính tiến độ dựa trên ngày hiện tại.
- Báo cáo dạng Gantt và Dashboard hiển thị tổng số công việc, % hoàn thành, công việc trễ hạn.
7.2. Cấu trúc workbook
| Sheet | Mô tả |
|---|---|
Tasks | Dữ liệu gốc (cột A:H). |
Gantt | Biểu đồ Gantt tự động cập nhật. |
Dashboard | Dashboard tổng hợp. |
Code | Lưu macro. |
7.3. Macro tạo ID tự động
Sub TaoTaskID() Dim ws As Worksheet, lastRow As Long, i As Long Set ws = ThisWorkbook.Sheets("Tasks") lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row For i = 2 To lastRow If ws.Cells(i, 1).Value = "" Then ws.Cells(i, 1).Value = "T" & Format(i - 1, "000") End If Next i MsgBox "Đã tạo Task ID cho các công việc mới.", vbInformation
End Sub
7.4. Tính tiến độ và đánh dấu màu
Sub CapNhatTienDo() Dim ws As Worksheet, i As Long, startDate As Date, endDate As Date Dim today As Date, pct As Double Set ws = ThisWorkbook.Sheets("Tasks") today = Date For i = 2 To ws.Cells(ws.Rows.Count, "A").End(xlUp).Row startDate = ws.Cells(i, 4).Value endDate = ws.Cells(i, 5).Value If ws.Cells(i, 7).Value = "Hoàn thành" Then pct = 1 ElseIf today < startDate Then pct = 0 ElseIf today > endDate Then pct = 0.9 ' Trễ nhưng chưa hoàn thành Else pct = (today - startDate) / (endDate - startDate) End If ws.Cells(i, 8).Value = Round(pct, 2) ' Cột % Tiến độ ' Đánh màu dựa trên pct Select Case pct Case Is >= 1 ws.Rows(i).Interior.Color = RGB(198, 239, 206) ' Xanh lá Case Is >= 0.75 ws.Rows(i).Interior.Color = RGB(255, 235, 156) ' Vàng nhạt Case Is < 0.75 ws.Rows(i).Interior.Color = RGB(255, 199, 206) ' Hồng nhạt End Select Next i MsgBox "Cập nhật tiến độ hoàn tất!", vbInformation
End Sub
7.5. Tự động vẽ biểu đồ Gantt
Sub VeGantt() Dim wsData As Worksheet, wsGantt As Worksheet Dim i As Long, lastRow As Long Dim startCol As Long, durCol As Long Set wsData = ThisWorkbook.Sheets("Tasks") Set wsGantt = ThisWorkbook.Sheets("Gantt") wsGantt.Cells.Clear ' Tiêu đề wsGantt.Range("A1").Value = "Task" wsGantt.Range("B1").Value = "Start" wsGantt.Range("C1").Value = "Duration" lastRow = wsData.Cells(wsData.Rows.Count, "A").End(xlUp).Row For i = 2 To lastRow wsGantt.Cells(i, 1).Value = wsData.Cells(i, 2).Value ' Tên công việc wsGantt.Cells(i, 2).Value = wsData.Cells(i, 4).Value ' Ngày bắt đầu wsGantt.Cells(i, 3).Value = wsData.Cells(i, 5).Value - wsData.Cells(i, 4).Value ' Thời gian (ngày) Next i ' Tạo biểu đồ Gantt (Stacked Bar) Dim cht As ChartObject Set cht = wsGantt.ChartObjects.Add(Left:=300, Top:=20, Width:=500, Height:=300) With cht.Chart .ChartType = xlBarStacked .SetSourceData Source:=wsGantt.Range("A1:C" & lastRow) .SeriesCollection(1).Format.Fill.Visible = msoFalse ' Ẩn cột Start .SeriesCollection(2).Format.Fill.ForeColor.RGB = RGB(0, 112, 192) ' Màu thanh Gantt .Axes(xlCategory).ReversePlotOrder = True .HasTitle = True .ChartTitle.Text = "Biểu đồ Gantt - Dự án" End With MsgBox "Biểu đồ Gantt đã được tạo!", vbInformation
End Sub
7.6. Dashboard tổng hợp
Sub TaoDashboard() Dim wsDash As Worksheet, wsTask As Worksheet Dim totalTask As Long, completedTask As Long, overdueTask As Long Set wsDash = ThisWorkbook.Sheets("Dashboard") Set wsTask = ThisWorkbook.Sheets("Tasks") totalTask = wsTask.Cells(wsTask.Rows.Count, "A").End(xlUp).Row - 1 completedTask = Application.WorksheetFunction.CountIf(wsTask.Range("G2:G" & wsTask.Rows.Count), "Hoàn thành") overdueTask = Application.WorksheetFunction.CountIfs(wsTask.Range("G2:G" & wsTask.Rows.Count), "<>Hoàn thành", _ wsTask.Range("E2:E" & wsTask.Rows.Count), "<" & Date) wsDash.Range("B2").Value = totalTask wsDash.Range("B3").Value = completedTask wsDash.Range("B4").Value = overdueTask wsDash.Range("B5").Formula = "=B3/B2" ' % hoàn thành wsDash.Range("A2:A5").Value = Application.Transpose(Array("Tổng số công việc", "Hoàn thành", "Quá hạn", "% Hoàn thành")) MsgBox "Dashboard đã được cập nhật!", vbInformation
End Sub
Kết quả: Khi chạy tuần tự các macro TaoTaskID → CapNhatTienDo → VeGantt → TaoDashboard, bạn sẽ có một hệ thống quản lý dự án hoàn chỉnh trong Excel, không cần phần mềm chuyên dụng.
8. Những lưu ý bảo mật khi chia sẻ file VBA
- Mật khẩu bảo vệ mã VBA
- Trong VBA Editor → Tools → VBAProject Properties → Protection → Tick “Lock project for viewing” và đặt password.
Giúp ngăn người dùng xem, chỉnh sửa code.
Tránh sử dụng
On Error Resume Nextkhông có kiểm soátCó thể ẩn lỗi nghiêm trọng, khiến file hoạt động sai mà không biết nguyên nhân.
Kiểm tra macro virus
Khi nhận file từ nguồn không rõ, luôn mở trong môi trường sandbox hoặc tắt macro trước khi mở.
Sử dụng
Digital Signature- Ký file VBA bằng chứng thực số để người dùng tin tưởng nguồn gốc macro.
9. Tài nguyên học VBA bổ sung
| Nguồn | Mô tả |
|---|---|
| Microsoft Docs – VBA Reference | Tài liệu chính thức, chi tiết mọi đối tượng, phương thức. |
| Chủ đề “Excel Macro Mastery” trên YouTube | Video hướng dẫn thực hành từng bước, từ cơ bản tới nâng cao. |
| Sách “Excel VBA Programming For Dummies” | Giải thích dễ hiểu, kèm ví dụ thực tế. |
| Cộng đồng Stack Overflow & Reddit r/vba | Nơi đặt câu hỏi, nhận giải pháp nhanh. |
| Website “ExcelCampus.com” | Bài viết chuyên sâu về UserForm, API, và tích hợp Power Query. |
10. Kết luận
Việc học và áp dụng VBA trong Excel không chỉ giúp bạn tự động hoá những công việc tẻ nhạt mà còn mở ra khả năng xây dựng các ứng dụng nội bộ mạnh mẽ, từ báo cáo tài chính, quản lý dự án, tới hệ thống CRM đơn giản. Bằng cách nắm vững các code VBA hay cho Excel được liệt kê ở trên – bao gồm các macro tự động lọc, gửi email, tạo PivotTable, gộp dữ liệu, xây dựng UserForm và dashboard – bạn sẽ có một bộ công cụ hoàn chỉnh để giải quyết hầu hết các nhu cầu công việc trong môi trường doanh nghiệp.
Hãy bắt đầu thực hành ngay hôm nay: tạo một file .xlsm, sao chép một trong các đoạn code trên, tùy chỉnh theo dữ liệu thực tế và chạy thử. Khi đã quen, bạn sẽ thấy thời gian hoàn thành công việc giảm đáng kể, đồng thời nâng cao độ chính xác và tính chuyên nghiệp của các báo cáo.
Chúc bạn thành công trên hành trình chinh phục VBA và biến Excel thành “cánh tay đắc lực” của mình!

Tiến sĩ Lê Thống Nhất sinh năm 1955 tại Nghệ An, là nhà giáo, nhà báo và doanh nhân trong lĩnh vực giáo dục. Ông từng giảng dạy Toán học tại Trường THPT Chuyên Phan Bội Châu và đảm nhiệm nhiều vai trò trong ngành giáo dục, từ viết sách, biên soạn tài liệu đến sáng lập các dự án hỗ trợ học tập trực tuyến.
Ông là người sáng lập BigSchool – nền tảng giáo dục trực tuyến kết nối giáo viên và học sinh cả nước. Ngoài ra, ông còn nổi tiếng với vai trò tác giả, diễn giả truyền cảm hứng và khách mời trên nhiều chương trình truyền hình, trong đó có “Ai là triệu phú” trên truyền hình VTV.
Trong suốt sự nghiệp, Tiến sĩ Lê Thống Nhất đã nhận nhiều giải thưởng giáo dục và được biết đến như một người luôn đổi mới, ứng dụng công nghệ vào dạy và học, góp phần lan tỏa tri thức và niềm say mê học tập cho thế hệ trẻ.
