Bài hướng dẫn đặc biệt này giúp các bạn lập trình VBA với Userform để lưu dữ liệu lên Google Sheets, Excel Online (cloud), bạn cũng có thể lấy dữ liệu từ cloud về userform hoặc sheet mà không cần phải học ngôn ngữ lập trình nào khác ngoài VBA. Đây là giải pháp cho phép lưu dữ liệu rất nhanh. Cách thức lập trình gần giống với Excel VBA vì tên các thuộc tính của đối tượng giống hệt Excel.
Video hướng dẫn
(Code trong video đã được sửa đổi bằng code trong bài viết này.)
Mã nguồn VBA
Dữ liệu trên Google Sheets
Sheet "sales" lưu các giao dịch bán hàng
(Hình 01 - Google Sheets -Sheet "sales")
Sheet "items" lưu danh mục hàng
(Hình 02 - Google Sheets -Sheet "items")
Bên Excel chúng ta thiết kế và lập trình VBA
+ Tạo một file Excel trắng. Nhấn ALT+F11 vào môi trường lập trình VBA
+ Chọn tên dự án mà ta lập trình (ở cửa sổ "VBAProject". Vào menu Tools-> References... tick chọn thư viện "AddinATools.dll" (
Tham khảo thêm tại đây)
+ Trong cửa sổ "Microsoft Visual Basic for Application", vào menu Insert -> Userform (để tạo Userform).
+ Chỉnh kích thước Userform phù hợp và vẽ các điều khiển và đặt tên như hình dưới đây:
Ứng với một một cột nhập trên sheet nguồn ở Google ta tạo một control để nhập liệu:
ComboBox, name là "cbItems"
TextBox, name là "txtIncome"
TextBox, name là "txtTax"
TextBox, name là "txtTotal"
CommandButton, name là "cmdSave": điều khiển này để lưu dữ liệu lên Google Sheets.
(Hình 03 - VBA-Userform design mode)
Dán khối mã nguồn dưới đây vào Userform
Option Explicit
'//Author: Nguyen Duy Tuan - https://bluesofts.net OR https://atoolspro.com
'//The first: goto menu Tools -> References... check item "addinatools.dll"
Const MyCloudType = ctGoogleDrive 'If Excel Online: ctOneDrive
Const FileID = "https://docs.google.com/spreadsheets/d/1fPaexjiuLSEY3YQdVf7....HiKWSL9SaaGGvGkbU/edit?"
Dim MyCloud As New BSCloud '//Cloud controller
Dim TaxPer As Double
'-----------------------------------------------
'//OpenWorkbook on drive
Function OpenCloudWorkbook() As BSCloudWorkbook
If MyCloud Is Nothing Then Set MyCloud = New BSCloud
If Not MyCloud.Connected(MyCloudType) Then
If Not MyCloud.OpenAuthor(Application, MyCloudType, Application.Hwnd) Then
MsgBoxW "Con not connect to your drive.", vbCritical, "Connect Error"
Exit Function
End If
End If
'//Connected Ok! Open Workbook
Set OpenCloudWorkbook = MyCloud.Workbooks.Open(FileID)
End Function
'-----------------------------------------------
Private Sub UserForm_Initialize()
Dim wbSrc As BSCloudWorkbook
Dim wsSrc As BSCloudWorksheet
Set wbSrc = OpenCloudWorkbook
Set wsSrc = wbSrc.Sheets("items")
'//Load data from Google Sheets to combobox
cbItems.ColumnCount = 3
cbItems.List = wsSrc.Range("A2:C" & wsSrc.LastRow).Value
End Sub
'-----------------------------------------------
Private Sub cbItems_Change()
lblItemName.Caption = cbItems.List(cbItems.ListIndex, 1)
TaxPer = cbItems.List(cbItems.ListIndex, 2)
End Sub
'-----------------------------------------------
Private Sub UpdateValues()
txtTax.Value = TaxPer * Val(txtIncome.Value)
txtTotal.Value = Val(txtIncome.Value) + Val(txtTax.Value)
End Sub
'-----------------------------------------------
Private Sub txtTax_Change()
UpdateValues
End Sub
'-----------------------------------------------
Private Sub txtIncome_Change()
UpdateValues
End Sub
'-----------------------------------------------
'//Write data to Google Sheets OR Excel Online
Private Sub cmdSave_Click()
Dim wbSrc As BSCloudWorkbook '//Excel.Workbook
Dim wsSrc As BSCloudWorksheet '//Excel.Worksheet
Dim rngSrc As BSCloudRange '//Excel.Range
Dim dataArr(3) '//Data to upload to Google Sheets
Set wbSrc = OpenCloudWorkbook
Set wsSrc = wbSrc.Sheets("sales")
Set rngSrc = wsSrc.Range("A1:D1") '//Start Row
'//Save data in controls to data array
dataArr(0) = cbItems.Text
dataArr(1) = Val(txtIncome.Text)
dataArr(2) = Val(txtTax.Text)
dataArr(3) = Val(txtTotal.Text)
Dim res As BSUpdateResponse
'//Append data array to Google Sheets, sheet name "sales"
If Not rngSrc.Append(dataArr, , , , res) Then '//get res's information
'//If Not wsSrc.Append(dataArr, res) Then '//Not get res's information
MsgBoxW "Upload Error.", vbCritical, "Upload Error"
Exit Sub
End If
'//Data upload successful
MsgBoxW "Data upload successful." & vbNewLine & "The last row is: " & GetLastRow(res.Updates.UpdatedRange), vbInformation, "Upload Ok"
End Sub
'-----------------------------------------------
Private Sub UserForm_Terminate()
'//Close all connections - Free memory.
If Not MyCloud Is Nothing Then
MyCloud.Workbooks.CloseAll
Set MyCloud = Nothing
End If
End Sub
Bây giờ bạn chạy Userform, thực hiện nhập liệu và lưu dữ liệu sẽ được đẩy lên Google Sheets.
(Hình 04 - VBA-Userform run-time mode)
Lưu ý:
+ Với nếu ghi dữ liệu vào dòng cuối bằng Append() thuộc class BSCloudWorksheet nó luôn coi dữ liệu nguồn tính từ A1 nhưng sau khi Append xong nó không nhận thông tin vùng cập nhật vào biến res kiểu BSUpdateResponse.
+ Dùng Append thuộc BSCloudRange linh hoạt hơn khi có thể ghi nối tiếp vào dòng cuối của bất kỳ vùng nào, đồng thời nhận thông tin vùng cập nhật. Append của BSCloudWorksheet luôn tính từ A1 và không nhận thông tin vùng cập nhật dữ liệu vào biến res.
Cấu trúc kiểu
BSUpdateResponse như sau:
Type BSUpdateResponse
FileID As String '//trả về ID của file trên Google Sheets nhận cập nhật
TableRange As String '//Trả về vùng bao dữ liệu quét được. Ví dụ A1:D13
Updates As BSUpdateValuesResponse '//Cấu trúc thông tin vùng cập nhật
End Type
Type BSUpdateValuesResponse
FileID As String '//Giải thíc ở trên
UpdatedCells As Long '//Tổng số ô nhận giá trị
UpdatedColumns As Long '//Tổng số cột nhận giá trị
UpdatedData As Variant '//Dữ liệu hoặc Mảng dữ liệu dã đẩy lên
UpdatedRange As String '//Ðịa chỉ vùng mới thêm. Ví dụ A14:D14
UpdatedRows As Long '//Tổng số dòng được cập nhật.
End Type