Lấy dữ liệu cổ phiếu từ Website Cafef.vn về Excel

Liên hệ QC
Bạn cần lấy thông tin gì từ web https://shopee.vn/search?keyword=bánh gạo
và có thể chia sẻ phần code đã viết không ?
Để xem có hướng bẫy capcha, hoặc delay thời gian.
Bạn có thể tìm một số code tương tự trên Stack Overflow nhé, mình cũng lấy ở đây.
Bài đã được tự động gộp:

lâu này ta hay keo sử dụng Python lấy dữ liệu Web Siêu nhanh có lẻ cũng tới lúc xem xét lại rồi

Delphi lấy dữ liệu Web OK sạch chỉ là ta chưa biết cách sử dụng nó + nguồn trang Web cần lấy thôi

có điều lấy dữ liệu Web phụ thuộc vào máy chủ của nó cho hay không cho và nó chỉ cần thay đổi tí teo xem như căng mắt ra dò lại từ đầu

nên tôi chỉ dừng ở bức biết chút chút khi cần sử dụng là đủ ... rảnh chơi cái khác thú vị hơn

Hiểu ra nguồn trang Web + cách sử dụng Delphi = OK
Quan trọng là tiện lợi, nhanh và gọn mà bạn.
Python viết xong cái là chạy được ngay. Nhà mình có con Android TV box cùi chạy Armbian, toàn là viết mã Python xong vứt lên đó cho nó cào dữ liệu trên internet 24/7, tiết kiệm điện, chứ nếu cần cũng có thể viết C# .NET Core biên dịch thành ARM64 chạy trên Armbian vẫn ngon.
 
Lần chỉnh sửa cuối:
Bạn có thể tìm một số code tương tự trên Stack Overflow nhé, mình cũng lấy ở đây.
Bài đã được tự động gộp:


Quan trọng là tiện lợi, nhanh và gọn mà bạn.
Python viết xong cái là chạy được ngay. Nhà mình có con Android TV box cùi chạy Armbian, toàn là viết mã Python xong vứt lên đó cho nó cào dữ liệu trên internet 24/7, tiết kiệm điện, chứ nếu cần cũng có thể viết C# .NET Core biên dịch thành ARM64 chạy trên Armbian vẫn ngon.
có thấy nguồn nào xác định đó là loại JSON gì hay không kiểu như xác định Type khi truyền tham số DataJSON vào hàm sẻ trả về nếu là TJSONArray hay TJSONObject và cách loại khác .. cho link tham khảo chút

Mới xong cái hàm xác định chính xác 2 loại JSON cơ bản là TJSONArray và TJSONObject

còn kiểu sau là tịt :p

Mã:
/*O_o*/
google.visualization.Query.setResponse({"version":"0.6","reqId":"0","status":"ok","sig":"1617797785","table":{"cols":[{"id":"A","label":"","type":"number","pattern":"General"},{"id":"B","label":"","type":"string"},{"id":"C","label":"","type":"string"},{"id":"D","label":"","type":"string"},{"id":"E","label":"","type":"number","pattern":"General"},{"id":"F","label":"","type":"string"},{"id":"G","label":"","type":"string"},{"id":"H","label":"","type":"number","pattern":"General"},{"id":"I","label":"","type":"string"},{"id":"J","label":"","type":"string"},{"id":"K","label":"","type":"number","pattern":"General"},{"id":"L","label":"","type":"string"},{"id":"M","label":"","type":"string"},{"id":"N","label":"","type":"number","pattern":"General"},{"id":"O","label":"","type":"string"},{"id":"P","label":"","type":"string"},{"id":"Q","label":"","type":"number","pattern":"General"},{"id":"R","label":"","type":"string"},{"id":"S","label":"","type":"string"},{"id":"T","label":"","type":"number","pattern":"General"},{"id"
:"U","label":"","type":"string"},{"id":"V","label":"","type":"string"},{"id":"W","label":"","type":"number","pattern":"General"},{"id":"X","label":"","type":"string"},{"id":"Y","label":"","type":"string"},{"id":"Z","label":"","type":"number","pattern":"General"},{"id":"AA","label":"","type":"string"},{"id":"AB","label":"","type":"string"},{"id":"AC","label":"","type":"number","pattern":"General"},{"id":"AD","label":"","type":"string"},{"id":"AE","label":"","type":"string"},{"id":"AF","label":"","type":"number","pattern":"General"},{"id":"AG","label":"","type":"string"},{"id":"AH","label":"","type":"string"},{"id":"AI","label":"","type":"number","pattern":"General"},{"id":"AJ","label":"","type":"string"},{"id":"AK","label":"","type":"string"},{"id":"AL","label":"","type":"number","pattern":"General"},{"id":"AM","label":"","type":"string"},{"id":"AN","label":"","type":"string"},{"id":"AO","label":"","type":"number","pattern":"General"},{"id":"AP","label":"","type":"string"},{"id":"AQ","label":"","type":"string
"},{"id":"AR","label":"","type":"number","pattern":"General"},{"id":"AS","label":"","type":"string"},{"id":"AT","label":"","type":"string"},{"id":"AU","label":"","type":"number","pattern":"General"},{"id":"AV","label":"","type":"string"},{"id":"AW","label":"","type":"string"},{"id":"AX","label":"","type":"number","pattern":"General"},{"id":"AY","label":"","type":"string"},{"id":"AZ","label":"","type":"string"},{"id":"BA","label":"","type":"number","pattern":"General"},{"id":"BB","label":"","type":"string"},{"id":"BC","label":"","type":"string"},{"id":"BD","label":"","type":"number","pattern":"General"},{"id":"BE","label":"","type":"string"},{"id":"BF","label":"","type":"string"},{"id":"BG","label":"","type":"number","pattern":"General"},{"id":"BH","label":"","type":"string"},{"id":"BI","label":"","type":"string"},{"id":"BJ","label":"","type":"number","pattern":"General"},{"id":"BK","label":"","type":"string"},{"id":"BL","label":"","type":"string"},{"id":"BM","label":"","type":"number","pattern":"General"},{"
id":"BN","label":"","type":"string"},{"id":"BO","label":"","type":"string"},{"id":"BP","label":"","type":"number","pattern":"General"},{"id":"BQ","label":"","type":"string"},{"id":"BR","label":"","type":"string"},{"id":"BS","label":"","type":"number","pattern":"General"},{"id":"BT","label":"","type":"string"},{"id":"BU","label":"","type":"string"},{"id":"BV","label":"","type":"number","pattern":"General"},{"id":"BW","label":"","type":"string"},{"id":"BX","label":"","type":"string"},{"id":"BY","label":"","type":"number","pattern":"General"},{"id":"BZ","label":"","type":"string"},{"id":"CA","label":"","type":"string"},{"id":"CB","label":"","type":"number","pattern":"General"},{"id":"CC","label":"","type":"string"},{"id":"CD","label":"","type":"string"},{"id":"CE","label":"","type":"number","pattern":"General"},{"id":"CF","label":"","type":"string"},{"id":"CG","label":"","type":"string"},{"id":"CH","label":"","type":"number","pattern":"General"},{"id":"CI","label":"","type":"string"},{"id":"CJ","label":"","type
":"string"},{"id":"CK","label":"","type":"number","pattern":"General"},{"id":"CL","label":"","type":"string"},{"id":"CM","label":"","type":"string"},{"id":"CN","label":"","type":"number","pattern":"General"},{"id":"CO","label":"","type":"string"},{"id":"CP","label":"","type":"string"},{"id":"CQ","label":"","type":"number","pattern":"General"},{"id":"CR","label":"","type":"number","pattern":"General"},{"id":"CS","label":"","type":"string"},{"id":"CT","label":"","type":"string"}],"rows":[{"c":[null,null,{"v":"1"},null,null,{"v":"2"},null,null,{"v":"3"},null,null,{"v":"4"},null,null,{"v":"5"},null,null,{"v":"6"},null,null,{"v":"7"},null,null,{"v":"8"},null,null,{"v":"9"},null,null,{"v":"10"},null,null,{"v":"11"},null,null,{"v":"12"},null,null,{"v":"13"},null,null,{"v":"14"},null,null,{"v":"15"},null,null,{"v":"16"},null,null,{"v":"17"},null,null,{"v":"18"},null,null,{"v":"19"},null,null,{"v":"20"},null,null,{"v":"21"},null,null,{"v":"22"},null,null,{"v":"23"},null,null,{"v":"24"},null,null,{"v":"25"},null,null,
{"v":"26"},null,null,{"v":"27"},null,null,{"v":"28"},null,null,{"v":"29"},null,null,{"v":"30"},null,null,{"v":"31"},null,null,null,null,{"v":null}]},{"c":[null,{"v":"Tên"},{"v":"Gi? vào"},{"v":"Gi? ra"},null,{"v":"Gi? vào"},{"v":"Gi? ra"},null,{"v":"Gi? vào"},{"v":"Gi? ra"},null,{"v":"Gi? vào"},{"v":"Gi? ra"},null,{"v":"Gi? vào"},{"v":"Gi? ra"},null,{"v":"Gi? vào"},{"v":"Gi? ra"},null,{"v":"Gi? vào"},{"v":"Gi? ra"},null,{"v":"Gi? vào"},{"v":"Gi? ra"},null,{"v":"Gi? vào"},{"v":"Gi? ra"},null,{"v":"Gi? vào"},{"v":"Gi? ra"},null,{"v":"Gi? vào"},{"v":"Gi? ra"},null,{"v":"Gi? vào"},{"v":"Gi? ra"},null,{"v":"Gi? vào"},{"v":"Gi? ra"},null,{"v":"Gi? vào"},{"v":"Gi? ra"},null,{"v":"Gi? vào"},{"v":"Gi? ra"},null,{"v":"Gi? vào"},{"v":"Gi? ra"},null,{"v":"Gi? vào"},{"v":"Gi? ra"},null,{"v":"Gi? vào"},{"v":"Gi? ra"},null,{"v":"Gi? vào"},{"v":"Gi? ra"},null,{"v":"Gi? vào"},{"v":"Gi? ra"},null,{"v":"Gi? vào"},{"v":"Gi? ra"},null,{"v":"Gi? vào"},{"v":"Gi? ra"},null,{"v":"Gi? vào"},{"v":"Gi? ra"},null,{"v":"Gi? vào"},{"v":"G
i? ra"},null,{"v":"Gi? vào"},{"v":"Gi? ra"},null,{"v":"Gi? vào"},{"v":"Gi? ra"},null,{"v":"Gi? vào"},{"v":"Gi? ra"},null,{"v":"Gi? vào"},{"v":"Gi? ra"},null,{"v":"Gi? vào"},{"v":"Gi? ra"},null,{"v":"Gi? vào"},{"v":"Gi? ra"},null,{"v":"Gi? vào"},{"v":"Gi? ra"},null,null,null,{"v":null}]},{"c":[{"v":3.0,"f":"3"},{"v":"B"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"}
,{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":31.0,"f":"31"},null,{"v":null}]},{"c":[{"v":4.0,"f":"4"},{"v":"B"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":
8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"1
7:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":31.0,"f":"31"},null,{"v":null}]},{"c":[{"v":8.0,"f":"8"},{"v":"B"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"}
,{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":"7:00"},{"v":"17:00"},{"v":8.0,"f":"8"},{"v":31.0,"f":"31"},null,{"v":null}]},{"c":[null,{"v":"T?ng c?ng"},null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,nu
ll,null,null,null,null,null,null,null,null,null,null,null,null,null,{"v":93.0,"f":"93"},null,{"v":null}]}],"parsedNumHeaders":0}});
 
JSON chỉ có một tiêu chuẩn mà thế giới thống nhất chứ không phải Google khác đâu. JSON cho phép khai báo các đối tượng mà các thành phần của chúng lại có thể là loại đối tượng khác nhau nhau. Ví dụ cấu trúc mẹ là một array - TJSONArray, trong mỗi phần tử của array lại là một object - TJSONObject, trong object này khai báo các thuộc tính, và một trong các thuộc tính đó lại có kiểu array - TJSONArray,.... Đây là một kiểu khai báo dạng Tree. Vậy nên mục tiêu hàm lấy cái gì thì phải lấy thành phần đó, các thành phần con đưa nó về string nếu cần.
Kiểm tra cấu trúc JSON thuộc loại nào thì chỉ cần:
{Delphi code}
var jv: TJsonValue;
begin
jv := TJSONValue.ParseJSONValue(responseString);
if jv is TJSONArray then
//xử lý kiể array
else
if jv is TJSONObject then
//Xử lý kiểu object
else
....
end;
 
JSON chỉ có một tiêu chuẩn mà thế giới thống nhất chứ không phải Google khác đâu. JSON cho phép khai báo các đối tượng mà các thành phần của chúng lại có thể là loại đối tượng khác nhau nhau. Ví dụ cấu trúc mẹ là một array - TJSONArray, trong mỗi phần tử của array lại là một object - TJSONObject, trong object này khai báo các thuộc tính, và một trong các thuộc tính đó lại có kiểu array - TJSONArray,.... Đây là một kiểu khai báo dạng Tree. Vậy nên mục tiêu hàm lấy cái gì thì phải lấy thành phần đó, các thành phần con đưa nó về string nếu cần.
Kiểm tra cấu trúc JSON thuộc loại nào thì chỉ cần:
{Delphi code}
var jv: TJsonValue;
begin
jv := TJSONValue.ParseJSONValue(responseString);
if jv is TJSONArray then
//xử lý kiể array
else
if jv is TJSONObject then
//Xử lý kiểu object
else
....
end;
hiểu đơn giản thì nó là vậy không lẻ tôi lại không biết điều đó

đi vào thực tế viết hàm trả về TypeName của một DataJSON bất kỳ truyền vào hàm xong kiểm trả xem nó là TJSONArray hay TJSONObject và các loại DataJSON khác nữa thì là chuyện khó lên rồi

Như bài số 22 thì 2 mục bạn nêu Tôi đã làm xong rồi nhưng không đơn giản là if jv is TJSONArray then ... thế là xong


1726124445952.png

Mở rộng trong Hàm ra kiểm tra mọi loại DataJSON truyền vào hàm thì mới là vấn đề tôi đang dò ... còn 2 mục cơ bản trên xong rồi
 
hiểu đơn giản thì nó là vậy không lẻ tôi lại không biết điều đó

đi vào thực tế viết hàm trả về TypeName của một DataJSON bất kỳ truyền vào hàm xong kiểm trả xem nó là TJSONArray hay TJSONObject và các loại DataJSON khác nữa thì là chuyện khó lên rồi

Như bài số 22 thì 2 mục bạn nêu Tôi đã làm xong rồi nhưng không đơn giản là if jv is TJSONArray then ... thế là xong


View attachment 303914

Mở rộng trong Hàm ra kiểm tra mọi loại DataJSON truyền vào hàm thì mới là vấn đề tôi đang dò ... còn 2 mục cơ bản trên xong rồi

Nếu bạn hiểu đúng thì cố làm đúng là ra nhé.
 
Rảnh tôi thử hàm mô tả bài số 6 Web khác xem sao thấy sử dụng tốt.. khi kết hợp với các thự viện khác có sẳn của Windows
Lấy tỷ giá VCB


Mã:
Rem https://portal.vietcombank.com.vn/UserControls/TVPortal.TyGia/pListTyGia.aspx?txttungay=25/02/2021&BacrhID=1&isEn=False
Sub TestSendHttpRequest3_vietcombank()
    Dim response As String
    Dim URL As String
    Dim Method As String
    Dim ContentType As String
    Dim Accept As String
    Dim UserAgent As String
    Dim DataToSend As String
    Dim html As New HTMLDocument ' Thay d?i cách khai báo
    Dim tbl As Object
    Dim row As Object
    Dim cell As Object
    Dim i As Integer, j As Integer

    ' Khai báo thông tin c?n thi?t
    URL = "https://portal.vietcombank.com.vn/UserControls/TVPortal.TyGia/pListTyGia.aspx?txttungay=25/02/2021&BacrhID=1&isEn=False"
    Method = "GET"
    ContentType = "application/json"
    Accept = "application/json"
    UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0"
    DataToSend = ""  ' D? li?u d? g?i, d? tr?ng cho phuong th?c GET

    ' G?i hàm SendHttpRequest
    Rem response = SendHttpRequest(Method, URL, ContentType, Accept, UserAgent, DataToSend)
    response = SendHttpRequest(Method, URL, "", "", "", DataToSend)

    ' Gán n?i dung ph?n h?i vào d?i tu?ng HTMLDocument
    html.body.innerHTML = response

    ' Tìm b?ng d? li?u d?a trên id c?a b?ng
    Set tbl = html.getElementById("ctl00_Content_ExrateView")
    
    Cells.ClearContents

    ' N?u tìm th?y b?ng thì x? lý
    If Not tbl Is Nothing Then
        ' Thêm tiêu d? b?ng t? th? <th>
        i = 1
        j = 1
        For Each cell In tbl.getElementsByTagName("th")
            Cells(i, j).Value = cell.innerText
            j = j + 1
        Next cell

        ' Duy?t qua các hàng và ô c?a b?ng và dua d? li?u vào Excel
        i = 2 ' B?t d?u t? dòng 2 vì dòng 1 ch?a tiêu d?
        For Each row In tbl.getElementsByTagName("tr")
            j = 1
            For Each cell In row.getElementsByTagName("td")
                Cells(i, j).Value = cell.innerText
                j = j + 1
            Next cell
            i = i + 1
        Next row
    Else
        MsgBox "Không tìm th?y b?ng d? li?u."
    End If
End Sub

Trên Delphi thư viện Indy quá tuyệt vời chạy đa nền tảng không lệ thuộc tây lông nào cả :p
 
Mấy trang khác thì không nói chứ trang tỷ giá Vietcombank hiện tại thì quá đơn giản, có sẳn API mà xài thôi. :D

JavaScript:
Option Explicit

Sub getVCBExchangeRate()
    Dim js As Object, dicData As Object
    Dim url As String, sDate As String, res As String, k As Long
  
    Application.ScreenUpdating = False
    
    '"https://www.vietcombank.com.vn/api/exchangerates?date=2024-09-12"
    url = "https://www.vietcombank.com.vn/api/exchangerates?date="
    sDate = Format(Sheets("VCB").Range("A1").value, "yyyy-mm-dd")
    url = url & sDate
    res = httpGet(url)

    Set js = JsonConverter.ParseJSON(res)
    Set dicData = js("Data")
    
    ReDim arr(dicData.Count, 4)
    For k = 1 To dicData.Count
        arr(k - 1, 0) = dicData(k)("currencyCode")
        arr(k - 1, 1) = dicData(k)("currencyName")
        arr(k - 1, 2) = dicData(k)("cash")
        arr(k - 1, 3) = dicData(k)("transfer")
        arr(k - 1, 4) = dicData(k)("sell")
    Next
    Sheets("VCB").Range("B3").value = js("Date")
    Sheets("VCB").Range("A5").Resize(UBound(arr, 1) + 1, UBound(arr, 2) + 1).value = arr
    
End Sub

Screen Shot 2024-09-13 at 13.13.11.png
 
Mấy trang khác thì không nói chứ trang tỷ giá Vietcombank hiện tại thì quá đơn giản, có sẳn API mà xài thôi. :D

JavaScript:
Option Explicit

Sub getVCBExchangeRate()
    Dim js As Object, dicData As Object
    Dim url As String, sDate As String, res As String, k As Long
 
    Application.ScreenUpdating = False
 
    '"https://www.vietcombank.com.vn/api/exchangerates?date=2024-09-12"
    url = "https://www.vietcombank.com.vn/api/exchangerates?date="
    sDate = Format(Sheets("VCB").Range("A1").value, "yyyy-mm-dd")
    url = url & sDate
    res = httpGet(url)

    Set js = JsonConverter.ParseJSON(res)
    Set dicData = js("Data")
 
    ReDim arr(dicData.Count, 4)
    For k = 1 To dicData.Count
        arr(k - 1, 0) = dicData(k)("currencyCode")
        arr(k - 1, 1) = dicData(k)("currencyName")
        arr(k - 1, 2) = dicData(k)("cash")
        arr(k - 1, 3) = dicData(k)("transfer")
        arr(k - 1, 4) = dicData(k)("sell")
    Next
    Sheets("VCB").Range("B3").value = js("Date")
    Sheets("VCB").Range("A5").Resize(UBound(arr, 1) + 1, UBound(arr, 2) + 1).value = arr
 
End Sub

View attachment 303941
Link trên nó sử dụng JSON Data Object khi Bạn sử dụng Module trên VBA nó hổ trợ 2 loại JSON mà tôi nói bài 22 và 24 xem trong Module đó khoãng trên 1000 dòng code

Tôi mới viết xong hàm đa luồng song song xử lý 2 loại JSON đó trong Delphi khõang 70 dòng code chi đó mà chạy nhanh hơn

1726212745918.png
Hình trên xử lý JSON 12 luồng và duyệt JSON gán lên Sheet 12 luồng nếu dữ liệu nhiều bay vèo vèo còn ít thì nó như nhau cả có sai tí ti không đáng tính
 
Copy Code sau vào File bài Số 1 xong gõ hàm trên Sheet theo các tham số xong Enter cái Cộp ... dữ liệu Google Sheet nó bay về Excel
Mã:
Declare PtrSafe Function GoogleSheetAsRecordset Lib "GoogleSheets64.dll" _
            (ByRef SheetId As Variant, _
             ByRef APIKey As Variant, _
             ByRef SheetName As Variant) As Variant
           
Function GetValue(value As Variant) As Variant
    If IsNull(value) Then
        GetValue = ""
    ElseIf IsNumeric(value) Then
        If Len(value) > 12 Then
            GetValue = Format(value, "#,##0.00")
        Else
            GetValue = Format(value, "#,##0")
        End If
    ElseIf IsDate(value) Then
        GetValue = Format(value, "dd/mm/yyyy")
    ElseIf Len(value) = 10 And IsNumeric(value) Then
        GetValue = Format(value, "####-###-###")
    Else
        GetValue = value
    End If
End Function

Function LoadDataFromGoogleSheets(SheetId As String, APIKey As String, SheetName As String) As Variant
    Dim Data As Variant
    Dim Res() As Variant
    Dim i As Long, j As Long
    Dim Rows As Long, Cols As Long
    Dim rs As Object

    ' Get the recordset from Google Sheets
    Set rs = GoogleSheetAsRecordset(SheetId, APIKey, SheetName)

    If Not rs Is Nothing Then
        If Not rs.EOF Then
            ' Retrieve data
            Data = rs.GetRows() ' Get all data from recordset

            ' Calculate Rows and Columns
            Rows = UBound(Data, 2) + 1
            Cols = UBound(Data, 1) + 1

            ' Resize the result array
            ReDim Res(1 To Rows, 1 To Cols)

            ' Fill the result array with data
            For j = 1 To Rows
                For i = 1 To Cols
                    Res(j, i) = GetValue(Data(i - 1, j - 1)) ' Get data value
                Next i
            Next j

            ' Assign the result to the output variable
            LoadDataFromGoogleSheets = Res
        Else
            LoadDataFromGoogleSheets = Array() ' Return empty array if no data
        End If
    Else
        LoadDataFromGoogleSheets = Array() ' Return empty array if rs is Nothing
    End If
End Function

Cơ bản là vậy còn tuỳ chỉnh phụ thuộc ai đó nếu ko thích thì viết kiểu khác = Tuỳ

Hàm GoogleSheetAsRecordset trả về các phương thức thuộc tính của ADODB trên Excel ...
sử dụng lấy dữ liệu còn không chèn dữ liệu


sau Khi gõ cái cộp sẻ ra như hình sau .. APIKey đã xoá ... ai đó tự làm lấy

1726307727482.png
 
Copy Code sau vào File bài Số 1 xong gõ hàm trên Sheet theo các tham số xong Enter cái Cộp ... dữ liệu Google Sheet nó bay về Excel
Mã:
Declare PtrSafe Function GoogleSheetAsRecordset Lib "GoogleSheets64.dll" _
            (ByRef SheetId As Variant, _
             ByRef APIKey As Variant, _
             ByRef SheetName As Variant) As Variant
          
Function GetValue(value As Variant) As Variant
    If IsNull(value) Then
        GetValue = ""
    ElseIf IsNumeric(value) Then
        If Len(value) > 12 Then
            GetValue = Format(value, "#,##0.00")
        Else
            GetValue = Format(value, "#,##0")
        End If
    ElseIf IsDate(value) Then
        GetValue = Format(value, "dd/mm/yyyy")
    ElseIf Len(value) = 10 And IsNumeric(value) Then
        GetValue = Format(value, "####-###-###")
    Else
        GetValue = value
    End If
End Function

Function LoadDataFromGoogleSheets(SheetId As String, APIKey As String, SheetName As String) As Variant
    Dim Data As Variant
    Dim Res() As Variant
    Dim i As Long, j As Long
    Dim Rows As Long, Cols As Long
    Dim rs As Object

    ' Get the recordset from Google Sheets
    Set rs = GoogleSheetAsRecordset(SheetId, APIKey, SheetName)

    If Not rs Is Nothing Then
        If Not rs.EOF Then
            ' Retrieve data
            Data = rs.GetRows() ' Get all data from recordset

            ' Calculate Rows and Columns
            Rows = UBound(Data, 2) + 1
            Cols = UBound(Data, 1) + 1

            ' Resize the result array
            ReDim Res(1 To Rows, 1 To Cols)

            ' Fill the result array with data
            For j = 1 To Rows
                For i = 1 To Cols
                    Res(j, i) = GetValue(Data(i - 1, j - 1)) ' Get data value
                Next i
            Next j

            ' Assign the result to the output variable
            LoadDataFromGoogleSheets = Res
        Else
            LoadDataFromGoogleSheets = Array() ' Return empty array if no data
        End If
    Else
        LoadDataFromGoogleSheets = Array() ' Return empty array if rs is Nothing
    End If
End Function

Cơ bản là vậy còn tuỳ chỉnh phụ thuộc ai đó nếu ko thích thì viết kiểu khác = Tuỳ

Hàm GoogleSheetAsRecordset trả về các phương thức thuộc tính của ADODB trên Excel ...
sử dụng lấy dữ liệu còn không chèn dữ liệu


sau Khi gõ cái cộp sẻ ra như hình sau .. APIKey đã xoá ... ai đó tự làm lấy

View attachment 303970
Cái API key của Google Sheets API chỉ có tác dụng với những endpoint dùng phương thức (method) GET, chứ để mà chỉnh sửa được spreadsheet thì cần phải dùng đến xác thực OAuth 2.0 để Google biết ai đang tương tác với spreadsheet, chưa kể cần phải chia sẻ spreadsheet công khai nữa.
Mà nhìn chung, nếu dùng để truy xuất dữ liệu từ spreadsheet thì mình thấy cũng ok.
1726498975514.png
 
Cái API key của Google Sheets API chỉ có tác dụng với những endpoint dùng phương thức (method) GET, chứ để mà chỉnh sửa được spreadsheet thì cần phải dùng đến xác thực OAuth 2.0 để Google biết ai đang tương tác với spreadsheet, chưa kể cần phải chia sẻ spreadsheet công khai nữa.
Mà nhìn chung, nếu dùng để truy xuất dữ liệu từ spreadsheet thì mình thấy cũng ok.
View attachment 304002
Việc lấy dữ liệu Từ Google Sheet về Excel nó quá đơn giản luôn.. có APIkey không không có lấy ok sạch .. miễn là chia Sẻ Google Sheet

Việc lấy theo APIkey nó an toàn hơn thôi vvv...

Như bài số 29 mục đích tôi viết hàm trả về ADODB Recordset với các phương thức, thuộc tính của ADODB cho người dùng tuỳ biến nhiều hơn trên VBA

Với lại chưa thấy ai viết hay Tôi chưa biết ... Nên viết theo cách khác chút không trùng lặp của ai đó và không cần thiết mua Component của bên thứ 3


1/ Hàm trả về khi ta sử dụng
Mã:
 ' Call the Delphi function
    Set rs = GoogleSheetAsRecordset(SheetId, APIKey, SheetName)
   
    ' S? d?ng rs nhu Recordset
    Do While Not rs.EOF
        Debug.Print rs.Fields(1).value ''1 là cot 2
        rs.MoveNext
    Loop

2/ Hàm trả về khi ta sử dụng
Mã:
    Set rs = GoogleSheetAsRecordset(SheetId, APIKey, SheetName)
   
    Cells.ClearContents
    ' Paste the data into the worksheet
    Set ws = ThisWorkbook.Sheets("Sheet1")  ' Change to your target sheet
    ws.Range("A1").CopyFromRecordset rs
   
    ' Cleanup
    rs.Close
    Set rs = Nothing

3/ Hàm trả về khi ta sử dụng

Mã:
' Call the Delphi function
    Set rs = GoogleSheetAsRecordset(SheetId, APIKey, SheetName)
   
    Cells.ClearContents
    ' Paste the data into the worksheet
    Set ws = ThisWorkbook.Sheets("Sheet1")  ' Change to your target sheet

    ' Get all data from the recordset
    Data = rs.GetRows()

    ' Paste data, skipping the first row (header)
    For i = LBound(Data, 2) + 1 To UBound(Data, 2) ' Start from the second row
        ws.Range("A" & (i + 1)).Resize(1, UBound(Data, 1) + 1).value = Application.Index(Data, 0, i)
    Next i

    ' Cleanup
    rs.Close
    Set rs = Nothing

đại ý là hàm trả về các phương thức, thuộc tính của ADODB khi ta khai báo ADODB trên VBA trả về Recordset


còn cách bạn viết trực tiếp trên Google Sheet thì tôi lại không dùng mà sẻ áp dụng cách liên kết máy chủ Web Server của tôi ...dự án đang dò
 
Không cần Google Sheets API, không cần OAuth, không cần chia sẻ tập tin Google Sheets
VẪN
đồng bộ
thời gian thực ngon lành.
Chứ chỉ đẩy dữ liệu một chiều thì chưa ăn thua gì.
 
Không cần Google Sheets API, không cần OAuth, không cần chia sẻ tập tin Google Sheets
VẪN
đồng bộ
thời gian thực ngon lành.
Chứ chỉ đẩy dữ liệu một chiều thì chưa ăn thua gì.
Thong thả ta chơi cho vui như chơi game thôi ... biết hết và nhanh quá mai mốt hết trò chơi :p
 
Việc lấy dữ liệu Từ Google Sheet về Excel nó quá đơn giản luôn.. có APIkey không không có lấy ok sạch .. miễn là chia Sẻ Google Sheet

Việc lấy theo APIkey nó an toàn hơn thôi vvv...

Như bài số 29 mục đích tôi viết hàm trả về ADODB Recordset với các phương thức, thuộc tính của ADODB cho người dùng tuỳ biến nhiều hơn trên VBA

Với lại chưa thấy ai viết hay Tôi chưa biết ... Nên viết theo cách khác chút không trùng lặp của ai đó và không cần thiết mua Component của bên thứ 3


1/ Hàm trả về khi ta sử dụng
Mã:
 ' Call the Delphi function
    Set rs = GoogleSheetAsRecordset(SheetId, APIKey, SheetName)
 
    ' S? d?ng rs nhu Recordset
    Do While Not rs.EOF
        Debug.Print rs.Fields(1).value ''1 là cot 2
        rs.MoveNext
    Loop

2/ Hàm trả về khi ta sử dụng
Mã:
    Set rs = GoogleSheetAsRecordset(SheetId, APIKey, SheetName)
 
    Cells.ClearContents
    ' Paste the data into the worksheet
    Set ws = ThisWorkbook.Sheets("Sheet1")  ' Change to your target sheet
    ws.Range("A1").CopyFromRecordset rs
 
    ' Cleanup
    rs.Close
    Set rs = Nothing

3/ Hàm trả về khi ta sử dụng

Mã:
' Call the Delphi function
    Set rs = GoogleSheetAsRecordset(SheetId, APIKey, SheetName)
 
    Cells.ClearContents
    ' Paste the data into the worksheet
    Set ws = ThisWorkbook.Sheets("Sheet1")  ' Change to your target sheet

    ' Get all data from the recordset
    Data = rs.GetRows()

    ' Paste data, skipping the first row (header)
    For i = LBound(Data, 2) + 1 To UBound(Data, 2) ' Start from the second row
        ws.Range("A" & (i + 1)).Resize(1, UBound(Data, 1) + 1).value = Application.Index(Data, 0, i)
    Next i

    ' Cleanup
    rs.Close
    Set rs = Nothing

đại ý là hàm trả về các phương thức, thuộc tính của ADODB khi ta khai báo ADODB trên VBA trả về Recordset


còn cách bạn viết trực tiếp trên Google Sheet thì tôi lại không dùng mà sẻ áp dụng cách liên kết máy chủ Web Server của tôi ...dự án đang dò

Hình như bác đã tư duy sai vấn đề. Bác đang dùng link google đã exoort ra csv hay json gì đó đây chỉ còn là link ldownload thông thường như bao thứ khác trên mạng. Đó chính là vì sao link bác yêu cầu phải share quyền cho everyone và cái apikey kia chỉ là hình thức.

Vậy là trong dll của bác không phải làm việc với google sheets. Khi nào bác nhận được dữ liệu từ một spreadsheetId với địa chỉ vùng dữ liệu bất ký, link được share với quyền giới hạn tuỳ vào user thì mới gọi là là lấy dữ liệu từ google sheets.
 
Hình như bác đã tư duy sai vấn đề. Bác đang dùng link google đã exoort ra csv hay json gì đó đây chỉ còn là link ldownload thông thường như bao thứ khác trên mạng. Đó chính là vì sao link bác yêu cầu phải share quyền cho everyone và cái apikey kia chỉ là hình thức.

Vậy là trong dll của bác không phải làm việc với google sheets. Khi nào bác nhận được dữ liệu từ một spreadsheetId với địa chỉ vùng dữ liệu bất ký, link được share với quyền giới hạn tuỳ vào user thì mới gọi là là lấy dữ liệu từ google sheets.
có thể nhầm lẫn gì chăng mà tôi chưa hình dung ra

Nhưng Tôi đang lấy dữ liệu Google Sheet về Excel Với APIkey SheetID là chính xác tuyệt đối không sai được

còn keo nó là chi Tôi cũng không quan tâm lắm :p .. còn APIkey tôi lấy theo mục khoanh màu đỏ vì thấy nó keo là APIkey ... còn tây keo là chi kệ nó

Tôi keo theo cách của tôi và biết sử dụng là OK

1726541982988.png

á ........... đoán thôi .. nghi ngờ tôi tải File Google Sheet về máy tính xong sử dụng ADODB mới trả về phương thức , thuộc tính Rs

nếu vậy thì lại nhầm lẫn gì chăng --=0_)()(-
 
Lần chỉnh sửa cuối:
Copy Code sau vào File Bài số 1 lấy SheetId khi truyền Tham số URL của Google Sheet vào hàm + APIKeys bài trên là ok xong

Mã:
Declare PtrSafe Function ExtractSheetIdFromURL Lib "GoogleSheets64.dll" _
            (ByRef URL As Variant) As Variant

          
Sub Test_ExtractSheetIdFromURL()
    Dim URL As String, SheetId As String
    URL = "https://docs.google.com/spreadsheets/d/1-0nB16Fefr8cTbEV7Gj5VjcegL5GcfMIc4RP5C9Sn4w/edit?gid=553666518#gid=553666518"
    SheetId = ExtractSheetIdFromURL(URL)
    Debug.Print SheetId
End Sub
 
Lấy dữ liệu JSON của Google Sheet thì chỉ càn dùng HTTP Get thông thường với cái Sheet ID là được rồi mà ta…Lấy sheet nào thì khai báo sheet đó thôi.
Cách này chỉ là lấy dữ liệu chứ không Insert, Update, Delete gì được nhé. Muốn chỉnh sửa thì dùng Google Sheet API (đang test).
 
Lần chỉnh sửa cuối:
Lấy dữ liệu JSON của Google Sheet thì chỉ càn dùng HTTP Get thông thường với cái Sheet ID là được rồi mà ta…Lấy sheet nào thì khai báo sheet đó thôi.
Cách này chỉ là lấy dữ liệu chứ không Insert, Update, Delete gì được nhé. Muốn chỉnh sửa thì dùng Google Sheet API (đang test).

Một điều em quan tâm là spreadsheet chia sẻ không phải everyone, và ấy địa chỉ như sheet “ban hàng” vùng A10:H1000 thì thế nào?
 
Nếu sử dụng JSON thì liên quan cái hàm chuyển JSON trên VBA của tây có khoãng trên 1000 dòng code ... dẹp nó đi cho gọn

chuyển qua CSV chỉ vài dòng code

Mượn link của Hướng GPE thử code thay thế hàm SendHttpRequest ... là hàm chi của ai đó tuỳ thích

Mã:
Sub GetDataFromGoogleSheet_CSV2()
    Dim csvData As String
    Dim lines As Variant
    Dim line As Variant
    Dim values As Variant
    Dim cleanedValue As String
    Dim I As Long
    Dim J As Long

    ' Gi? s? csvData ch?a d? li?u CSV t? hàm SendHttpRequest
    csvData = SendHttpRequest("GET", "https://docs.google.com/spreadsheets/d/1-0nB16Fefr8cTbEV7Gj5VjcegL5GcfMIc4RP5C9Sn4w/gviz/tq?tqx=out:csv", "text/csv", "text/csv", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0", Null)
    Debug.Print csvData

    ' Tách d? li?u thành t?ng dòng
    lines = Split(csvData, vbLf)
   
    Cells.ClearContents

    ' Duy?t t?ng dòng d? l?y giá tr?
    For I = LBound(lines) To UBound(lines)
        ' Tách t?ng dòng thành các giá tr?
        values = Split(lines(I), ",")

        ' Luu giá tr? vào b?ng tính (thay Sheet1 b?ng tên c?a trang tính c?a b?n)
        For J = LBound(values) To UBound(values)
            ' Lo?i b? các d?u "" th?a
            cleanedValue = Replace(values(J), """", "")
            Sheets("Sheet2").Cells(I + 1, J + 1).Value = Trim(cleanedValue)
        Next J
    Next I

    'MsgBox "D? li?u dã du?c luu vào b?ng tính!"
End Sub
 
Nếu dùng API của Google thì có hết từ lâu lắm rồi mà.

Còn dùng OAuth thì phải hết sức cẩn thận với đám mây, cái này phải có ràng buộc trách nhiệm nghiêm ngặt, và không ai làm như ai đó (có một nhược điểm chí mạng và buồn cười). Lần này thì mặc kệ nó. =]]]

Mà hài nhất là khúc đẩy dữ liệu phải chọn Range trước. :D
 
Web KT

Bài viết mới nhất

Back
Top Bottom