Có thể bạn quan tâm: Excel Từ A Đến Z: Hướng Dẫn Toàn Diện Cho Người Mới Bắt Đầu Và Người Dùng Nâng Cao
1. Giới thiệu chung về VBA và hàm (Function) trong Excel
Microsoft Excel không chỉ là một công cụ bảng tính mạnh mẽ mà còn là một môi trường lập trình tích hợp thông qua Visual Basic for Applications (VBA). VBA cho phép người dùng tự động hoá các tác vụ lặp lại, xây dựng các công cụ tùy chỉnh và mở rộng khả năng tính toán của Excel. Trong số các thành phần cơ bản của VBA, Function (hàm) đóng vai trò quan trọng vì nó giúp tách rời logic xử lý thành các khối mã có thể tái sử dụng, dễ bảo trì và dễ kiểm thử.
Khi nói tới “Excel VBA call a function”, chúng ta đang nói tới việc gọi một hàm đã được định nghĩa trong một module VBA từ một vị trí khác – có thể là từ một Sub (procedure), một hàm khác, một nút bấm trên worksheet, hay thậm chí là từ một công thức Excel (UDF – User Defined Function). Bài viết này sẽ đi sâu vào:
- Cách tạo và định nghĩa một Function trong VBA.
- Các cách gọi Function trong các ngữ cảnh khác nhau.
- Các lưu ý quan trọng (đối số, kiểu trả về, scope, error handling…).
- Ví dụ thực tế từ cơ bản tới nâng cao.
- Những mẹo tối ưu và best practices khi làm việc với Function trong Excel VBA.
Mục tiêu cuối cùng là bạn sẽ nắm vững cách call a function trong Excel VBA, từ đó xây dựng các giải pháp tự động hoá hiệu quả và chuyên nghiệp.
Có thể bạn quan tâm: Excel Tính Tiền Nhà Trọ: Hướng Dẫn Chi Tiết Từ A Đến Z Để Quản Lý Tài Chính Hiệu Quả
2. Cú pháp cơ bản để định nghĩa một Function trong VBA
Trong VBA, một Function được khai báo bằng từ khóa Function, tiếp theo là tên hàm, danh sách các tham số (nếu có) và kiểu dữ liệu trả về. Cú pháp tổng quát:
Function TênHàm(ThamSo1 As Kiểu1, ThamSo2 As Kiểu2, ...) As KiểuKếtQuả ' Các câu lệnh xử lý TênHàm = GiáTrịKếtQuả ' Gán giá trị trả về cho tên hàm
End Function
2.1. Ví dụ đơn giản: tính tổng hai số
Function TongHaiSo(a As Double, b As Double) As Double TongHaiSo = a + b
End Function
Trong ví dụ trên:
TongHaiSolà tên hàm, nhận hai tham sốavàbkiểuDouble.- Dòng
TongHaiSo = a + bgán kết quả cho hàm, đây là cách trả về giá trị trong VBA.
2.2. Kiểu dữ liệu (Data Types)
VBA hỗ trợ nhiều kiểu dữ liệu, bao gồm:
| Kiểu | Mô tả |
|---|---|
Integer | Số nguyên trong khoảng -32,768 đến 32,767 |
Long | Số nguyên lớn hơn Integer |
Double | Số thực (floating‑point) với độ chính xác cao |
String | Chuỗi ký tự |
Boolean | True hoặc False |
Variant | Kiểu dữ liệu mặc định, có thể chứa bất kỳ kiểu nào |
Date | Ngày tháng |
Object | Tham chiếu tới một đối tượng (worksheet, range, …) |
Chọn đúng kiểu dữ liệu sẽ giúp giảm lỗi và tối ưu hiệu suất.
2.3. Tham số tùy chọn (Optional) và giá trị mặc định
Bạn có thể khai báo tham số là tùy chọn bằng từ khóa Optional. Khi không truyền giá trị, tham số sẽ nhận giá trị mặc định (Empty cho Variant, 0 cho số, “” cho String, v.v.) hoặc một giá trị bạn chỉ định:
Function GiaiThua(n As Long, Optional showMsg As Boolean = False) As Long Dim i As Long, result As Long result = 1 For i = 2 To n result = result i Next i If showMsg Then MsgBox "Giai thừa của " & n & " là " & result End If GiaiThua = result
End Function
Có thể bạn quan tâm: Cách Tính Lương Theo Giờ Trong Excel: Hướng Dẫn Chi Tiết Từ A Đến Z
3. Các cách gọi (Call) Function trong VBA
3.1. Gọi trực tiếp trong một Sub
Đây là cách phổ biến nhất. Bạn chỉ cần viết tên hàm và truyền các đối số (nếu có). Nếu hàm trả về giá trị, bạn có thể gán nó cho một biến hoặc sử dụng ngay trong một biểu thức.
Sub DemoGoiFunction() Dim sum As Double sum = TongHaiSo(5.5, 3.2) ' Gọi hàm và gán kết quả MsgBox "Tổng = " & sum
End Sub
Lưu ý: Khi gọi hàm mà không cần giá trị trả về, bạn có thể sử dụng từ khóa Call và đặt đối số trong dấu ngoặc:
Call GiaiThua(5, True) ' Không gán kết quả, chỉ thực thi
Nếu không dùng Call, bạn phải bỏ dấu ngoặc quanh tham số:
GiaiThua 5, True ' Cú pháp này cũng hợp lệ
3.2. Gọi hàm từ một hàm khác
Bạn có thể lồng hàm trong hàm để tái sử dụng logic.
Function TinhDienTichHinhTron(radius As Double) As Double TinhDienTichHinhTron = WorksheetFunction.Pi() radius ^ 2
End Function Function TinhChuViHinhTron(radius As Double) As Double TinhChuViHinhTron = 2 WorksheetFunction.Pi() radius
End Function Sub DemoLopHinhTron() Dim r As Double: r = 4 Dim area As Double, perimeter As Double area = TinhDienTichHinhTron(r) ' Gọi hàm tính diện tích perimeter = TinhChuViHinhTron(r) ' Gọi hàm tính chu vi MsgBox "Bán kính = " & r & vbCrLf & _ "Diện tích = " & area & vbCrLf & _ "Chu vi = " & perimeter
End Sub
3.3. Gọi hàm từ một công thức trên worksheet (UDF)
Nếu bạn muốn hàm của mình có thể được sử dụng như một hàm Excel thông thường, bạn chỉ cần khai báo hàm ở một module chuẩn (Standard Module) và không sử dụng các đối tượng Excel trong hàm (tránh Application.ScreenUpdating = False trong UDF). Ví dụ:
Function TongBaSo_UDF(a As Double, b As Double, c As Double) As Double TongBaSo_UDF = a + b + c
End Function
Sau khi lưu macro, bạn có thể nhập công thức trong ô Excel:
=TongBaSo_UDF(1, 2, 3)
3.4. Gọi hàm từ một Control (Button, ComboBox…)
Khi bạn gán một macro (Sub) cho một nút bấm, trong Sub đó bạn có thể gọi hàm như bình thường.
Sub BtnTinhTong_Click() Dim result As Double result = TongHaiSo(Val(Range("A1").Value), Val(Range("B1").Value)) Range("C1").Value = result
End Sub
3.5. Gọi hàm qua Application.Run

Có thể bạn quan tâm: Lệnh Product Trong Excel Là Gì? – Tất Cả Những Điều Bạn Cần Biết Về Hàm Product, Cách Sử Dụng Và Ứng Dụng Thực Tế
Trong một số trường hợp (ví dụ: gọi hàm từ một workbook khác, hoặc gọi hàm có tên động), bạn có thể dùng:
Dim result As Variant
result = Application.Run("TênWorkbook.xlsm!TênModule.TenHam", arg1, arg2)
Điều này rất hữu ích khi bạn muốn thực thi hàm trong một file khác mà không mở trực tiếp.
4. Quản lý phạm vi (Scope) và khả năng truy cập
4.1. Public vs Private
- Public: Hàm có thể được gọi từ bất kỳ module, workbook, hoặc thậm chí từ một workbook khác (kèm
Application.Run). - Private: Hàm chỉ có thể được gọi trong cùng một module.
Public Function CongHaiSo(a As Double, b As Double) As Double CongHaiSo = a + b
End Function Private Function TruHaiSo(a As Double, b As Double) As Double TruHaiStr = a - b
End Function
Nếu bạn muốn hàm trở thành UDF, nó phải là Public và nằm trong module chuẩn (không phải trong ThisWorkbook hay Sheet).
4.2. Module chuẩn vs Module lớp (Class Module)
- Standard Module: Dùng cho các hàm chung, UDF, và các thủ tục không gắn vào đối tượng.
- Class Module: Khi bạn muốn tạo đối tượng tùy chỉnh, các hàm trong Class Module thường là Method và phải được gọi thông qua một instance của lớp.
' Class Module: clsCalculator
Public Function Cong(a As Double, b As Double) As Double Cong = a + b
End Function ' Trong module chuẩn
Sub DemoClass() Dim calc As New clsCalculator MsgBox calc.Cong(5, 7)
End Sub
5. Xử lý lỗi (Error Handling) trong Function
Khi một hàm gặp lỗi, tốt nhất là không để lỗi lan ra Sub gọi, mà trả về một giá trị lỗi hoặc thông báo. Hai cách phổ biến:
5.1. Sử dụng On Error GoTo
Function Chia(a As Double, b As Double) As Variant On Error GoTo ErrHandler Chia = a / b Exit Function ErrHandler: Chia = CVErr(xlErrDiv0) ' Trả về lỗi #DIV/0! trong Excel
End Function
5.2. Trả về một tuple (Array) chứa trạng thái và dữ liệu
Function LayDuLieu(ByVal key As String) As Variant Dim result(1) As Variant On Error GoTo ErrHandler result(0) = True ' Trạng thái thành công result(1) = Application.VLookup(key, Sheets("Data").Range("A:B"), 2, False) LayDuLieu = result Exit Function ErrHandler: result(0) = False result(1) = "Không tìm thấy" LayDuLieu = result
End Function
Sau đó, khi gọi:
Sub DemoLayDuLieu() Dim res As Variant res = LayDuLieu("ABC") If res(0) Then MsgBox "Giá trị: " & res(1) Else MsgBox "Lỗi: " & res(1) End If
End Sub
6. Các ví dụ thực tế
6.1. Tự động tạo báo cáo tổng hợp
Giả sử bạn có nhiều sheet chứa dữ liệu bán hàng và muốn tính tổng doanh thu cho mỗi tháng. Bạn có thể viết một hàm tổng hợp và gọi nó từ một Sub.
Function TongDoanhThu(sheetName As String, monthNum As Integer) As Double Dim ws As Worksheet Dim rng As Range, cell As Range Dim total As Double Set ws = ThisWorkbook.Worksheets(sheetName) Set rng = ws.Range("A2:A1000") ' Cột ngày For Each cell In rng If Month(cell.Value) = monthNum Then total = total + cell.Offset(0, 2).Value ' Giả sử cột C là doanh thu End If Next cell TongDoanhThu = total
End Function Sub TaoBaoCaoTong() Dim months As Variant, i As Integer, result As Double months = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) For i = LBound(months) To UBound(months) result = TongDoanhThu("BánHàng2025", months(i)) Sheets("BáoCáo").Cells(i + 1, 2).Value = result Next i MsgBox "Báo cáo đã được cập nhật."
End Sub
6.2. Hàm UDF tính ngày làm việc tiếp theo (skip weekends & holidays)
Public Function NgayLamViecTieptheo(startDate As Date, daysToAdd As Long) As Date Dim i As Long, curDate As Date Dim holidays As Range Set holidays = ThisWorkbook.Worksheets("Config").Range("Holidays") ' Danh sách ngày lễ curDate = startDate For i = 1 To daysToAdd curDate = curDate + 1 Do While Weekday(curDate, vbMonday) > 5 Or Not IsError(Application.Match(curDate, holidays, 0)) curDate = curDate + 1 Loop Next i NgayLamViecTieptheo = curDate
End Function
Sau khi lưu, bạn có thể dùng trên sheet:
=NgayLamViecTieptheo(A2, 10)
6.3. Gọi hàm từ một workbook khác
Giả sử workbook Utility.xlsm chứa hàm TinhThuong.
' Utility.xlsm - Module1
Public Function TinhThuong(a As Double, b As Double) As Double TinhThuong = a / b
End Function
Trong workbook hiện tại:
Sub DemoGoiTuWorkbookKhac() Dim result As Double result = Application.Run("'Utility.xlsm'!TinhThuong", 50, 5) MsgBox "Kết quả: " & result
End Sub
Điều này hoạt động ngay cả khi Utility.xlsm không mở (Excel sẽ mở ngầm).
7. Best Practices khi viết và gọi Function trong VBA
| Thực hành | Lý do |
|---|---|
| Đặt tên hàm rõ ràng, ngắn gọn, có ý nghĩa | Dễ đọc, bảo trì và tránh xung đột với hàm Excel có sẵn. |
| Sử dụng kiểu dữ liệu cụ thể (không dùng Variant nếu không cần) | Nâng cao hiệu suất và giảm lỗi kiểu dữ liệu. |
Luôn khai báo Option Explicit ở đầu module | Buộc khai báo biến, tránh lỗi đánh máy. |
| Giới hạn phạm vi (Public/Private) hợp lý | Ngăn rò rỉ logic không cần thiết và giảm xung đột. |
| Tránh thay đổi trạng thái Excel trong UDF (ScreenUpdating, Calculation, …) | Vì UDF được tính lại tự động, thay đổi này có thể gây lỗi hoặc chậm. |
| Xử lý lỗi trong hàm, trả về giá trị lỗi (CVErr) nếu dùng trong sheet | Người dùng sẽ thấy thông báo lỗi Excel quen thuộc (#VALUE!, #DIV/0!). |
| Document hàm bằng comment | Giúp người khác (và bạn trong tương lai) hiểu nhanh cách dùng. |
Nếu hàm trả về mảng, sử dụng Variant và khai báo Array | Đảm bảo Excel có thể đưa ra kết quả mảng trong ô. |
| Kiểm tra độ dài đối số trước khi thực hiện tính toán | Ngăn ngừa lỗi runtime khi dữ liệu không hợp lệ. |
Sử dụng ByVal cho các đối số không cần thay đổi | Tránh sửa đổi dữ liệu không mong muốn và tăng tốc. |
| Đối với hàm cần truy cập workbook/worksheet, truyền đối tượng làm đối số | Giảm phụ thuộc vào ActiveSheet/ActiveWorkbook. |
8. Tổng kết
Việc call a function trong Excel VBA không chỉ là một thao tác kỹ thuật đơn giản mà còn là nền tảng để xây dựng các giải pháp tự động hoá mạnh mẽ. Từ việc định nghĩa một hàm cơ bản, quản lý phạm vi, xử lý lỗi, cho tới việc tạo UDF có thể sử dụng trực tiếp trên worksheet, mỗi bước đều có những chi tiết quan trọng cần lưu ý.
Trong thực tế, bạn sẽ thường gặp các tình huống:
- Tái sử dụng logic: Thay vì sao chép mã, bạn đóng gói vào hàm và gọi lại ở nhiều nơi.
- Tối ưu hiệu suất: Hàm được viết hiệu quả sẽ giảm thời gian tính toán, đặc biệt khi làm việc với dữ liệu lớn.
- Tương tác giữa các workbook:
Application.Runmở ra khả năng xây dựng hệ thống macro phân tán. - Tích hợp với UI: Gọi hàm từ button, combo box, hoặc form giúp người dùng cuối thao tác dễ dàng.
Hy vọng qua bài viết chi tiết trên, bạn đã nắm vững cách tạo, gọi và quản lý các Function trong Excel VBA. Hãy áp dụng những kiến thức này vào dự án thực tế, liên tục tối ưu và mở rộng để đạt được hiệu suất và tính ổn định tối đa. Chúc bạn thành công trong hành trình lập trình VBA!

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ẻ.
