Tải hóa đơn điện tử (https://hoadondientu.gdt.gov.vn/) Excel Vba (8 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