Tải hóa đơn điện tử (https://hoadondientu.gdt.gov.vn/) Excel Vba (18 người xem)

Người dùng đang xem chủ đề này

  • ongke0711

    Thành viên gắn bó
    Tham gia
    7/9/06
    Bài viết
    2,523
    Được thích
    3,473
    Giới tính
    Nam
    Chào các bạn,
    Tôi ngồi mò mẫm mấy ngày mới tìm được cách tải hóa đơn điện tử từ trang https://hoadondientu.gdt.gov.vn/. Cách này có thể không chuyên nghiệp nhưng cũng giải quyết được vấn đề tải hóa đơn hàng loạt từ trang trên và ghi xuống Excel theo định dạng dễ tổng hợp dữ liệu sau này.
    - Tốc độ không nhanh như các ứng dụng python siêu nhanh.
    - Chưa tìm được các link tải file .xml hoặc .html
    - Chưa trải nghiệm qua các định dạng hóa đơn điện tử của các nhà cung cấp giải pháp khác nhau nên sẽ không đảm bảo chạy đúng 100%.
    - Chưa biết cách tích hợp code vượt Captcha của (Python, C#..) vào VBA nên phải nhập Captcha thủ công.
    Nói chung cái tool cũng giải quyết được việc tải hóa đơn hàng loạt :D .
    Tôi sẽ upload file demo không khóa (có khóa cũng như không) sau vì code còn lộn xộn lắm. Các bạn xem qua và đóng góp cách xử lý tốt hơn, gọn hơn nhé.


    *** 12/10/2024: Cập nhật sửa một đống lỗi.
    *** 15/10/2024: Cập nhật sửa lỗi Null và nhập ngày tháng.
    *** 16/10/2024: Thêm tính năng lưu User/Pass.
    *** 20/10/2024: Sửa lỗi hiển thị ngày tháng, sửa và thêm một số code phụ trợ.
    *** 28/10/2024: Sửa lấy hóa đơn từ máy tính tiền.
    *** 07/11/2024: Sửa code trích xuất dữ liệu, thêm cột so sánh.
    *** 13/11/2024: Dùng code của bạn Hesanbi để tự động nhập Captcha. Thêm code lấy link tra cứu của VNPT và BKAV.
    *** 05/02/2025: Thêm code tải file Zip và trích xuất dữ liệu hóa đơn từ file XML. Sửa một số lỗi.
    *** 23/02/2025: Sửa lỗi hiển thị sai <Trạng thái hóa đơn>.
    *** 10/05/2026: Cập nhật do trang hoadondientu thay đổi thiết kế.
    *** 19/05/2026: Sửa lỗi hiển thị sai trạng thái hoá đơn.
     

    File đính kèm

    Lần chỉnh sửa cuối:
    1. Đăng nhập vào xong chọn kỳ 01/04/26 - 30/04/26, bấm tải Hdon, đợi load 1 hồi thông báo Xong, rồi hiện lên các bảng như hình 1 + 2
    2. Bấm tổng hợp hdon chi tiết XML chọn đường dẫn đã lưu hiện lỗi như hình 3
     

    File đính kèm

    • 1778480855718.png
      1778480855718.png
      113.4 KB · Đọc: 70
    • 1778480875940.png
      1778480875940.png
      116.4 KB · Đọc: 37
    • 1778480906758.png
      1778480906758.png
      28.4 KB · Đọc: 40
    Upvote 0
    Xin cảm ơn chú vì đã làm ra file này, cháu 2k3 mới ra trường rất biết ơn ạ :''"
     
    Upvote 0
    1. Đăng nhập vào xong chọn kỳ 01/04/26 - 30/04/26, bấm tải Hdon, đợi load 1 hồi thông báo Xong, rồi hiện lên các bảng như hình 1 + 2
    2. Bấm tổng hợp hdon chi tiết XML chọn đường dẫn đã lưu hiện lỗi như hình 3
    - Cái lỗi thư mục không có chứa file XML thì bạn vô File Explorer - View - Show - chọn Filename and extension nhe.
    - Do tôi chưa sửa đường dẫn web (url) để tải file XML/zip nên bị lỗi tải file ở trên.


    * Đã cập nhật file. Bạn vô bài #694 để tải lại nhé.
    Mới test tải về 493 file .zip nhưng báo lỗi gửi nhiều yêu cầu tới máy chủ quá. Do vậy các bạn chia nhỏ ngày ra tải nhé.

    Screenshot 2026-05-11 at 2.50.59 PM.png
     
    Lần chỉnh sửa cuối:
    Upvote 0
    Cái trang vnpt bạn tra cứu hoá đơn là trang nào? Tôi thấy có mấy cái link.
    À cái trang mà khách hàng sử dụng dịch vụ của Bưu chính viễn thông dạng: mst-tt78.invoice.vnpt.vn... nó ra cái mã captcha như bác gửi bên trên đó.
     
    Upvote 0
    Trang hóa đơn của NCC 0101162173 https://asiainvoice.vn/tra-cuu, hiện tại e thấy có 1 số bên bán phần mềm họ tra cứu được hóa đơn gốc, anh chị nào biết cách tra hóa đơn thủ công này không ạ?
     
    Upvote 0
    - Cái lỗi thư mục không có chứa file XML thì bạn vô File Explorer - View - Show - chọn Filename and extension nhe.
    - Do tôi chưa sửa đường dẫn web (url) để tải file XML/zip nên bị lỗi tải file ở trên.


    * Đã cập nhật file. Bạn vô bài #694 để tải lại nhé.
    Mới test tải về 493 file .zip nhưng báo lỗi gửi nhiều yêu cầu tới máy chủ quá. Do vậy các bạn chia nhỏ ngày ra tải nhé.

    Chào các bạn,
    Tôi ngồi mò mẫm mấy ngày mới tìm được cách tải hóa đơn điện tử từ trang https://hoadondientu.gdt.gov.vn/. Cách này có thể không chuyên nghiệp nhưng cũng giải quyết được vấn đề tải hóa đơn hàng loạt từ trang trên và ghi xuống Excel theo định dạng dễ tổng hợp dữ liệu sau này.
    - Tốc độ không nhanh như các ứng dụng python siêu nhanh.
    - Chưa tìm được các link tải file .xml hoặc .html
    - Chưa trải nghiệm qua các định dạng hóa đơn điện tử của các nhà cung cấp giải pháp khác nhau nên sẽ không đảm bảo chạy đúng 100%.
    - Chưa biết cách tích hợp code vượt Captcha của (Python, C#..) vào VBA nên phải nhập Captcha thủ công.
    Nói chung cái tool cũng giải quyết được việc tải hóa đơn hàng loạt :D .
    Tôi sẽ upload file demo không khóa (có khóa cũng như không) sau vì code còn lộn xộn lắm. Các bạn xem qua và đóng góp cách xử lý tốt hơn, gọn hơn nhé.


    *** 12/10/2024: Cập nhật sửa một đống lỗi.
    *** 15/10/2024: Cập nhật sửa lỗi Null và nhập ngày tháng.
    *** 16/10/2024: Thêm tính năng lưu User/Pass.
    *** 20/10/2024: Sửa lỗi hiển thị ngày tháng, sửa và thêm một số code phụ trợ.
    *** 28/10/2024: Sửa lấy hóa đơn từ máy tính tiền.
    *** 07/11/2024: Sửa code trích xuất dữ liệu, thêm cột so sánh.
    *** 13/11/2024: Dùng code của bạn Hesanbi để tự động nhập Captcha. Thêm code lấy link tra cứu của VNPT và BKAV.
    *** 05/02/2025: Thêm code tải file Zip và trích xuất dữ liệu hóa đơn từ file XML. Sửa một số lỗi.
    *** 23/02/2025: Sửa lỗi hiển thị sai <Trạng thái hóa đơn>.
    *** 10/05/2026: Cập nhật do trang hoadondientu thay đổi thiết kế.
    đợt này mã tra cứu hóa đơn của misa nó không hiện ra nữa a, a khắc phục giúp em với
     
    Upvote 0
    Đang dùng ổn định thì một ngày đẹp trời hiện ra lỗi này. Các bác hổ trợ giúp e với ạ !?!

    Loi.pngLoi 2.png
     
    Upvote 0
    E mới tải bản v6.2 của chủ thớt nhưng bị lỗi vầy, nhờ anh chị em hỗ trợ giúp
     

    File đính kèm

    • 1778572099281.png
      1778572099281.png
      142.5 KB · Đọc: 50
    Upvote 0
    Nếu các bạn đang dùng file cũ thì cũng có thể tự sửa đường dẫn web (url) như sau:
    - Mở màn hình để code VBE: Atl + F11
    - Mở menu Edit - chọn Replace, làm như hình:

    Screenshot at May 13 11-12-00 AM.png
     
    Upvote 0
    Upvote 0
    em có tải bản v6.2 lúc mở file để đăng nhập lần đầu thì hiện thông báo như ảnh, nhờ anh chị hỗ trợ giúp em lỗi này với ạ
    1778656795025.png
     
    Upvote 0
    bản mới này e thấy lỗi hiển thị trạng thái hóa đơn à a
     
    Upvote 0

    File đính kèm

    • z7822170330670_fe56f6b6243149c4ff3b680366a226b4.jpg
      z7822170330670_fe56f6b6243149c4ff3b680366a226b4.jpg
      43 KB · Đọc: 36
    • z7822171109437_dbbbafb40522e37c02d0f9a359f0e8d3.jpg
      z7822171109437_dbbbafb40522e37c02d0f9a359f0e8d3.jpg
      48.8 KB · Đọc: 39
    Upvote 0
    file cũ mình đã laycapcha và cái api theo cách bạn chỉ nhưng vẫn bị báo lỗi này á.
    Lỗi đó do cái hàm httpGet() thiết lập cũ sai một chút.
    Bỏ hàm layTenDV(), do còn lỗi chưa lấy được.
    Bạn vô màn hình code, tìm kiếm cái hàm trên rồi thay thế, bỏ một số dòng như bên dưới:

    JavaScript:
    Function httpGet(ByVal url As String, bearer As String, res As String) As Boolean
        On Error GoTo EH
       
        With xmlHttp 'CreateObject("MSXML2.serverXMLHTTP.6.0")
            .Open "GET", url, False
            .setRequestHeader "User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36"
            .setRequestHeader "Accept", "application/json"
            .setRequestHeader "Content-type", "application/json"
            .setRequestHeader "Authorization", "Bearer " & bearer & ""
            .send


    Screenshot at May 13 9-50-16 PM.png
     
    Lần chỉnh sửa cuối:
    Upvote 0
    Lỗi đó do cái hàm httpGet() thiết lập cũ sai một chút.
    Bạn vô màn hình code, tìm kiếm cái hàm trên rồi thay thế, bỏ một số dòng như bên dưới:

    JavaScript:
    Function httpGet(ByVal url As String, bearer As String, res As String) As Boolean
        On Error GoTo EH
       
        With xmlHttp 'CreateObject("MSXML2.serverXMLHTTP.6.0")
            .Open "GET", url, False
            .setRequestHeader "User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36"
            .setRequestHeader "Accept", "application/json"
            .setRequestHeader "Content-type", "application/json"
            .setRequestHeader "Authorization", "Bearer " & bearer & ""
            .send


    View attachment 311636
    cảm ơn @ongke0711 nhé. chạy file cũ được rồi á.
    Bài đã được tự động gộp:

    View attachment 311637
    hóa đơn mới là nó hiển thị chữ tất cả, còn hóa đơn thay thế thì nó hiển thị hóa đơn mới à ad
    bạn vào cái mình gửi dưới sửa lại I2 thành I3 là được nhé. nêu siêng thì bạn coi lại các trang trước có hướng dẫn sửa các lỗi á.
     

    File đính kèm

    • z7823268127366_8d6e7ffe7c097b3ff28a6d084c5f4394.jpg
      z7823268127366_8d6e7ffe7c097b3ff28a6d084c5f4394.jpg
      39.5 KB · Đọc: 39
    Upvote 0
    2.png
    E đã khắc phục được lỗi này. Trong hàm "ApiGet", các bác chỉnh lại đoạn code sau:

    Public Function ApiGet(ByVal urlPath As String) As String
    Dim http As Object
    Set http = CreateObject("MSXML2.ServerXMLHTTP.6.0")
    http.Open "GET", urlPath, False
    http.setRequestHeader "Authorization", "Bearer " & getToken()
    http.setRequestHeader "Accept", "application/json"
    http.setRequestHeader "User-Agent", "Mozilla/5.0 ExcelVBA-HDDT"

    On Error Resume Next
    http.send

    If err.Number <> 0 Then
    err.Clear
    ApiGet = ""
    Exit Function
    End If

    If http.Status = 401 Or http.Status = 403 Then
     
    Lần chỉnh sửa cuối:
    Upvote 0
    Upvote 0
    Mọi người cho em hỏi cái file đó tải về cái link hóa đơn gốc copy dán vào không ra nhỉ, có cách nào khác không , cám ơn mọi người.
     
    Upvote 0
    1778733274522.png
    Trang web chưa ổn hay sao á . Mình cứ bị báo lỗ này mặc dù đã khai chỉ có 10 ngày
     
    Upvote 0
    Mọi người cho em hỏi cái file đó tải về cái link hóa đơn gốc copy dán vào không ra nhỉ, có cách nào khác không , cám ơn mọi người.
    Chỉ có cách tinh chỉnh link thôi. Và tùy chỉnh này chỉ tác dụng cục bộ ở phạm vi từng đơn vị.
     
    Upvote 0
    Không tải về được CHI TIẾT hóa đơn bán hàng (các mục hóa đơn còn lại tải về bình thường). Các bác hổ trợ giúp e với ạ !?!
     
    Upvote 0
    Mấy bữa nay anh em vào test chức năng nhiều quá. Trang thuế quay đơ ra không tải được gì hết.
     
    Upvote 0
    Bạn tải lại file đi. File này cũ rồi.
    Không tải về được CHI TIẾT hóa đơn bán hàng (các mục hóa đơn còn lại tải về bình thường). Bác ongke0711 hổ trợ giúp e với ạ !?!

    Sau khi chạy lấy thông tin CHI TIẾT hóa đơn bán hàng thì mình lấy được giá trị url2 :


    Và khi gán giá trị vào hàm ApiGet thì bị tạo ra giá trị "res" bị "rỗng" không hợp lệ như hình đính kèm
    res = ApiGet(url2)

    Nhưng nếu áp dụng với hóa đơn mua hàng thì res vẫn có giá trị
     

    File đính kèm

    • 1.png
      1.png
      9.8 KB · Đọc: 13
    • 2.png
      2.png
      10.7 KB · Đọc: 10
    Upvote 0
    Không tải về được CHI TIẾT hóa đơn bán hàng (các mục hóa đơn còn lại tải về bình thường). Bác ongke0711 hổ trợ giúp e với ạ !?!

    Sau khi chạy lấy thông tin CHI TIẾT hóa đơn bán hàng thì mình lấy được giá trị url2 :


    Và khi gán giá trị vào hàm ApiGet thì bị tạo ra giá trị "res" bị "rỗng" không hợp lệ như hình đính kèm
    res = ApiGet(url2)

    Nhưng nếu áp dụng với hóa đơn mua hàng thì res vẫn có giá trị
    Theo như chuỗi url bạn đưa lên thì thiếu tham số chỗ "sort=" rồi.
    sort = "tdlap:desc"
     
    Upvote 0
    Gặp link sai so với quy luật của tổ chức cung cấp hoá đơn thì tìm cách khắc phục lấy link đúng thôi. Bạn cần thì mình hỗ trợ riêng ngoài.
     
    Upvote 0
    Chào các bạn,
    Tôi ngồi mò mẫm mấy ngày mới tìm được cách tải hóa đơn điện tử từ trang https://hoadondientu.gdt.gov.vn/. Cách này có thể không chuyên nghiệp nhưng cũng giải quyết được vấn đề tải hóa đơn hàng loạt từ trang trên và ghi xuống Excel theo định dạng dễ tổng hợp dữ liệu sau này.
    - Tốc độ không nhanh như các ứng dụng python siêu nhanh.
    - Chưa tìm được các link tải file .xml hoặc .html
    - Chưa trải nghiệm qua các định dạng hóa đơn điện tử của các nhà cung cấp giải pháp khác nhau nên sẽ không đảm bảo chạy đúng 100%.
    - Chưa biết cách tích hợp code vượt Captcha của (Python, C#..) vào VBA nên phải nhập Captcha thủ công.
    Nói chung cái tool cũng giải quyết được việc tải hóa đơn hàng loạt :D .
    Tôi sẽ upload file demo không khóa (có khóa cũng như không) sau vì code còn lộn xộn lắm. Các bạn xem qua và đóng góp cách xử lý tốt hơn, gọn hơn nhé.


    *** 12/10/2024: Cập nhật sửa một đống lỗi.
    *** 15/10/2024: Cập nhật sửa lỗi Null và nhập ngày tháng.
    *** 16/10/2024: Thêm tính năng lưu User/Pass.
    *** 20/10/2024: Sửa lỗi hiển thị ngày tháng, sửa và thêm một số code phụ trợ.
    *** 28/10/2024: Sửa lấy hóa đơn từ máy tính tiền.
    *** 07/11/2024: Sửa code trích xuất dữ liệu, thêm cột so sánh.
    *** 13/11/2024: Dùng code của bạn Hesanbi để tự động nhập Captcha. Thêm code lấy link tra cứu của VNPT và BKAV.
    *** 05/02/2025: Thêm code tải file Zip và trích xuất dữ liệu hóa đơn từ file XML. Sửa một số lỗi.
    *** 23/02/2025: Sửa lỗi hiển thị sai <Trạng thái hóa đơn>.
    *** 10/05/2026: Cập nhật do trang hoadondientu thay đổi thiết kế.
    Bấc ơi, hiện tại sao file không connect được nữa bác nhỉ?
     
    Upvote 0

    chào bạn ongke0711

    Cho mình hỏi chút chỗ Token này mình đưa số seri trên token vào hay sao bạn?
    Nếu chữ ký số (token) gia hạn nhiều lần thì nhập hết các seri hay như thế nào?
    Cảm ơn bạn đã hỗ trợ
    HOADONTU.jpg

     
    Upvote 0

    chào bạn ongke0711

    Cho mình hỏi chút chỗ Token này mình đưa số seri trên token vào hay sao bạn?​

    Nếu chữ ký số (token) gia hạn nhiều lần thì nhập hết các seri hay như thế nào?​

    Cảm ơn bạn đã hỗ trợ​

    View attachment 311666

    Token này là code lấy tự động của trang web thôi, không phải nhập gì cả. Khi đăng nhập trang hddt, nó sẽ cấp cho cái mã để truy vấn dữ liệu mà không cần phải đăng nhập lại. Có thời gian hiệu lực trong 24h. Khi bạn bấm nút Tải hoá đơn, nếu có thông báo token hết hiệu lực thì bạn phải đăng nhập lại rồi tiếp tục sử dụng. Không phải token của kế toán nhé.
     
    Upvote 0
    Trang thuế hoạt động ổn định được mấy hôm. Chiều hôm nay thì sập luôn rồi! ;)HDDT.png
     
    Upvote 0
    Các bác hỗ trợ giúp em sao chỗ trạng thái hóa đơn này sao chỉ hiện thị tất cả nhỉ, hôm trước là hiện thị hóa đơn mới, thay thế và xóa bỏ mà nhỉ, mà chỗ này lại rất quan trọng nữa chứ, hỗ trợ giúp em với ạ, em cảm ơn nhiều ạ
    1779177633333.png
     
    Upvote 0
    mobiphone có cách nào lấy được hóa đơn gốc về không mọi người ơi.
    Link tra cứu của mobifone không có mã captcha nên dễ lấy.
    Nếu tích hợp code tải của mobifone không vô file trên của tôi cũng hơi khó vì danh sách hoá đơn trả về có nhiều nhà cung cấp. Nếu bạn tổng hợp ra được một danh sách các mã tra cứu của mobifone thì có thể code để nó tải theo danh sách đó.
     
    Upvote 0
    Các bác hỗ trợ giúp em sao chỗ trạng thái hóa đơn này sao chỉ hiện thị tất cả nhỉ, hôm trước là hiện thị hóa đơn mới, thay thế và xóa bỏ mà nhỉ, mà chỗ này lại rất quan trọng nữa chứ, hỗ trợ giúp em với ạ, em cảm ơn nhiều ạ

    Đã cập nhật lại file ở bài #1.
    Do tham chiếu sai số dòng trong mảng "Trạng thái hoá đơn".
     

    File đính kèm

    Upvote 0
    Link tra cứu của mobifone không có mã captcha nên dễ lấy.
    Nếu tích hợp code tải của mobifone không vô file trên của tôi cũng hơi khó vì danh sách hoá đơn trả về có nhiều nhà cung cấp. Nếu bạn tổng hợp ra được một danh sách các mã tra cứu của mobifone thì có thể code để nó tải theo danh sách đó.
    Bác thớt chắc hiểu nhầm đơn vị rồi. Mobifone thì tạm thời chưa lấy được mã tra cứu MSTTCGP: 0100686209. Ngoài ra còn của ông FPT, MSTTCGP:
    0104128565.
    - Trong file bác update thì đang để nhầm tên Mobifone nhưng MST của M-Invoice.
     
    Upvote 0
    Bác thớt chắc hiểu nhầm đơn vị rồi. Mobifone thì tạm thời chưa lấy được mã tra cứu MSTTCGP: 0100686209. Ngoài ra còn của ông FPT, MSTTCGP:
    0104128565.
    - Trong file bác update thì đang để nhầm tên Mobifone nhưng MST của M-Invoice.
    :) Đúng là nhầm thật. Mà cái hoá đơn của Mobifone đúng là không tìm ra được mã tra cứu (từ các file json, xml của web), chỉ có được từ file pdf hoá đơn gốc.
     
    Upvote 0
    Bác thớt chắc hiểu nhầm đơn vị rồi. Mobifone thì tạm thời chưa lấy được mã tra cứu MSTTCGP: 0100686209. Ngoài ra còn của ông FPT, MSTTCGP:
    0104128565.
    - Trong file bác update thì đang để nhầm tên Mobifone nhưng MST của M-Invoice.
    vậy là thành mobifone chỉ có nhận email với FTP cũng vậy không còn cách nào khác đúng ko anh.
     
    Upvote 0
    vậy là thành mobifone chỉ có nhận email với FTP cũng vậy không còn cách nào khác đúng ko anh.
    Một số đơn vị tư nhân khác cũng không lấy được mã, nhưng rất hiếm. Code vba hiện tại đã xem được 95% số lượng hoá đơn gốc. Tùy đối tác của đơn vị mình "đa dạng" hay không. Hầu hết hoá đơn thông thường như xăng dầu, vetc, viettel, vnpt, bank (bidv, agri, vietcom)... Là xem được gốc. Còn lại thì chưa gặp nên chưa rõ.
     
    Upvote 0
    :) Đúng là nhầm thật. Mà cái hoá đơn của Mobifone đúng là không tìm ra được mã tra cứu (từ các file json, xml của web), chỉ có được từ file pdf hoá đơn gốc.
    Với số lượng hóa đơn 1 tháng khoảng 10,000 hóa đơn, phần chi tiết khoảng 40,000 dòng thì có cách nào dùng file này vẫn tải được trong 1 lần không anh nhỉ?
     
    Upvote 0
    Đã cập nhật lại file ở bài #1.
    Do tham chiếu sai số dòng trong mảng "Trạng thái hoá đơn".
    Tôi dựa trên file của Bạn, tôi góp thêm nút lệnh lấy Phụ lục giảm thuế 8% theo mẫu Bang_Ke_01_GiamThue_GTGT_NQ142_GTGT_TT80_t04.2026
    Mã:
    Option Explicit
    
    Sub TaoPLGT()
        Const Col_ThueSuat As String = "X"
        Const Col_ThanhTien As String = "Z"
        Const Col_TenHHDV As String = "R"
        Const Col_TenNguoiBan As String = "F"
        Const Col_NgayHD As String = "C"
        Const Col_SoHD As String = "B"
        Const Col_SoHD_TongHop As String = "E"
        Const Col_KetQua_TongHop As String = "BA"
        
        Application.ScreenUpdating = False
        Application.Calculation = xlCalculationManual
    
        Dim wsDest As Worksheet
        Dim arrMua As Variant, arrBan As Variant
        Dim rStart As Long, colIdx As Integer, rHeader2 As Long
        Dim sheetNameDest As String: sheetNameDest = "BK01_GT_GTGT_NQ142"
        
        arrMua = GetFilteredData("ChiTietHD_Mua", True, Col_ThueSuat, Col_ThanhTien, Col_TenHHDV, Col_TenNguoiBan, Col_NgayHD, Col_SoHD)
        arrBan = GetFilteredData("ChiTietHD_Ban", False, Col_ThueSuat, Col_ThanhTien, Col_TenHHDV, "", "", "")
        
        If Not IsArray(arrMua) And Not IsArray(arrBan) Then
            MsgBox "Không tìm th?y d? li?u thu? 8% (ho?c các giá tr? d?u b?ng 0)!", vbExclamation
            GoTo CleanUp
        End If
        
        If IsArray(arrMua) Then
            Dim wsTH As Worksheet
            Dim dictKQ As Object
            Dim lastRowTH As Long
            Dim arrSoHD_TH As Variant, arrKQ_TH As Variant
            Dim i As Long, soHD As String
            
            On Error Resume Next
            Set wsTH = ThisWorkbook.Sheets("TongHopHD_Mua")
            On Error GoTo 0
            
            If Not wsTH Is Nothing Then
                Set dictKQ = CreateObject("Scripting.Dictionary")
                dictKQ.CompareMode = 1
                lastRowTH = wsTH.Cells(wsTH.Rows.count, Col_SoHD_TongHop).End(xlUp).row
                If lastRowTH >= 2 Then
                    arrSoHD_TH = wsTH.Range(Col_SoHD_TongHop & "1:" & Col_SoHD_TongHop & lastRowTH).Value
                    arrKQ_TH = wsTH.Range(Col_KetQua_TongHop & "1:" & Col_KetQua_TongHop & lastRowTH).Value
                    For i = 2 To lastRowTH
                        If Not IsEmpty(arrSoHD_TH(i, 1)) Then
                            dictKQ(CStr(arrSoHD_TH(i, 1))) = arrKQ_TH(i, 1)
                        End If
                    Next i
                    For i = 1 To UBound(arrMua, 1)
                        soHD = CStr(arrMua(i, 7))
                        If dictKQ.Exists(soHD) Then
                            arrMua(i, 8) = dictKQ(soHD)
                        End If
                    Next i
                End If
            End If
        End If
        
        On Error Resume Next
        Set wsDest = ThisWorkbook.Sheets(sheetNameDest)
        On Error GoTo 0
        If wsDest Is Nothing Then
            Set wsDest = ThisWorkbook.Sheets.Add(After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.count))
            wsDest.name = sheetNameDest
        Else
            wsDest.Cells.Clear
        End If
        wsDest.Range("1:22").EntireRow.Hidden = True
        wsDest.Cells.Font.name = "Arial"
        wsDest.Cells.Font.size = 10
        rStart = 25
        wsDest.Cells(rStart, 2).Value = _
            "I. H" & ChrW(224) & "ng h" & ChrW(243) & "a, d" & ChrW(7883) & "ch v" & ChrW(7909) & _
            " mua v" & ChrW(224) & "o trong k" & ChrW(7923) & " " & ChrW(273) & ChrW(432) & ChrW(7907) & _
            "c " & ChrW(225) & "p d" & ChrW(7909) & "ng m" & ChrW(7913) & "c thu" & ChrW(7871) & _
            " su" & ChrW(7845) & "t thu" & ChrW(7871) & " gi" & ChrW(225) & " tr" & ChrW(7883) & _
            " gia t" & ChrW(259) & "ng 8% (" & ChrW(225) & "p d" & ChrW(7909) & "ng cho ng" & _
            ChrW(432) & ChrW(7901) & "i n" & ChrW(7897) & "p thu" & ChrW(7871) & " k" & ChrW(234) & _
            " khai theo ph" & ChrW(432) & ChrW(417) & "ng ph" & ChrW(225) & "p kh" & _
            ChrW(7845) & "u tr" & ChrW(7915) & " thu" & ChrW(7871) & ")"
        wsDest.Cells(rStart, 2).Font.Bold = True
        Dim hMua As Variant
        hMua = Array( _
            "STT", _
            "T" & ChrW(234) & "n h" & ChrW(224) & "ng h" & ChrW(243) & "a, d" & ChrW(7883) & "ch v" & ChrW(7909), _
            "Gi" & ChrW(225) & " tr" & ChrW(7883) & " h" & ChrW(224) & "ng h" & ChrW(243) & "a, d" & ChrW(7883) & "ch v" & ChrW(7909) & " mua v" & ChrW(224) & "o ch" & ChrW(432) & "a c" & ChrW(243) & " thu" & ChrW(7871) & " GTGT " & ChrW(273) & ChrW(432) & ChrW(7907) & "c kh" & ChrW(7845) & "u tr" & ChrW(7915) & " trong k" & ChrW(7923), _
            "Thu" & ChrW(7871) & " GTGT c" & ChrW(7911) & "a h" & ChrW(224) & "ng h" & ChrW(243) & "a, d" & ChrW(7883) & "ch v" & ChrW(7909) & " mua v" & ChrW(224) & "o " & ChrW(273) & ChrW(432) & ChrW(7907) & "c kh" & ChrW(7845) & "u tr" & ChrW(7915) & " trong k" & ChrW(7923), _
            "T" & ChrW(234) & "n ng" & ChrW(432) & ChrW(7901) & "i b" & ChrW(225) & "n", _
            "Ng" & ChrW(224) & "y l" & ChrW(7853) & "p h" & ChrW(243) & "a " & ChrW(273) & ChrW(417) & "n", _
            "S" & ChrW(7889) & " h" & ChrW(243) & "a " & ChrW(273) & ChrW(417) & "n", _
            "K" & ChrW(7871) & "t qu" & ChrW(7843) & " ki" & ChrW(7875) & "m tra h" & ChrW(243) & "a " & ChrW(273) & ChrW(417) & "n" _
        )
        wsDest.Range(wsDest.Cells(26, 2), wsDest.Cells(26, 9)).Value = hMua
        
        For colIdx = 2 To 9
            wsDest.Range(wsDest.Cells(26, colIdx), wsDest.Cells(28, colIdx)).Merge
        Next colIdx
        wsDest.Range(wsDest.Cells(29, 2), wsDest.Cells(29, 9)).Value = Array("'(1)", "'(2)", "'(3)", "'(4)", "A", "B", "C", "D")
        Call FormatHeaders(wsDest.Range(wsDest.Cells(26, 2), wsDest.Cells(29, 9)))
        wsDest.Range(wsDest.Cells(26, 6), wsDest.Cells(29, 9)).Interior.Color = vbYellow
        If IsArray(arrMua) Then
            rStart = 30
            wsDest.Range(wsDest.Cells(rStart, 2), wsDest.Cells(rStart + UBound(arrMua, 1) - 1, 9)).Value = arrMua
            Call FormatDataBody(wsDest.Range(wsDest.Cells(rStart, 2), wsDest.Cells(rStart + UBound(arrMua, 1) - 1, 9)), 8)
            rStart = rStart + UBound(arrMua, 1)
        Else
            rStart = 30
        End If
    
        rStart = rStart + 1
        wsDest.Cells(rStart, 2).Value = "II. H" & ChrW(224) & "ng h" & ChrW(243) & "a, d" & ChrW(7883) & "ch v" & ChrW(7909) & " b" & ChrW(225) & "n ra trong k" & ChrW(7923)
        wsDest.Cells(rStart, 2).Font.Bold = True
        
        rHeader2 = rStart + 1
        Dim hBan As Variant
        hBan = Array( _
            "STT", _
            "T" & ChrW(234) & "n h" & ChrW(224) & "ng h" & ChrW(243) & "a, d" & ChrW(7883) & "ch v" & ChrW(7909), _
            "Gi" & ChrW(225) & " tr" & ChrW(7883) & " h" & ChrW(224) & "ng h" & ChrW(243) & "a, d" & ChrW(7883) & "ch v" & ChrW(7909) & " ch" & ChrW(432) & "a c" & ChrW(243) & " thu" & ChrW(7871) & " GTGT", _
            "Thu" & ChrW(7871) & " su" & ChrW(7845) & "t thu" & ChrW(7871) & " GTGT theo quy " & ChrW(273) & ChrW(7883) & "nh", _
            "Thu" & ChrW(7871) & " su" & ChrW(7845) & "t thu" & ChrW(7871) & " GTGT sau gi" & ChrW(7843) & "m", _
            "Thu" & ChrW(7871) & " GTGT c" & ChrW(7911) & "a h" & ChrW(224) & "ng h" & ChrW(243) & "a, d" & ChrW(7883) & "ch v" & ChrW(7909) & " b" & ChrW(225) & "n ra " & ChrW(273) & ChrW(432) & ChrW(7907) & "c gi" & ChrW(7843) & "m" _
        )
        wsDest.Range(wsDest.Cells(rHeader2, 2), wsDest.Cells(rHeader2, 7)).Value = hBan
      
        For colIdx = 2 To 7
            wsDest.Range(wsDest.Cells(rHeader2, colIdx), wsDest.Cells(rHeader2 + 2, colIdx)).Merge
        Next colIdx
        
        wsDest.Range(wsDest.Cells(rHeader2 + 3, 2), wsDest.Cells(rHeader2 + 3, 7)).Value = Array("'(1)", "'(2)", "'(3)", "'(4)", "(5)=(4)x80%", "(6)=(3)x[(4)-(5)]")
        
        Call FormatHeaders(wsDest.Range(wsDest.Cells(rHeader2, 2), wsDest.Cells(rHeader2 + 3, 7)))
        
        rStart = rHeader2 + 4
        If IsArray(arrBan) Then
            wsDest.Range(wsDest.Cells(rStart, 2), wsDest.Cells(rStart + UBound(arrBan, 1) - 1, 7)).Value = arrBan
            Call FormatDataBody(wsDest.Range(wsDest.Cells(rStart, 2), wsDest.Cells(rStart + UBound(arrBan, 1) - 1, 7)), 6)
        End If
        
        wsDest.Columns(1).ColumnWidth = 3     ' C?t A tr?ng bên ngoài
        wsDest.Columns(2).ColumnWidth = 5     ' STT (B)
        wsDest.Columns(3).ColumnWidth = 40    ' Tên HHDV (C)
        wsDest.Columns(4).ColumnWidth = 18    ' Giá tr? (D)
        wsDest.Columns(5).ColumnWidth = 18    ' Ti?n thu? (E)
        wsDest.Columns(6).ColumnWidth = 25    ' Tên ngu?i bán (F)
        wsDest.Columns(7).ColumnWidth = 15    ' Ngày l?p (G)
        wsDest.Columns(8).ColumnWidth = 15    ' S? HÐ (H)
        wsDest.Columns(9).ColumnWidth = 20    ' KQ Ki?m tra (I)
    
    CleanUp:
        Application.Calculation = xlCalculationAutomatic
        Application.ScreenUpdating = True
        If IsArray(arrMua) Or IsArray(arrBan) Then
            MsgBox "Da tai xong Phu Luc thanh cong!", vbInformation, "Hoan tat"
            Sheets("BK01_GT_GTGT_NQ142").Select
            
        End If
    End Sub
    
    Private Function GetFilteredData(sheetName As String, isMua As Boolean, _
                                     cThue As String, cTien As String, cTen As String, _
                                     cNban As String, cNgay As String, cSo As String) As Variant
        Dim ws As Worksheet
        Dim lastRow As Long, i As Long, r As Long
        Dim arrSrc As Variant, arrDest As Variant
        Dim valThue As Variant, valTien As Variant
        
        On Error Resume Next
        Set ws = ThisWorkbook.Sheets(sheetName)
        On Error GoTo 0
        If ws Is Nothing Then Exit Function
        lastRow = ws.Cells(ws.Rows.count, cThue).End(xlUp).row
        If lastRow < 2 Then Exit Function
        arrSrc = ws.Range("A1:CZ" & lastRow).Value
        Dim iThue As Integer, iTien As Integer, iTen As Integer
        Dim iNban As Integer, iNgay As Integer, iSo As Integer
        
        iThue = ws.Range(cThue & 1).Column
        iTien = ws.Range(cTien & 1).Column
        iTen = ws.Range(cTen & 1).Column
        If isMua Then
            iNban = ws.Range(cNban & 1).Column
            iNgay = ws.Range(cNgay & 1).Column
            iSo = ws.Range(cSo & 1).Column
        End If
        Dim cols As Integer
        If isMua Then cols = 8 Else cols = 6
        ReDim arrDest(1 To lastRow, 1 To cols)
        r = 0
        For i = 2 To lastRow
            valThue = arrSrc(i, iThue)
            If Not IsError(valThue) And Not IsEmpty(valThue) Then
                If CStr(valThue) Like "*8%*" Or valThue = 8 Or valThue = 0.08 Or CStr(valThue) = "8" Then
                    valTien = arrSrc(i, iTien)
                    If Not IsNumeric(valTien) Or IsEmpty(valTien) Then valTien = 0
                    If CDbl(valTien) <> 0 Then
                        r = r + 1
                        arrDest(r, 1) = r
                        arrDest(r, 2) = arrSrc(i, iTen)
                        arrDest(r, 3) = Round(CDbl(valTien), 0)
                        
                        If isMua Then
                            arrDest(r, 4) = Round(CDbl(valTien) * 0.08, 0)
                            arrDest(r, 5) = arrSrc(i, iNban)
                            arrDest(r, 6) = arrSrc(i, iNgay)
                            arrDest(r, 7) = arrSrc(i, iSo)
                            arrDest(r, 8) = ""
                        Else
                            arrDest(r, 4) = ""
                            arrDest(r, 5) = ""
                            arrDest(r, 6) = ""
                        End If
                    End If
                End If
            End If
        Next i
        If r > 0 Then
            Dim arrFinal As Variant
            ReDim arrFinal(1 To r, 1 To cols)
            Dim rIdx As Long, cIdx As Integer
            For rIdx = 1 To r
                For cIdx = 1 To cols
                    arrFinal(rIdx, cIdx) = arrDest(rIdx, cIdx)
                Next cIdx
            Next rIdx
            GetFilteredData = arrFinal
        End If
    End Function
    
    Private Sub FormatHeaders(rng As Range)
        With rng
            .Borders.LineStyle = xlContinuous
            .Borders.Weight = xlThin
            .Interior.Color = RGB(204, 255, 204)
            .Font.Bold = True
            .HorizontalAlignment = xlCenter
            .VerticalAlignment = xlCenter
            .WrapText = True
        End With
    End Sub
    
    Private Sub FormatDataBody(rng As Range, cols As Integer)
        With rng
            .Borders.LineStyle = xlContinuous
            .Borders.Weight = xlThin
            .VerticalAlignment = xlCenter
        End With
        rng.Columns(1).HorizontalAlignment = xlCenter
        rng.Columns(3).NumberFormat = "#,##0"
        If cols = 8 Then
            rng.Columns(4).NumberFormat = "#,##0"
            rng.Columns(6).NumberFormat = "dd/mm/yyyy"
        End If
    End Sub
     
    Upvote 0
    Một số đơn vị tư nhân khác cũng không lấy được mã, nhưng rất hiếm. Code vba hiện tại đã xem được 95% số lượng hoá đơn gốc. Tùy đối tác của đơn vị mình "đa dạng" hay không. Hầu hết hoá đơn thông thường như xăng dầu, vetc, viettel, vnpt, bank (bidv, agri, vietcom)... Là xem được gốc. Còn lại thì chưa gặp nên chưa rõ.
    Ngân hàng bạn lấy như nào vậy, chỉ mình với được không
     
    Upvote 0
    Mẫu Agri và Vietcom bác nào hôm trước chia sẻ, mình cắt gọt nội dung cần thiết rồi viết thêm code xuất file xml cho tiện. Web cho tìm kiếm bằng file xml.
    BIDV thì tìm theo thông tin hóa đơn.
     

    File đính kèm

    Upvote 0
    Với số lượng hóa đơn 1 tháng khoảng 10,000 hóa đơn, phần chi tiết khoảng 40,000 dòng thì có cách nào dùng file này vẫn tải được trong 1 lần không anh nhỉ?
    Tôi dùng cái api đang công khai trên trang web chứ không phải api do TCT cung cấp cho các đơn vị chuyên nghiệp nên nó bị hạn chế số lần request trong một khoảng thời gian (rate limit). Hơn nữa đang dùng VBA chứ không phải các ngôn ngữ lập trình cao cấp khác nên không có hỗ trợ kiểu truy vấn bất đồng bộ để tăng tốc độ tải, không có độ trễ v.v... Do vậy bạn chia nhỏ ra mà tải hoặc dùng các phần mềm tải hàng loạt rất nhiều trên mạng.
     
    Lần chỉnh sửa cuối:
    Upvote 0
    Mẫu Agri và Vietcom bác nào hôm trước chia sẻ, mình cắt gọt nội dung cần thiết rồi viết thêm code xuất file xml cho tiện. Web cho tìm kiếm bằng file xml.
    BIDV thì tìm theo thông tin hóa đơn.
    Ngân hàng thường xml tool tải không về, bạn có thể cập nhật được các ngân hàng có thể lấy được không.
     
    Upvote 0
    Ngân hàng thường xml tool tải không về, bạn có thể cập nhật được các ngân hàng có thể lấy được không.
    Mình lấy được BIDV (theo thông tin hóa đơn); Agribank, Vietcombank (theo XML), Không lấy được: Vietinbank, MB, ACB, các ngân hàng còn lại chưa gặp.
     
    Upvote 0

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

    Back
    Top Bottom