• Ms Access VBA và Google drive, một vài ý tưởng trong chia sẻ và đồng bộ số liệu...
  • Ms Access VBA và Google drive, một vài ý tưởng trong chia sẻ và đồng bộ số liệu...

    paulsteigel > 10-08-15, 03:28 PM

    Bản demo đã có nhiều sửa đổi để các cụ Test thử nhé...
    Bản demo tôi cung cấp ở đây là trích từ ứng dụng đang làm dở nên có nhiều chỗ tôi comment bằng tiếng Anh, các cụ thông cảm nhé
    Bản demo của tôi hiện đã có thêm chức năng tải file lên GoogleDrive.

    Tôi đang dùng 1 account thử nghiệm để test, các bác có thể dùng xem sao...
    ============================================
    Phương pháp sử dụng GoogleDrive với VBA
    Đặt vấn đề:
    Tôi cần ứng dụng của tôi tương tác với dịch vụ lưu trữ trên mạng: ở đây sử dụng Google Drive (do họ cung cấp miễn phí đến 15GB với sự ổn định khá cao)
    Ứng dụng của tôi viết trên nền VBA và tôi cần các file của tôi có thể tải lên và tải xuống khi cần.

    Phân tích:
    Hiện tại Google Drive cung cấp phương thức truy nhập ổ đĩa GoogleDrive cho người dùng tuy nhiên đối với người dùng VB/VBA cổ điển thì việc thao tác với googleDrive còn nhiều phiên toái, cụ thể như sau:
    + Làm thế nào để Truy nhập vào tài khoản người dùng một cách tiện lợi?
    + Làm thế nào để sử dụng các câu lệnh GoogleAPI khi tải tập tin lên, đặc biệt là việc vượt qua cơ chế xác thực người dùng ...vv

    Sau thời gian nghiên cứu các phương án thực hiện với sự tham khảo một số tài liệu trên mạng, tôi sử dụng phương án sau đây:
    Công việc 1: Tạo dự án để sử dụng các dịch vụ của Google
    Công việc 2: Tạo ứng dụng và các mã xác thực để sau đó có thể sử dụng dịch vụ GoogleDrive

    1. Làm rõ cơ chế xác thực người dùng và thiết lập các thông tin ban đầu
    Bước 1: Khi truy nhập tài khoản Google, người ta phải cung cấp tên người dùng, mật khẩu
    Bước 2: Google sẽ cung cấp mã xác thực (AuthCode), người dùng sau đó phải nhấn Accept/Chấp nhận trên hộp thoại UserConsent
    Bước 3: Google sẽ cung cấp Khóa truy cập (Token) và người dùng sẽ sử dụng khóa này để thao tác với các dịch vụ của Google.
    Bước 4: Vào https://console.developers.google.com/project để tạo ra một dự án sử dụng các dịch vụ của google như Google Drive chẳng hạn
    + Nhấn nút Create Project
    + Chọn tên dự án, ví dụ ở đây tôi tạo PublicStorage
    Sau khi đợi một lúc, ta chọn dự án PublicStorage từ hộp chọn
    Bước 5: Tạo các mã xác thực
    + Nhấn APIs & auth
    + Nhấn Credentials
    + Nhấn Create new Client ID
    + Chọn Installed Application
    + Nhấn Configure consent screen
    + Mục product name ta chọn một tên thân thiện cho ứng dụng của mình, chẳng hạn ở đây tôi chọn publicdata
    + Nhấn Save
    + Chọn Installed Application, trong mục Installed application type chọn Other
    + Nhấn Create Client ID
    Sau khi xong, nhấn APIs, chọn GoogleDrive rồi nhấn Enable API.

    Chúng ta sẽ nhận được màn hình kết quả với các thông số trong mục Client ID for native application như sau:
    Client ID: [Thay bằng mã của bạn]
    Client secret: [b][Thay bằng mã của bạn][/b]
    Redirect URIs: urn:ietf:wg:oauth:2.0:oob http://localhost

    Hãy lưu ý Client IDClient secret, đây là những cái chúng ta cần sau này.

    Đến đây bước khởi tao ban đầu của chúng ta đã hoàn tất.
    Bây giờ hãy chuyển sang phần coding/ viết mã.

    2. Viết mã, phân tích cơ chế.
    Đáng tiếc là Google chưa xây dựng các cơ chế sử dụng dịch vụ cho ứng dụng viết bằng VBA/VB cổ điển nên chúng ta đành phải mượn công cụ của bên ngoài để thực hiện các chuỗi lệnh thao tác với GoogleDrive. Ở đây tôi đã chọn công cụ rclone viết bằng ngôn ngữ GO (công cụ lập trình của Google) và thao tác bằng dòng lệnh.

    a. Truy nhập vào Google qua cơ chế xác thực OAuth
    Thật may mắn là Google sử dụng cơ chế xác thực người dùng OAuth theo đó, một khi người dùng:
    + Truy nhập vào tài khoản với tên tài khoản và mật khẩu;
    + Cung cấp mã Client_ID, Client_Secret
    + Chấp nhận cho phép sử dụng ứng dụng.
    Google sẽ cho phép bất kỳ ứng dụng nào với các thông tin đã cung cấp khai thác tài nguyên gắn với tài khoản người dùng thông qua một mã gọi là Token. Mỗi máy tính sẽ có một mã Token riêng.

    Vậy trước tiên, chúng ta sẽ thiết kế một mô đun cho phép xác thực với OAuth. Thật may mắn, Tim Halls đã viết giúp chúng ta một Class để thực hiện việc xác thực này, tôi dùng bộ thư viện này với một số sửa đổi trong đó có mấy thủ tục chính bao gồm AuthCode để lấy Code xác thực trên trình duyệt, BrowserComplete để đánh giá khi nào trình duyệt hoàn thành việc lấy thông tin, WaitUntilLoaded để kiểm tra trạng thái của trình duyệt, InitClientCredentials để khai báo các thông tin truy cập, InitEndPoints để thiết lập các địa chỉ truy cập dịch vụ xác thực của google.

    Với class này, tôi chỉ cần viết thêm một đoạn thủ tục sau đây để lấy mã

    Mã:
    Private Function GetAuthCode() As String
        Dim myClass As New gAuth2, client_id As String, client_secret As String
        client_id = "mã client_id của bạn"
        client_secret = "clien_secret của bạn"
        With myClass
            .LogOnGoogle "email của bạn", "mật khẩu của bạn"
            .InitClientCredentials client_id, client_secret
            .InitEndPoints
            GetAuthCode = .AuthCode
        End With
    End Function


    Bước 1 đã xong. Tiếp theo chúng ta sẽ phải thiết lập được phương thức cấu hình cho rclone. Ứng dụng này không thể tự động chạy mà bạn phải tự cấu hình bằng dòng lệnh thông qua thủ tục chạy rclone config và sau đó là khai báo các thông tin khác nhau cho ứng dụng. Đáng tiếc nó lại chạy giống như trong môi trường DOS (command prompt) vì thế sẽ khá khó khăn để người dùng thông thường phải làm việc này bằng tay với các dòng lệnh khô khan.
    Vì ứng dụng của tôi sử dụng 1 tài khoản cho mọi người dùng vì thế tôi bắt buộc phải thiết kế để ứng dụng làm được điều này với sự can thiệp ít nhất của người dùng (Chỉ là nhấn nút đồng ý cho phép thao tác với Google Drive qua màn hình User Consent đã nói ở trên).
    Như thế ta cần một cơ chế có thể truyền tham số cho rclone theo một nhóm trình tự nào đó. Đến đây ta có 2 cách tiếp cận: sử dụng SendKeys và sử dụng Shell để truyền thông tin.
    Cách dùng SendKeys không tốt do nó đòi hỏi màn hình Console (ở đây là DOS) luôn phải kích hoạt. Vì thế tôi lựa chọn cách dùng Shell và giấu màn hình CMD đi rồi truyền tham số. Thủ tục thực hiện đơn giản như sau:

     ' 2 phase 2 - send to console

    Mã:
    Set objShell = CreateObject("WScript.Shell") ' Tạo một phiên làm việc Shell
    Set oExec = objShell.Exec("CMD /K") ' mở giao diện DOS
    Call HideWindow(oExec.ProcessID) ' Giấu giao diện DOS

    Sau đó đến tiết mục truyền tham số cho giao diện DOS thông qua nhóm lệnh sau đây:

    Mã:
    With oExec
    DoEvents
    For i = LBound(cmdList) To UBound(cmdList)
       .StdIn.WriteLine CStr(cmdList(i)) ' truyền từng tham số vào và đợi
    Next
    Do Until .StdOut.AtEndOfStream
       strResults = strResults & vbCrLf & .StdOut.ReadLine ' lấy phản hồi từ giao diện
       DoEvents
    Loop
    End With

    Toàn bộ thủ tục này như sau:


    Mã:
    Private Sub WriteConsole(Optional CreateNew As Boolean = False)
        ' This will try to set up google new token
        Dim objShell As Object
        Dim oExec As Object
        Dim strResults As String
        
        ' 1. Pha 1, truy nhập và lấy mã xác thực
        Dim i As Long, client_id As String, client_secret As String, ReturnValue As Long
        Dim cmdList As Variant, theCode As String
        
        client_id = "456200380740-dr4nihc6u5fslh7larcoiqi6o189liqo.apps.googleusercontent.com"
        client_secret = "duo0jfm-IhRWffLCCtpCJY48"
        
        theCode = GetAuthCode
        If CreateNew Then
            cmdList = Array(rcPath & "rclone.exe config", "n", "gdrive", "6", client_id, client_secret, theCode, "y", "q", "exit")
        Else
            cmdList = Array(rcPath & "rclone.exe config", "e", "1", "", "", "", "", "y", theCode, "y", "q", "exit")
        End If
        DoEvents
        ' 2 phase 2 - send to console
        Set objShell = CreateObject("WScript.Shell")
        Set oExec = objShell.Exec("CMD /K")
        Call HideWindow(oExec.ProcessID)

        With oExec
            ' find a way to get stick to the windows and parse data..
            DoEvents
            For i = LBound(cmdList) To UBound(cmdList)
                .StdIn.WriteLine CStr(cmdList(i)) 
                Sleep 1000 ' wait for the message to be completed
            Next
    ' tiếp nhận kết quả
            Do Until .StdOut.AtEndOfStream
                strResults = strResults & vbCrLf & .StdOut.ReadLine
                DoEvents
            Loop
        End With
        Set oExec = Nothing
        ' in kết quả
        Me.rtbOutput = strResults
    End Sub


    Thủ tục này thực hiện 2 chế đô: tạo mới cấu hình hoặc lấy token mới từ các mã hiện tại.
    Trong ví dụ này, ta dùng call WriteConsole(true)
    Hãy chú ý mảng
    cmdList = Array(rcPath & "rclone.exe config", "n", "gdrive", "6", client_id, client_secret, theCode, "y", "q", "exit")
    nó quy định thứ tự các lệnh sẽ thực hiện bao gồm từ việc tải ra chế độ cấu hình rclone cho đến khi nhập các thống số cấu hình và kết thúc.

    Cú pháp
    Mã:
    .StdIn.WriteLine CStr(cmdList(i)) 
    chịu trách nhiệm gửi lệnh
    và phần sau đó sẽ ghi lại lệnh và gửi ra báo cáo.
    Với việc chạy nhóm thủ tục này, chúng ta sẽ hoàn thành phần cấu hình cho rclone. Thủ tục này chỉ chạy một lần duy nhân khi chạy ứng dụng ban đầu.

    Sau khi đã cài đặt xong, chúng ta chỉ cần sử dụng các dòng lệnh của rclone để thực hiện công việc tạo thư mục, sao chép, tải file lên ...vv
    Nếu các bạn muốn thử, hãy dùng chính account email của mình và theo hướng dẫn sẽ có được kết quả như ý muốn.

    Ứng dụng demo ở sau đây nhé, có nhiều thứ cop nhặt, có gì các bạn cứ hỏi
    http://www.sfdp.net/thuthuataccess/demo/...ects=0&d=1

    Trong file ví dụ của tôi có một số đặc điểm sau:
    + tbRef để lưu trứ 2 tập tin là zlib.dll và rclone.zip (bản nén của rclone).
    + Một số thủ tục giải nén/ dãn nén bằng zlib
    + Một số thủ tục lưu tập tin thư viện vào bảng tbref và bung nó từ bảng này...

    Ứng dụng chạy như sau:
    1. Chạy form frmUpload
    Khi chạy nó sẽ kiểm tra xem đã có 2 tập tin zlib.dll và rclone.exe trong thư mục chạy hay chưa?
    Nếu không có thì sẽ lấy từ trong bảng tbRef ra.

    2. Khi bạn nhấn Lấy Token
    + Bạn cần có các thông tin ở texbox liên quan, hiện tại tôi dùng với 1 account thử nghiệm.
    + Chạy rclone để thiết lập cấu hình lần đầu
    (lần sau nó cũng vẫn chạy như thế vì tôi không đưa ra cơ chế kiểm tra xem có cấu hình của rclone chưa).
    Bây giờ việc chấp thuận cũng như nhập các thông tin khác đã được tự động hóa. Gần đây có báo đưa về việc rò rỉ an ninh liên quan đến cơ chế này, hy vọng Google sẽ sơm có cách điều chỉnh mà không làm ảnh hưởng tới công cụ này!

    Và bạn có thể sửa code để tải vài file ....


    Và nhiều thứ linh tinh mục khác.
    Có ai hỏi gì xin cứ đặt câu hỏi nhé

    Chúc các bạn tuần mới đầy niềm vui!
  • RE: VBA và Google drive

    maidinhdan > 10-08-15, 03:53 PM

    Bài viết rất là hay, đọc thấy mê...vọc ngay thôi. 015
  • Tiếp tục VBA và Google Drive nào

    paulsteigel > 25-08-15, 01:38 PM


    Googdrive...tiếp nào
    Sau thời gian nghiên cứu và mày mò, có vẻ công cụ tải file, upload file lên googdrive bằng VBA là hoàn toàn khả thi.
    Hôm nay tôi xin phép giới thiệu với các bạn phần đầu của nỗ lực này nhé.
    Trước hết, để tiện lợi cho việc viết bài, tôi sẽ lấy một ứng dụng mở của tôi sử dụng làm thí nghiệm.

    A. Để làm việc được với Googdrive từ VBA hoặc bất cứ ứng dụng nào không phải là giao diện Web, bạn cần thỏa mãn được mấy điều kiện sau:
    + Có một Ứng dụng được tạo ra để truy cập vào các dịch vụ của Google
    + Ứng dụng này được tạo ra với các thông số tối thiểu sau
    * AppID (Mã ứng dụng). Trong ví dụ của tôi là [openstore-1034]
    * ClientID (Mã ứng dụng khách). Trong ví dụ của tôi là ["759747656687-rjkm22bit7ob5tufc5sbgg1gsuj48fme.apps.googleusercontent.com"]
    * ClientSecret (mã bí mật của ứng dụng khách). Trong ví dụ của tôi là ["Jf5DqXlZ2G3cOtUtHIraaxvQ"]
    + Khi ứng dụng này truy cập vào bất cứ dịch vụ nào, người dùng cần phải truy cập vào tài khoản gmail sau đó phải chấp thuận cho ứng dụng sử dụng.
    ...
    ==============================================================
    Do bài viết của tôi không thể đăng được, các bạn có thể đọc ở tài liệu sau đây nhé
    Bài đọc chi tiết
    ==============================================================

    Liên kết tải file ví dụ ở đây
    http://www.sfdp.net/thuthuataccess/demo/...ects=0&d=1
    Chúng ta có thể thấy kết quả như trong sheet1 với việc dùng Json2table nhé.
    Tiếp cận với tải file lên, tải xuống, xóa ... vv sẽ làm tương tự.

    Đến đây xin tạm dừng bài viết đã nhé.
    Chúc các bạn vui vẻ.
  • RE: VBA và Google drive

    maidinhdan > 25-08-15, 05:19 PM

    Tối nay về nghiên cứu phần này, thấy giới thiệu là ngon rồi, Với code này, có thể phục vụ rất rất rất rất nhiều việc.

    Cảm ơn anh Ngọc!
  • RE: VBA và Google drive

    paulsteigel > 27-08-15, 01:09 AM

    Sau khi dành tương đối nhiều thời gian cho chủ đề GoogleDrive, tôi đã hoàn thành bước 1:
    + Liệt kê danh sách file và đối tượng thư mục trong googleDrive
    + Cho phép tải file nhỏ lên GoogleDrive.
    Ứng dụng gửi kèm theo chỉ mang tính demo nhưng cơ bản thực hiện được nhiệm vụ.
    Tất nhiên còn có một số điểm khác cần cân nhắc bao gồm:
    + Bẫy lỗi
    + Hoàn thiện cơ chế tải file dùng chế độ tải phân đoạn đối với các file lớn.
    + Hoàn thiện cơ chế tương tác với file/ folder.
    ...

    Hy vọng chúng ta sẽ cùng nhau đi tiếp.
    Với chế độ tải file đơn giản chỉ áp dụng đối với file nhỏ, Google cũng có một số điểm hạn chế. Tất cả các ứng dụng khác họ không dùng dạng SimpleUpload mà dùng dạng tải phân đoạn Resumable Upload.
    Tuy nhiên với chế độ phân đoạn thì cần có thêm thời gian nên tôi xin tạm trình bày về chế độ tải đơn giản đã nhé.

    Để tải file lên được chúng ta cần có những thủ tục sau:
    + Đọc file dưới dạng nhị phân và chuyển thành chuỗi (nhiều thủ tục đọc file nhị phân đều gặp lỗi với tên file có ký tự Unicode).
    + Chuyển tên chuỗi sang dạng Utf-8.
    + Lấy được mã Token
    + Đăng tải thông tin.

    Các bạn có thể xem qua thủ tục Upload có trong Module Upload nhé.
    Các thủ tục khác đang được tiếp tục hoàn thiện.
    Chúc các bạn ngủ ngon
    File đính kèm như trong bài trước - ở đây 
  • RE: VBA và Google drive

    maidinhdan > 27-08-15, 08:53 AM

    Sao không cọn Access viết vậy anh? thấy Excel là bắt đầu rầu  019
  • RE: VBA và Google drive

    paulsteigel > 27-08-15, 09:05 AM

    (27-08-15, 08:53 AM)maidinhdan Đã viết: Sao không cọn Access viết vậy anh? thấy Excel là bắt đầu rầu  019

    Vì tớ lười lười - thôi để đóng vào cái demo vậy...
  • RE: VBA và Google drive

    thucgia > 27-08-15, 12:00 PM

    (10-08-15, 03:28 PM)paulsteigel Đã viết: Bản demo đã có nhiều sửa đổi để các cụ Test thử nhé...
    Bản demo tôi cung cấp ở đây là trích từ ứng dụng đang làm dở nên có nhiều chỗ tôi comment bằng tiếng Anh, các cụ thông cảm nhé
    Bản demo của tôi hiện đã có thêm chức năng tải file lên GoogleDrive.

    Tôi đang dùng 1 account thử nghiệm để test, các bác có thể dùng xem sao...
    ============================================
    Phương pháp sử dụng GoogleDrive với VBA
    Đặt vấn đề:
    Tôi cần ứng dụng của tôi tương tác với dịch vụ lưu trữ trên mạng: ở đây sử dụng Google Drive (do họ cung cấp miễn phí đến 15GB với sự ổn định khá cao)
    Ứng dụng của tôi viết trên nền VBA và tôi cần các file của tôi có thể tải lên và tải xuống khi cần.

    Phân tích:
    Hiện tại Google Drive cung cấp phương thức truy nhập ổ đĩa GoogleDrive cho người dùng tuy nhiên đối với người dùng VB/VBA cổ điển thì việc thao tác với googleDrive còn nhiều phiên toái, cụ thể như sau:
    + Làm thế nào để Truy nhập vào tài khoản người dùng một cách tiện lợi?
    + Làm thế nào để sử dụng các câu lệnh GoogleAPI khi tải tập tin lên, đặc biệt là việc vượt qua cơ chế xác thực người dùng ...vv

    Sau thời gian nghiên cứu các phương án thực hiện với sự tham khảo một số tài liệu trên mạng, tôi sử dụng phương án sau đây:
    Công việc 1: Tạo dự án để sử dụng các dịch vụ của Google
    Công việc 2: Tạo ứng dụng và các mã xác thực để sau đó có thể sử dụng dịch vụ GoogleDrive

    1. Làm rõ cơ chế xác thực người dùng và thiết lập các thông tin ban đầu
    Bước 1: Khi truy nhập tài khoản Google, người ta phải cung cấp tên người dùng, mật khẩu
    Bước 2: Google sẽ cung cấp mã xác thực (AuthCode), người dùng sau đó phải nhấn Accept/Chấp nhận trên hộp thoại UserConsent
    Bước 3: Google sẽ cung cấp Khóa truy cập (Token) và người dùng sẽ sử dụng khóa này để thao tác với các dịch vụ của Google.
    Bước 4: Vào https://console.developers.google.com/project để tạo ra một dự án sử dụng các dịch vụ của google như Google Drive chẳng hạn
    + Nhấn nút Create Project
    + Chọn tên dự án, ví dụ ở đây tôi tạo PublicStorage
    Sau khi đợi một lúc, ta chọn dự án PublicStorage từ hộp chọn
    Bước 5: Tạo các mã xác thực
    + Nhấn APIs & auth
    + Nhấn Credentials
    + Nhấn Create new Client ID
    + Chọn Installed Application
    + Nhấn Configure consent screen
    + Mục product name ta chọn một tên thân thiện cho ứng dụng của mình, chẳng hạn ở đây tôi chọn publicdata
    + Nhấn Save
    + Chọn Installed Application, trong mục Installed application type chọn Other
    + Nhấn Create Client ID
    Sau khi xong, nhấn APIs, chọn GoogleDrive rồi nhấn Enable API.

    Chúng ta sẽ nhận được màn hình kết quả với các thông số trong mục Client ID for native application như sau:
    Client ID: [Thay bằng mã của bạn]
    Client secret: [b][Thay bằng mã của bạn][/b]
    Redirect URIs: urn:ietf:wg:oauth:2.0:oob http://localhost

    Hãy lưu ý Client IDClient secret, đây là những cái chúng ta cần sau này.

    Đến đây bước khởi tao ban đầu của chúng ta đã hoàn tất.
    Bây giờ hãy chuyển sang phần coding/ viết mã.

    2. Viết mã, phân tích cơ chế.
    Đáng tiếc là Google chưa xây dựng các cơ chế sử dụng dịch vụ cho ứng dụng viết bằng VBA/VB cổ điển nên chúng ta đành phải mượn công cụ của bên ngoài để thực hiện các chuỗi lệnh thao tác với GoogleDrive. Ở đây tôi đã chọn công cụ rclone viết bằng ngôn ngữ GO (công cụ lập trình của Google) và thao tác bằng dòng lệnh.

    a. Truy nhập vào Google qua cơ chế xác thực OAuth
    Thật may mắn là Google sử dụng cơ chế xác thực người dùng OAuth theo đó, một khi người dùng:
    + Truy nhập vào tài khoản với tên tài khoản và mật khẩu;
    + Cung cấp mã Client_ID, Client_Secret
    + Chấp nhận cho phép sử dụng ứng dụng.
    Google sẽ cho phép bất kỳ ứng dụng nào với các thông tin đã cung cấp khai thác tài nguyên gắn với tài khoản người dùng thông qua một mã gọi là Token. Mỗi máy tính sẽ có một mã Token riêng.

    Vậy trước tiên, chúng ta sẽ thiết kế một mô đun cho phép xác thực với OAuth. Thật may mắn, Tim Halls đã viết giúp chúng ta một Class để thực hiện việc xác thực này, tôi dùng bộ thư viện này với một số sửa đổi trong đó có mấy thủ tục chính bao gồm AuthCode để lấy Code xác thực trên trình duyệt, BrowserComplete để đánh giá khi nào trình duyệt hoàn thành việc lấy thông tin, WaitUntilLoaded để kiểm tra trạng thái của trình duyệt, InitClientCredentials để khai báo các thông tin truy cập, InitEndPoints để thiết lập các địa chỉ truy cập dịch vụ xác thực của google.

    Với class này, tôi chỉ cần viết thêm một đoạn thủ tục sau đây để lấy mã

    Mã:
    Private Function GetAuthCode() As String
        Dim myClass As New gAuth2, client_id As String, client_secret As String
        client_id = "mã client_id của bạn"
        client_secret = "clien_secret của bạn"
        With myClass
            .LogOnGoogle "email của bạn", "mật khẩu của bạn"
            .InitClientCredentials client_id, client_secret
            .InitEndPoints
            GetAuthCode = .AuthCode
        End With
    End Function


    Bước 1 đã xong. Tiếp theo chúng ta sẽ phải thiết lập được phương thức cấu hình cho rclone. Ứng dụng này không thể tự động chạy mà bạn phải tự cấu hình bằng dòng lệnh thông qua thủ tục chạy rclone config và sau đó là khai báo các thông tin khác nhau cho ứng dụng. Đáng tiếc nó lại chạy giống như trong môi trường DOS (command prompt) vì thế sẽ khá khó khăn để người dùng thông thường phải làm việc này bằng tay với các dòng lệnh khô khan.
    Vì ứng dụng của tôi sử dụng 1 tài khoản cho mọi người dùng vì thế tôi bắt buộc phải thiết kế để ứng dụng làm được điều này với sự can thiệp ít nhất của người dùng (Chỉ là nhấn nút đồng ý cho phép thao tác với Google Drive qua màn hình User Consent đã nói ở trên).
    Như thế ta cần một cơ chế có thể truyền tham số cho rclone theo một nhóm trình tự nào đó. Đến đây ta có 2 cách tiếp cận: sử dụng SendKeys và sử dụng Shell để truyền thông tin.
    Cách dùng SendKeys không tốt do nó đòi hỏi màn hình Console (ở đây là DOS) luôn phải kích hoạt. Vì thế tôi lựa chọn cách dùng Shell và giấu màn hình CMD đi rồi truyền tham số. Thủ tục thực hiện đơn giản như sau:

     ' 2 phase 2 - send to console

    Mã:
    Set objShell = CreateObject("WScript.Shell") ' Tạo một phiên làm việc Shell
    Set oExec = objShell.Exec("CMD /K") ' mở giao diện DOS
    Call HideWindow(oExec.ProcessID) ' Giấu giao diện DOS

    Sau đó đến tiết mục truyền tham số cho giao diện DOS thông qua nhóm lệnh sau đây:

    Mã:
    With oExec
    DoEvents
    For i = LBound(cmdList) To UBound(cmdList)
       .StdIn.WriteLine CStr(cmdList(i)) ' truyền từng tham số vào và đợi
    Next
    Do Until .StdOut.AtEndOfStream
       strResults = strResults & vbCrLf & .StdOut.ReadLine ' lấy phản hồi từ giao diện
       DoEvents
    Loop
    End With

    Toàn bộ thủ tục này như sau:


    Mã:
    Private Sub WriteConsole(Optional CreateNew As Boolean = False)
        ' This will try to set up google new token
        Dim objShell As Object
        Dim oExec As Object
        Dim strResults As String
        
        ' 1. Pha 1, truy nhập và lấy mã xác thực
        Dim i As Long, client_id As String, client_secret As String, ReturnValue As Long
        Dim cmdList As Variant, theCode As String
        
        client_id = "456200380740-dr4nihc6u5fslh7larcoiqi6o189liqo.apps.googleusercontent.com"
        client_secret = "duo0jfm-IhRWffLCCtpCJY48"
        
        theCode = GetAuthCode
        If CreateNew Then
            cmdList = Array(rcPath & "rclone.exe config", "n", "gdrive", "6", client_id, client_secret, theCode, "y", "q", "exit")
        Else
            cmdList = Array(rcPath & "rclone.exe config", "e", "1", "", "", "", "", "y", theCode, "y", "q", "exit")
        End If
        DoEvents
        ' 2 phase 2 - send to console
        Set objShell = CreateObject("WScript.Shell")
        Set oExec = objShell.Exec("CMD /K")
        Call HideWindow(oExec.ProcessID)

        With oExec
            ' find a way to get stick to the windows and parse data..
            DoEvents
            For i = LBound(cmdList) To UBound(cmdList)
                .StdIn.WriteLine CStr(cmdList(i)) 
                Sleep 1000 ' wait for the message to be completed
            Next
    ' tiếp nhận kết quả
            Do Until .StdOut.AtEndOfStream
                strResults = strResults & vbCrLf & .StdOut.ReadLine
                DoEvents
            Loop
        End With
        Set oExec = Nothing
        ' in kết quả
        Me.rtbOutput = strResults
    End Sub


    Thủ tục này thực hiện 2 chế đô: tạo mới cấu hình hoặc lấy token mới từ các mã hiện tại.
    Trong ví dụ này, ta dùng call WriteConsole(true)
    Hãy chú ý mảng
    cmdList = Array(rcPath & "rclone.exe config", "n", "gdrive", "6", client_id, client_secret, theCode, "y", "q", "exit")
    nó quy định thứ tự các lệnh sẽ thực hiện bao gồm từ việc tải ra chế độ cấu hình rclone cho đến khi nhập các thống số cấu hình và kết thúc.

    Cú pháp
    Mã:
    .StdIn.WriteLine CStr(cmdList(i)) 
    chịu trách nhiệm gửi lệnh
    và phần sau đó sẽ ghi lại lệnh và gửi ra báo cáo.
    Với việc chạy nhóm thủ tục này, chúng ta sẽ hoàn thành phần cấu hình cho rclone. Thủ tục này chỉ chạy một lần duy nhân khi chạy ứng dụng ban đầu.

    Sau khi đã cài đặt xong, chúng ta chỉ cần sử dụng các dòng lệnh của rclone để thực hiện công việc tạo thư mục, sao chép, tải file lên ...vv
    Nếu các bạn muốn thử, hãy dùng chính account email của mình và theo hướng dẫn sẽ có được kết quả như ý muốn.

    Ứng dụng demo ở sau đây nhé, có nhiều thứ cop nhặt, có gì các bạn cứ hỏi
    http://www.sfdp.net/thuthuataccess/demo/...ects=0&d=1

    Trong file ví dụ của tôi có một số đặc điểm sau:
    + tbRef để lưu trứ 2 tập tin là zlib.dll và rclone.zip (bản nén của rclone).
    + Một số thủ tục giải nén/ dãn nén bằng zlib
    + Một số thủ tục lưu tập tin thư viện vào bảng tbref và bung nó từ bảng này...

    Ứng dụng chạy như sau:
    1. Chạy form frmUpload
    Khi chạy nó sẽ kiểm tra xem đã có 2 tập tin zlib.dll và rclone.exe trong thư mục chạy hay chưa?
    Nếu không có thì sẽ lấy từ trong bảng tbRef ra.

    2. Khi bạn nhấn Lấy Token
    + Bạn cần có các thông tin ở texbox liên quan, hiện tại tôi dùng với 1 account thử nghiệm.
    + Chạy rclone để thiết lập cấu hình lần đầu
    (lần sau nó cũng vẫn chạy như thế vì tôi không đưa ra cơ chế kiểm tra xem có cấu hình của rclone chưa).
    Bây giờ việc chấp thuận cũng như nhập các thông tin khác đã được tự động hóa. Gần đây có báo đưa về việc rò rỉ an ninh liên quan đến cơ chế này, hy vọng Google sẽ sơm có cách điều chỉnh mà không làm ảnh hưởng tới công cụ này!

    Và bạn có thể sửa code để tải vài file ....


    Và nhiều thứ linh tinh mục khác.
    Có ai hỏi gì xin cứ đặt câu hỏi nhé

    Chúc các bạn tuần mới đầy niềm vui!


    Bước 5: Tạo các mã xác thực
    + Nhấn APIs & auth
    + Nhấn Credentials
    + Nhấn Create new Client ID
    + Chọn Installed Application
    + Nhấn Configure consent screen
    + Mục product name ta chọn một tên thân thiện cho ứng dụng của mình, chẳng hạn ở đây tôi chọn publicdata
    + Nhấn Save
    + Chọn Installed Application, trong mục Installed application type chọn Other
    + Nhấn Create Client ID
    Sau khi xong, nhấn APIs, chọn GoogleDrive rồi nhấn Enable API.

    ??? sao mình làm bước này không được nhỉ
    không thấy các id
  • RE: VBA và Google drive

    thucgia > 27-08-15, 01:43 PM

    (10-08-15, 03:28 PM)paulsteigel Đã viết: Bản demo đã có nhiều sửa đổi để các cụ Test thử nhé...
    Bản demo tôi cung cấp ở đây là trích từ ứng dụng đang làm dở nên có nhiều chỗ tôi comment bằng tiếng Anh, các cụ thông cảm nhé
    Bản demo của tôi hiện đã có thêm chức năng tải file lên GoogleDrive.

    Tôi đang dùng 1 account thử nghiệm để test, các bác có thể dùng xem sao...
    ============================================
    Phương pháp sử dụng GoogleDrive với VBA
    Đặt vấn đề:
    Tôi cần ứng dụng của tôi tương tác với dịch vụ lưu trữ trên mạng: ở đây sử dụng Google Drive (do họ cung cấp miễn phí đến 15GB với sự ổn định khá cao)
    Ứng dụng của tôi viết trên nền VBA và tôi cần các file của tôi có thể tải lên và tải xuống khi cần.

    Phân tích:
    Hiện tại Google Drive cung cấp phương thức truy nhập ổ đĩa GoogleDrive cho người dùng tuy nhiên đối với người dùng VB/VBA cổ điển thì việc thao tác với googleDrive còn nhiều phiên toái, cụ thể như sau:
    + Làm thế nào để Truy nhập vào tài khoản người dùng một cách tiện lợi?
    + Làm thế nào để sử dụng các câu lệnh GoogleAPI khi tải tập tin lên, đặc biệt là việc vượt qua cơ chế xác thực người dùng ...vv

    Sau thời gian nghiên cứu các phương án thực hiện với sự tham khảo một số tài liệu trên mạng, tôi sử dụng phương án sau đây:
    Công việc 1: Tạo dự án để sử dụng các dịch vụ của Google
    Công việc 2: Tạo ứng dụng và các mã xác thực để sau đó có thể sử dụng dịch vụ GoogleDrive

    1. Làm rõ cơ chế xác thực người dùng và thiết lập các thông tin ban đầu
    Bước 1: Khi truy nhập tài khoản Google, người ta phải cung cấp tên người dùng, mật khẩu
    Bước 2: Google sẽ cung cấp mã xác thực (AuthCode), người dùng sau đó phải nhấn Accept/Chấp nhận trên hộp thoại UserConsent
    Bước 3: Google sẽ cung cấp Khóa truy cập (Token) và người dùng sẽ sử dụng khóa này để thao tác với các dịch vụ của Google.
    Bước 4: Vào https://console.developers.google.com/project để tạo ra một dự án sử dụng các dịch vụ của google như Google Drive chẳng hạn
    + Nhấn nút Create Project
    + Chọn tên dự án, ví dụ ở đây tôi tạo PublicStorage
    Sau khi đợi một lúc, ta chọn dự án PublicStorage từ hộp chọn
    Bước 5: Tạo các mã xác thực
    + Nhấn APIs & auth
    + Nhấn Credentials
    + Nhấn Create new Client ID
    + Chọn Installed Application
    + Nhấn Configure consent screen
    + Mục product name ta chọn một tên thân thiện cho ứng dụng của mình, chẳng hạn ở đây tôi chọn publicdata
    + Nhấn Save
    + Chọn Installed Application, trong mục Installed application type chọn Other
    + Nhấn Create Client ID
    Sau khi xong, nhấn APIs, chọn GoogleDrive rồi nhấn Enable API.

    Chúng ta sẽ nhận được màn hình kết quả với các thông số trong mục Client ID for native application như sau:
    Client ID: [Thay bằng mã của bạn]
    Client secret: [b][Thay bằng mã của bạn][/b]
    Redirect URIs: urn:ietf:wg:oauth:2.0:oob http://localhost

    Hãy lưu ý Client IDClient secret, đây là những cái chúng ta cần sau này.

    Đến đây bước khởi tao ban đầu của chúng ta đã hoàn tất.
    Bây giờ hãy chuyển sang phần coding/ viết mã.

    2. Viết mã, phân tích cơ chế.
    Đáng tiếc là Google chưa xây dựng các cơ chế sử dụng dịch vụ cho ứng dụng viết bằng VBA/VB cổ điển nên chúng ta đành phải mượn công cụ của bên ngoài để thực hiện các chuỗi lệnh thao tác với GoogleDrive. Ở đây tôi đã chọn công cụ rclone viết bằng ngôn ngữ GO (công cụ lập trình của Google) và thao tác bằng dòng lệnh.

    a. Truy nhập vào Google qua cơ chế xác thực OAuth
    Thật may mắn là Google sử dụng cơ chế xác thực người dùng OAuth theo đó, một khi người dùng:
    + Truy nhập vào tài khoản với tên tài khoản và mật khẩu;
    + Cung cấp mã Client_ID, Client_Secret
    + Chấp nhận cho phép sử dụng ứng dụng.
    Google sẽ cho phép bất kỳ ứng dụng nào với các thông tin đã cung cấp khai thác tài nguyên gắn với tài khoản người dùng thông qua một mã gọi là Token. Mỗi máy tính sẽ có một mã Token riêng.

    Vậy trước tiên, chúng ta sẽ thiết kế một mô đun cho phép xác thực với OAuth. Thật may mắn, Tim Halls đã viết giúp chúng ta một Class để thực hiện việc xác thực này, tôi dùng bộ thư viện này với một số sửa đổi trong đó có mấy thủ tục chính bao gồm AuthCode để lấy Code xác thực trên trình duyệt, BrowserComplete để đánh giá khi nào trình duyệt hoàn thành việc lấy thông tin, WaitUntilLoaded để kiểm tra trạng thái của trình duyệt, InitClientCredentials để khai báo các thông tin truy cập, InitEndPoints để thiết lập các địa chỉ truy cập dịch vụ xác thực của google.

    Với class này, tôi chỉ cần viết thêm một đoạn thủ tục sau đây để lấy mã

    Mã:
    Private Function GetAuthCode() As String
        Dim myClass As New gAuth2, client_id As String, client_secret As String
        client_id = "mã client_id của bạn"
        client_secret = "clien_secret của bạn"
        With myClass
            .LogOnGoogle "email của bạn", "mật khẩu của bạn"
            .InitClientCredentials client_id, client_secret
            .InitEndPoints
            GetAuthCode = .AuthCode
        End With
    End Function


    Bước 1 đã xong. Tiếp theo chúng ta sẽ phải thiết lập được phương thức cấu hình cho rclone. Ứng dụng này không thể tự động chạy mà bạn phải tự cấu hình bằng dòng lệnh thông qua thủ tục chạy rclone config và sau đó là khai báo các thông tin khác nhau cho ứng dụng. Đáng tiếc nó lại chạy giống như trong môi trường DOS (command prompt) vì thế sẽ khá khó khăn để người dùng thông thường phải làm việc này bằng tay với các dòng lệnh khô khan.
    Vì ứng dụng của tôi sử dụng 1 tài khoản cho mọi người dùng vì thế tôi bắt buộc phải thiết kế để ứng dụng làm được điều này với sự can thiệp ít nhất của người dùng (Chỉ là nhấn nút đồng ý cho phép thao tác với Google Drive qua màn hình User Consent đã nói ở trên).
    Như thế ta cần một cơ chế có thể truyền tham số cho rclone theo một nhóm trình tự nào đó. Đến đây ta có 2 cách tiếp cận: sử dụng SendKeys và sử dụng Shell để truyền thông tin.
    Cách dùng SendKeys không tốt do nó đòi hỏi màn hình Console (ở đây là DOS) luôn phải kích hoạt. Vì thế tôi lựa chọn cách dùng Shell và giấu màn hình CMD đi rồi truyền tham số. Thủ tục thực hiện đơn giản như sau:

     ' 2 phase 2 - send to console

    Mã:
    Set objShell = CreateObject("WScript.Shell") ' Tạo một phiên làm việc Shell
    Set oExec = objShell.Exec("CMD /K") ' mở giao diện DOS
    Call HideWindow(oExec.ProcessID) ' Giấu giao diện DOS

    Sau đó đến tiết mục truyền tham số cho giao diện DOS thông qua nhóm lệnh sau đây:

    Mã:
    With oExec
    DoEvents
    For i = LBound(cmdList) To UBound(cmdList)
       .StdIn.WriteLine CStr(cmdList(i)) ' truyền từng tham số vào và đợi
    Next
    Do Until .StdOut.AtEndOfStream
       strResults = strResults & vbCrLf & .StdOut.ReadLine ' lấy phản hồi từ giao diện
       DoEvents
    Loop
    End With

    Toàn bộ thủ tục này như sau:


    Mã:
    Private Sub WriteConsole(Optional CreateNew As Boolean = False)
        ' This will try to set up google new token
        Dim objShell As Object
        Dim oExec As Object
        Dim strResults As String
        
        ' 1. Pha 1, truy nhập và lấy mã xác thực
        Dim i As Long, client_id As String, client_secret As String, ReturnValue As Long
        Dim cmdList As Variant, theCode As String
        
        client_id = "456200380740-dr4nihc6u5fslh7larcoiqi6o189liqo.apps.googleusercontent.com"
        client_secret = "duo0jfm-IhRWffLCCtpCJY48"
        
        theCode = GetAuthCode
        If CreateNew Then
            cmdList = Array(rcPath & "rclone.exe config", "n", "gdrive", "6", client_id, client_secret, theCode, "y", "q", "exit")
        Else
            cmdList = Array(rcPath & "rclone.exe config", "e", "1", "", "", "", "", "y", theCode, "y", "q", "exit")
        End If
        DoEvents
        ' 2 phase 2 - send to console
        Set objShell = CreateObject("WScript.Shell")
        Set oExec = objShell.Exec("CMD /K")
        Call HideWindow(oExec.ProcessID)

        With oExec
            ' find a way to get stick to the windows and parse data..
            DoEvents
            For i = LBound(cmdList) To UBound(cmdList)
                .StdIn.WriteLine CStr(cmdList(i)) 
                Sleep 1000 ' wait for the message to be completed
            Next
    ' tiếp nhận kết quả
            Do Until .StdOut.AtEndOfStream
                strResults = strResults & vbCrLf & .StdOut.ReadLine
                DoEvents
            Loop
        End With
        Set oExec = Nothing
        ' in kết quả
        Me.rtbOutput = strResults
    End Sub


    Thủ tục này thực hiện 2 chế đô: tạo mới cấu hình hoặc lấy token mới từ các mã hiện tại.
    Trong ví dụ này, ta dùng call WriteConsole(true)
    Hãy chú ý mảng
    cmdList = Array(rcPath & "rclone.exe config", "n", "gdrive", "6", client_id, client_secret, theCode, "y", "q", "exit")
    nó quy định thứ tự các lệnh sẽ thực hiện bao gồm từ việc tải ra chế độ cấu hình rclone cho đến khi nhập các thống số cấu hình và kết thúc.

    Cú pháp
    Mã:
    .StdIn.WriteLine CStr(cmdList(i)) 
    chịu trách nhiệm gửi lệnh
    và phần sau đó sẽ ghi lại lệnh và gửi ra báo cáo.
    Với việc chạy nhóm thủ tục này, chúng ta sẽ hoàn thành phần cấu hình cho rclone. Thủ tục này chỉ chạy một lần duy nhân khi chạy ứng dụng ban đầu.

    Sau khi đã cài đặt xong, chúng ta chỉ cần sử dụng các dòng lệnh của rclone để thực hiện công việc tạo thư mục, sao chép, tải file lên ...vv
    Nếu các bạn muốn thử, hãy dùng chính account email của mình và theo hướng dẫn sẽ có được kết quả như ý muốn.

    Ứng dụng demo ở sau đây nhé, có nhiều thứ cop nhặt, có gì các bạn cứ hỏi
    http://www.sfdp.net/thuthuataccess/demo/...ects=0&d=1

    Trong file ví dụ của tôi có một số đặc điểm sau:
    + tbRef để lưu trứ 2 tập tin là zlib.dll và rclone.zip (bản nén của rclone).
    + Một số thủ tục giải nén/ dãn nén bằng zlib
    + Một số thủ tục lưu tập tin thư viện vào bảng tbref và bung nó từ bảng này...

    Ứng dụng chạy như sau:
    1. Chạy form frmUpload
    Khi chạy nó sẽ kiểm tra xem đã có 2 tập tin zlib.dll và rclone.exe trong thư mục chạy hay chưa?
    Nếu không có thì sẽ lấy từ trong bảng tbRef ra.

    2. Khi bạn nhấn Lấy Token
    + Bạn cần có các thông tin ở texbox liên quan, hiện tại tôi dùng với 1 account thử nghiệm.
    + Chạy rclone để thiết lập cấu hình lần đầu
    (lần sau nó cũng vẫn chạy như thế vì tôi không đưa ra cơ chế kiểm tra xem có cấu hình của rclone chưa).
    Bây giờ việc chấp thuận cũng như nhập các thông tin khác đã được tự động hóa. Gần đây có báo đưa về việc rò rỉ an ninh liên quan đến cơ chế này, hy vọng Google sẽ sơm có cách điều chỉnh mà không làm ảnh hưởng tới công cụ này!

    Và bạn có thể sửa code để tải vài file ....


    Và nhiều thứ linh tinh mục khác.
    Có ai hỏi gì xin cứ đặt câu hỏi nhé

    Chúc các bạn tuần mới đầy niềm vui!

    Hình như giao diện đường link :

    https://console.developers.google.com/project

    bi giờ đã được thay đổi, nên mình không thể lấy được Client ID và Client secret như bạn hướng dẫn. Hay là Google thay đổi chính sách không?

    Mình tìm thấy đoạn youtube sau giống như hướng dẫn của bạn

    video how to get Client ID and Client secret
  • RE: VBA và Google drive

    paulsteigel > 27-08-15, 02:05 PM

    (27-08-15, 09:05 AM)paulsteigel Đã viết:
    (27-08-15, 08:53 AM)maidinhdan Đã viết: Sao không cọn Access viết vậy anh? thấy Excel là bắt đầu rầu  019

    Vì tớ lười lười - thôi để đóng vào cái demo vậy...

    Có bản demo cho access rồi nhé. Link ở bài đầu Dân ạ. Hoặc ở đây:
    http://www.sfdp.net/thuthuataccess/demo/...ects=0&d=1
    Đến tối mình sẽ trả lời bạn thugia. Giờ đang bận tí. Bạn thông cảm nhé.