Lấy tỷ giá VCB về file excel

Liên hệ QC

AnhNQT

Thành viên chính thức
Tham gia
6/11/18
Bài viết
61
Được thích
5
Giới tính
Nam
Xin chào các Bác GPE,
Em cần giúp để lấy tỷ giá VCB về excel theo một vài mã cần và theo ngày ạ. Nếu được thì ngày nào cũng tự lấy về thì càng tốt ạ.
Em cảm ơn!
 

File đính kèm

  • Lay ty gia VCB.xlsm
    10.4 KB · Đọc: 42
Upvote 0
Lý ra bạn nên viết rõ là:
Kết quả lấy dữ liệu từ web về là một Table chuẩn chỉ, vậy nên muốn làm gì cũng được.
Nếu url trả về Table thì đơn giản, nếu trả về html không vẫn conver thành bảng được, mấy cái web có sử dụng token dùng power query vẫn xử lý được vì nó cho phép nhập header, power query trên BI thì xịn xò hơn nó tự conver json và htlm thành bảng luôn
Join hiểu theo SQL là tạo relation và join, trong Power query gọi là merge và có thể merge nhiều table với nhau miễn là có trường Key (nguồn từ web hay bất kỳ đâu cũng được).
Groupby thì Power query làm được từ bất kỳ nguồn nào, cứ lấy về rồi thêm step groupby
Các tính năng tôi kể ở trên cũng vậy, hễ lấy được về rồi là làm được hết
Nói thêm: Nếu trang web có nhiều page(s), mỗi page là 1 table theo ngày (hoặc theo bất kỳ tiêu chí nào), có thể dùng vòng lặp ngay trong hàm M để lấy về và union (combine) lại với nhau
Chưa kể nó cho phép lưu data ngoài bảng tính hay trên Ram, lưu trên Ram thì data cho thể cả trăm triệu dòng, dùng power pivot nâng cao trả kết quả động (power pivot và power Bi nó sử dụng cùng công nghệ với mấy thằng SAP đời mới bây giờ), từ cái kết quả động đó có thể tạo hơn 100 cái report khác nhau với tốc độ vài s, nếu ví VBA là ngôn ngữ bậc thấp thì M code là ngôn ngữ bậc cao , có thể tốc độ một số trường hợp không bằng VBA nhưng về query connect, ETL, tính toán, report, visualize ... thì VBA không so được, nó là anh em với power BI nhưng nó miễn phí, có thể nói power query+power pivot trong excel là tool BI miễn phí tốt nhất, cái connect của power query hiện nay chắc hơn 140 source rồi như file, Oracle, Sql, mySQL, postgresql, odbc, cloud, web...chỉ riêng việc connect SQL trong power query với ADO trong vba cũng có khác biệt rồi, ADO chỉ connect các câu query select, còn trong power query cho phép code thuần như tạo bảng tạm, loop rồi lấy kết quả sau cùng thôi
 
Upvote 0
Đúng như tôi xem qua câu hỏi ban đầu. Để đơn giản bạn dùng phương pháp QueryTable mà tôi đã gửi link youtube hướng dẫn. Dùng nguyên kiến thức đó, kết hợp với code thêm về vòng lặp để so sánh là ra. File đính kém là toàn bộ mã nguồn.

lay_ty_gia.gif
Mã nguồn:
Mã:
Option Explicit

'Kien thuc code trong file nay ban xem link: https://www.youtube.com/watch?v=OSfcpLGVLOk

Sub LayTyGia()
    Range("J6:L6").Value = "Waiting..."
    Range("J6:L6").Value = LayTyGiaTheoNgay(Range("J2").Value, Range("J3").Value)
End Sub

Function LayTyGiaTheoNgay(dNgay As Date, strNgoaiTe As String)
    Dim qry As QueryTable, rng As Range, I As Long, arrRes(1 To 3)
    LayTableTuWeb dNgay
    Set qry = ThisWorkbook.Sheets("webdata").QueryTables(1)
    Set rng = qry.ResultRange
    For I = 3 To rng.Rows.Count
        If StrComp(rng.Rows(I).Cells(, 2).Value, strNgoaiTe, vbTextCompare) = 0 Then
            arrRes(1) = rng.Rows(I).Cells(, 3).Value
            arrRes(2) = rng.Rows(I).Cells(, 4).Value
            arrRes(3) = rng.Rows(I).Cells(, 5).Value
            Exit For
        End If
    Next
    LayTyGiaTheoNgay = arrRes
End Function

Sub LayTableTuWeb(ByVal dNgay As Date)
    Dim qry As QueryTable
    Dim sh As Worksheet
    Dim CnnStr As String
    
    Set sh = ThisWorkbook.Sheets("webdata")
    'Xoa querytable truoc do
    XoaQT sh
    
    CnnStr = "URL;https://portal.vietcombank.com.vn/UserControls/TVPortal.TyGia/pListTyGia.aspx?txttungay=" & Format(dNgay, "dd/mm/yyyy")
    Set qry = sh.QueryTables.Add(CnnStr, sh.Range("A1"))
    'Query
    qry.WebSelectionType = xlSpecifiedTables
    qry.WebFormatting = xlWebFormattingNone
    qry.WebTables = """ctl00_Content_ExrateView""" 'hoan nhieu hon mot table
    qry.Refresh False 'Load du lieu
End Sub

Sub XoaQT(sh As Worksheet)
    Dim qry As QueryTable
    On Error Resume Next 'Bo qua loi
    For Each qry In sh.QueryTables
        qry.ResultRange.ClearContents 'Xoa data trong vung table
        qry.Delete 'Xoa QueryTable
    Next
End Sub
 

File đính kèm

  • Lay ty gia VCB.xlsm
    29.7 KB · Đọc: 44
Upvote 0
Đúng như tôi xem qua câu hỏi ban đầu. Để đơn giản bạn dùng phương pháp QueryTable mà tôi đã gửi link youtube hướng dẫn. Dùng nguyên kiến thức đó, kết hợp với code thêm về vòng lặp để so sánh là ra. File đính kém là toàn bộ mã nguồn.

Mã nguồn:
Mã:
Option Explicit

'Kien thuc code trong file nay ban xem link: https://www.youtube.com/watch?v=OSfcpLGVLOk

Sub LayTyGia()
    Range("J6:L6").Value = "Waiting..."
    Range("J6:L6").Value = LayTyGiaTheoNgay(Range("J2").Value, Range("J3").Value)
End Sub

Function LayTyGiaTheoNgay(dNgay As Date, strNgoaiTe As String)
    Dim qry As QueryTable, rng As Range, I As Long, arrRes(1 To 3)
    LayTableTuWeb dNgay
    Set qry = ThisWorkbook.Sheets("webdata").QueryTables(1)
    Set rng = qry.ResultRange
    For I = 3 To rng.Rows.Count
        If StrComp(rng.Rows(I).Cells(, 2).Value, strNgoaiTe, vbTextCompare) = 0 Then
            arrRes(1) = rng.Rows(I).Cells(, 3).Value
            arrRes(2) = rng.Rows(I).Cells(, 4).Value
            arrRes(3) = rng.Rows(I).Cells(, 5).Value
            Exit For
        End If
    Next
    LayTyGiaTheoNgay = arrRes
End Function

Sub LayTableTuWeb(ByVal dNgay As Date)
    Dim qry As QueryTable
    Dim sh As Worksheet
    Dim CnnStr As String
   
    Set sh = ThisWorkbook.Sheets("webdata")
    'Xoa querytable truoc do
    XoaQT sh
   
    CnnStr = "URL;https://portal.vietcombank.com.vn/UserControls/TVPortal.TyGia/pListTyGia.aspx?txttungay=" & Format(dNgay, "dd/mm/yyyy")
    Set qry = sh.QueryTables.Add(CnnStr, sh.Range("A1"))
    'Query
    qry.WebSelectionType = xlSpecifiedTables
    qry.WebFormatting = xlWebFormattingNone
    qry.WebTables = """ctl00_Content_ExrateView""" 'hoan nhieu hon mot table
    qry.Refresh False 'Load du lieu
End Sub

Sub XoaQT(sh As Worksheet)
    Dim qry As QueryTable
    On Error Resume Next 'Bo qua loi
    For Each qry In sh.QueryTables
        qry.ResultRange.ClearContents 'Xoa data trong vung table
        qry.Delete 'Xoa QueryTable
    Next
End Sub
Đúng là 1 bài toán có nhiều cách giải. Quan trọng người dùng cảm thấy happy với phương án nào.
 
Upvote 0
Nếu url trả về Table thì đơn giản, nếu trả về html không vẫn conver thành bảng được, mấy cái web có sử dụng token dùng power query vẫn xử lý được vì nó cho phép nhập header, power query trên BI thì xịn xò hơn nó tự conver json và htlm thành bảng luôn
Mình cũng có nêu ở bài #33 rồi đó.
 
Upvote 0
Cái query from web chỉ đơn giản là lấy dữ liệu từ một url về, và chỉ thế mà thôi. Mỗi lần thực hiện là phải tạo ra một query mới.
Chẳng có lý do gì để so sánh nó với Power Query cả, bởi nó chỉ là 1 chức năng.

Còn Power Query là một bộ công cụ/ thư viện hoàn chỉnh được tích hợp vào Excel, nó có môi trường viết mã lệnh (M code), cho phép thực hiện mã lệnh (tương tự như môi trường VBA).
Ngay cái phần web scraping có hẳn thư viện Web siêu hịn.
Chưa kể kết hợp với Html.Table, Json cho phép xử lý dữ liệu trả về ngon lành cành đào.

View attachment 264062
Nếu có điều kiện, mong anh chia sẻ những cái siêu hịn này ở 1 Topic mới, để anh/em GPE học hỏi.
Cảm ơn anh !!!
 
Upvote 0
Xin chào các Bác GPE,
Em cần giúp để lấy tỷ giá VCB về excel theo một vài mã cần và theo ngày ạ. Nếu được thì ngày nào cũng tự lấy về thì càng tốt ạ.
Em cảm ơn!
Một đoạn code mình thấy trên diễn đàn từ năm 2015 vẫn còn chạy được.

Option Explicit

Private Sub tygia_Click()
Dim objWeb As QueryTable
Dim sWebTable As String
'Trong ma html cua site nay ty gia duoc luu trong table thu 1
sWebTable = 1
Set objWeb = ActiveSheet.QueryTables.Add( _
Connection:="URL;http://www.vietcombank.com.vn/ExchangRates/", _
Destination:=Range("A1"))
With objWeb
.WebSelectionType = xlSpecifiedTables
.WebTables = sWebTable
.Refresh BackgroundQuery:=False
.SaveData = True
End With
Set objWeb = Nothing
End Sub

Hoặc thay = Url của befaint
https://portal.vietcombank.com.vn/U...spx?txttungay=11/08/2021&BacrhID=1&isEn=False
 
Lần chỉnh sửa cuối:
Upvote 0
Bây giờ làm cách nào để có 1 bảng với tất cả các tỷ giá trong 1 khoảng thời gian (ví dụ của tháng 7 từ 1-7-2021 đến 31-7-2021) mà không phải nhập từng ngày một vào B4 các bác nhỉ? Em nghĩ tới vòng lặp FOR nhưng mà không biết cách làm. Nhờ các thầy/ các tiền bối hướng dẫn
 
Upvote 0
Bây giờ làm cách nào để có 1 bảng với tất cả các tỷ giá trong 1 khoảng thời gian (ví dụ của tháng 7 từ 1-7-2021 đến 31-7-2021) mà không phải nhập từng ngày một vào B4 các bác nhỉ? Em nghĩ tới vòng lặp FOR nhưng mà không biết cách làm. Nhờ các thầy/ các tiền bối hướng dẫn
Quan trọng là trên web nó không có option để chọn từ ngày đến ngày. Chứ a nghĩ là lấy được @hoangminhtien
 
Upvote 0
Bây giờ làm cách nào để có 1 bảng với tất cả các tỷ giá trong 1 khoảng thời gian (ví dụ của tháng 7 từ 1-7-2021 đến 31-7-2021) mà không phải nhập từng ngày một vào B4 các bác nhỉ? Em nghĩ tới vòng lặp FOR nhưng mà không biết cách làm. Nhờ các thầy/ các tiền bối hướng dẫn
1. Viết 1 hàm UnionQuery: Union 2 query truyền vào (Query1, Query2)
2. Viết 1 hàm Query1 lấy kết quả theo 1 ngày truyền vào
3. Thủ tục chính: Dùng 1 vòng lặp theo i từ ngày đầu đến ngày cuối:
Nếu i = ngày đầu, Kq = query dữ liệu web của ngày đầu = Query1(ngày đầu)
Ngược lại (i > ngày đầu), lấy Kqi = query dữ liệu web của ngày i, dùng hàm UnionQuery union Kqi với Kq của (i-1):
 
Lần chỉnh sửa cuối:
Upvote 0
Quan trọng là trên web nó không có option để chọn từ ngày đến ngày. Chứ a nghĩ là lấy được @hoangminhtien
Dùng cách cơ bản thôi cũng được
PHP:
Sub Query1()
    Dim qry As QueryTable, StartDate As Date, EndDate As Date
    Dim CnnStr As String, iDate As Date, sh As Worksheet
    Dim NextRw As Long, NewLastRw As Long
    Set sh = Sheet2
    For I = sh.QueryTables.Count To 1 Step -1
        sh.QueryTables(I).Delete
    Next
    StartDate = sh.[B2]: EndDate = sh.[D2]
    Application.DisplayAlerts = False
    Application.ScreenUpdating = False
    sh.Range("A4:F10000").ClearContents
    For iDate = StartDate To EndDate
        CnnStr = "URL;https://portal.vietcombank.com.vn/UserControls/TVPortal.TyGia/pListTyGia.aspx?txttungay=" & _
        Format(iDate, "dd/mm/yyyy")
        NextRw = sh.Range("B10000").End(xlUp).Row + 1
        Set qry = sh.QueryTables.Add(CnnStr, sh.Cells(NextRw, 2))
    With qry
        .WebSelectionType = xlSpecifiedTables
        .WebTables = """ctl00_Content_ExrateView"""
        .Refresh False
        .Refresh BackgroundQuery:=False
        .SaveData = True
    End With
        NewLastRw = sh.Range("B10000").End(xlUp).Row
        sh.Range(Cells(NextRw, 1), Cells(NewLastRw, 1)).Value = iDate
    Next
    Application.DisplayAlerts = True
        sh.Range("A3:F" & NewLastRw).AutoFilter Field:=4, Criteria1:="=Mua", _
        Operator:=xlOr, Criteria2:="=Ti" & ChrW(7873) & "n m" & ChrW(7863) & "t"
        Rows("4:" & NewLastRw).Delete Shift:=xlUp
        sh.ShowAllData
    Application.ScreenUpdating = True
    Set qry = Nothing
    Set sh = Nothing
End Sub
 
Upvote 0
Cách khác: Dùng vòng lặp trong Power Query
PHP:
let
    WebAddress = Excel.CurrentWorkbook(){[Name="WebAdd"]}[Content]{0}[Column1] ,
    DateFrom = Number.From(Excel.CurrentWorkbook(){[Name="DFrom"]}[Content]{0}[Column1]) ,
    DateTo = Number.From(Excel.CurrentWorkbook(){[Name="DTo"]}[Content]{0}[Column1]) ,
    DaysNo = {0..DateTo - DateFrom},
    abc=Date.ToText(Date.From(DaysNo{0}+DateFrom),"dd/MM/yyyy"),
    DataW = List.Transform(DaysNo, (wd) =>  
    let
        Datewd=DaysNo{wd}+DateFrom,
        Source = Web.Page(Web.Contents(WebAddress & Date.ToText(Date.From(Datewd),"dd/MM/yyyy"))),
        Data0 = Source{0}[Data],
        RenamedColumns = Table.RenameColumns(Data0,{{"Ngoại tệ Tên ngoại tệ", "Tên Ngoại tệ"}, {"Ngoại tệ Mã NT", "Mã ngoại tệ"}}),
        RemoveRows = Table.Skip(RenamedColumns,2),
        ReplaceValue = Table.ReplaceValue(RemoveRows,"-","0",Replacer.ReplaceText,{"Mua Tiền mặt"}),
        ChangeType = Table.TransformColumnTypes(ReplaceValue,{{"Mua Tiền mặt", type number}, {"Mua Chuyển khoản", type number}, 
              {"Bán", type number}}),
        AddDate = Table.AddColumn(ChangeType, "Date", each Date.From(Datewd), Date.Type)
    in AddDate),
    List2 =Table.FromList(DataW,Splitter.SplitByNothing()),
    ListColumns2 = Table.ColumnNames(DataW{0}),
    KetQua = Table.ReorderColumns(Table.ExpandTableColumn(List2, "Column1", ListColumns2),
          {"Date", "Tên Ngoại tệ", "Mã ngoại tệ", "Mua Tiền mặt", "Mua Chuyển khoản", "Bán"})
 
in
    KetQua

Chọn từ ngày đến ngày và refresh

1629428757754.png
 

File đính kèm

  • TyGiaVCB-FromTo.xlsx
    25.1 KB · Đọc: 50
Upvote 0
Cách khác: Dùng vòng lặp trong Power Query
PHP:
let
    WebAddress = Excel.CurrentWorkbook(){[Name="WebAdd"]}[Content]{0}[Column1] ,
    DateFrom = Number.From(Excel.CurrentWorkbook(){[Name="DFrom"]}[Content]{0}[Column1]) ,
    DateTo = Number.From(Excel.CurrentWorkbook(){[Name="DTo"]}[Content]{0}[Column1]) ,
    DaysNo = {0..DateTo - DateFrom},
    abc=Date.ToText(Date.From(DaysNo{0}+DateFrom),"dd/MM/yyyy"),
    DataW = List.Transform(DaysNo, (wd) => 
    let
        Datewd=DaysNo{wd}+DateFrom,
        Source = Web.Page(Web.Contents(WebAddress & Date.ToText(Date.From(Datewd),"dd/MM/yyyy"))),
        Data0 = Source{0}[Data],
        RenamedColumns = Table.RenameColumns(Data0,{{"Ngoại tệ Tên ngoại tệ", "Tên Ngoại tệ"}, {"Ngoại tệ Mã NT", "Mã ngoại tệ"}}),
        RemoveRows = Table.Skip(RenamedColumns,2),
        ReplaceValue = Table.ReplaceValue(RemoveRows,"-","0",Replacer.ReplaceText,{"Mua Tiền mặt"}),
        ChangeType = Table.TransformColumnTypes(ReplaceValue,{{"Mua Tiền mặt", type number}, {"Mua Chuyển khoản", type number},
              {"Bán", type number}}),
        AddDate = Table.AddColumn(ChangeType, "Date", each Date.From(Datewd), Date.Type)
    in AddDate),
    List2 =Table.FromList(DataW,Splitter.SplitByNothing()),
    ListColumns2 = Table.ColumnNames(DataW{0}),
    KetQua = Table.ReorderColumns(Table.ExpandTableColumn(List2, "Column1", ListColumns2),
          {"Date", "Tên Ngoại tệ", "Mã ngoại tệ", "Mua Tiền mặt", "Mua Chuyển khoản", "Bán"})
 
in
    KetQua

Chọn từ ngày đến ngày và refresh

View attachment 264396
Power Query đúng là công lực thượng thừa.
Rất tuyệt vời, đúng ý của @hoangminhtien kìa.
 
Upvote 0
Em thử một giải pháp khác,
Khởi tạo 1 Parameter theo ngày, sử dụng chức năng Invoke Custom Function.
Ở Sheet Note có thể chọn bất kỳ ngày nào muốn lấy tỷ giá. Sau khi chọn ngày, sang Sheet CaNguF1 và Refresh.
Nếu muốn lấy thêm ngày thì nhập tiếp vào dòng cuối cùng.
 

File đính kèm

  • TyGiaVCB-FromTo_Tuychon.xlsx
    36.3 KB · Đọc: 31
Lần chỉnh sửa cuối:
Upvote 0
Cách khác: Dùng vòng lặp trong Power Query
PHP:
let
    WebAddress = Excel.CurrentWorkbook(){[Name="WebAdd"]}[Content]{0}[Column1] ,
    DateFrom = Number.From(Excel.CurrentWorkbook(){[Name="DFrom"]}[Content]{0}[Column1]) ,
    DateTo = Number.From(Excel.CurrentWorkbook(){[Name="DTo"]}[Content]{0}[Column1]) ,
    DaysNo = {0..DateTo - DateFrom},
    abc=Date.ToText(Date.From(DaysNo{0}+DateFrom),"dd/MM/yyyy"),
    DataW = List.Transform(DaysNo, (wd) => 
    let
        Datewd=DaysNo{wd}+DateFrom,
        Source = Web.Page(Web.Contents(WebAddress & Date.ToText(Date.From(Datewd),"dd/MM/yyyy"))),
        Data0 = Source{0}[Data],
        RenamedColumns = Table.RenameColumns(Data0,{{"Ngoại tệ Tên ngoại tệ", "Tên Ngoại tệ"}, {"Ngoại tệ Mã NT", "Mã ngoại tệ"}}),
        RemoveRows = Table.Skip(RenamedColumns,2),
        ReplaceValue = Table.ReplaceValue(RemoveRows,"-","0",Replacer.ReplaceText,{"Mua Tiền mặt"}),
        ChangeType = Table.TransformColumnTypes(ReplaceValue,{{"Mua Tiền mặt", type number}, {"Mua Chuyển khoản", type number},
              {"Bán", type number}}),
        AddDate = Table.AddColumn(ChangeType, "Date", each Date.From(Datewd), Date.Type)
    in AddDate),
    List2 =Table.FromList(DataW,Splitter.SplitByNothing()),
    ListColumns2 = Table.ColumnNames(DataW{0}),
    KetQua = Table.ReorderColumns(Table.ExpandTableColumn(List2, "Column1", ListColumns2),
          {"Date", "Tên Ngoại tệ", "Mã ngoại tệ", "Mua Tiền mặt", "Mua Chuyển khoản", "Bán"})
 
in
    KetQua

Chọn từ ngày đến ngày và refresh

View attachment 264396
Bác @ptm0412 ơi, em dùng được 1 thời gian đến hôm này bị lỗi này ạ, Bác sửa giúp em với được không?
1631759554986.png
 
Upvote 0
Upvote 0
Upvote 0
Mở trang VCB -> vô mục Tỷ Giá -> click phải chuột chọn "Inspect" và chọn các mục như hình sẽ thấy câu lệnh request.

View attachment 264026
Bác có lấy được tỷ giá của ngân hàng MB với BIDV không? Em làm theo bác mà không được. Em cảm ơn!
 
Upvote 0
Web KT
Back
Top Bottom