CÔNG TY CỔ PHẦN BLUESOFTS

Lập trình VBA tạo Userform lưu dữ liệu lên Google Sheets hoặc Excel Online

 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