Chào mọi người,
Dạo này mình đang làm việc với một dự án cần lấy dữ liệu từ cơ sở dữ liệu MySQL để tổng hợp báo cáo trên Excel. Ban đầu mình định dùng Power Query nhưng lại gặp một số hạn chế nhất định, nên mình đã tìm hiểu và áp dụng cách kết nối trực tiếp bằng VBA. Hôm nay mình muốn chia sẻ lại kinh nghiệm này cho anh em nào đang cần.
Vấn đề gặp phải:
- Dữ liệu lớn, cập nhật thường xuyên.
- Power Query đôi khi xử lý chậm hoặc không linh hoạt với các truy vấn phức tạp.
- Cần tự động hóa hoàn toàn quy trình lấy dữ liệu mà không cần can thiệp thủ công.
Giải pháp: Sử dụng VBA để kết nối tới MySQL và trích xuất dữ liệu.
Các bước thực hiện cơ bản:
- Cài đặt MySQL Connector/ODBC: Đảm bảo bạn đã cài đặt driver phù hợp cho hệ điều hành của mình.
- Khai báo biến và kết nối: Sử dụng ADODB.Connection để thiết lập kết nối. Chuỗi kết nối sẽ cần thông tin về server, database, user, password.
- Thực thi câu lệnh SQL: Tạo một đối tượng ADODB.Recordset để chạy câu lệnh SELECT của bạn.
- Đổ dữ liệu vào Excel: Sử dụng phương thức CopyFromRecordset để đưa dữ liệu từ Recordset vào một vùng trên sheet Excel.
- Xử lý lỗi và đóng kết nối: Đừng quên thêm các đoạn mã xử lý lỗi và đóng kết nối để tránh rò rỉ tài nguyên.
Một đoạn mã ví dụ cho việc kết nối:
Sub ConnectMySQL()
Dim cn As Object
Dim rs As Object
Dim sConnString As String
Dim sSQL As String
' Chuỗi kết nối (thay đổi cho phù hợp)
sConnString = "Driver={MySQL ODBC 8.0 Unicode Driver};Server=localhost;Database=your_database;Uid=your_user;Pwd=your_password;"
' Câu lệnh SQL (thay đổi cho phù hợp)
sSQL = "SELECT * FROM your_table WHERE some_condition;"
On Error GoTo ErrorHandler
Set cn = CreateObject("ADODB.Connection")
cn.Open sConnString
Set rs = CreateObject("ADODB.Recordset")
rs.Open sSQL, cn, 3, 3 ' adOpenStatic, adLockOptimistic
' Đổ dữ liệu vào Sheet1, bắt đầu từ ô A1
Sheet1.Range("A1").CopyFromRecordset rs
MsgBox "Lấy dữ liệu thành công!"
ExitHandler:
On Error Resume Next
If Not rs Is Nothing Then
If rs.State = 1 Then rs.Close
Set rs = Nothing
End If
If Not cn Is Nothing Then
If cn.State = 1 Then cn.Close
Set cn = Nothing
End If
Exit Sub
ErrorHandler:
MsgBox "Lỗi: " & Err.Description
Resume ExitHandler
End Sub
Cách này khá mạnh mẽ và cho phép tùy biến sâu. Anh em nào đã từng làm hoặc có kinh nghiệm xử lý với các DB khác như PostgreSQL, SQL Server bằng VBA thì chia sẻ thêm nhé!