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

Liên hệ QC

ongke0711

Thành viên gắn bó
Tham gia
7/9/06
Bài viết
2,230
Được thích
2,950
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.
 

File đính kèm

  • TaiHoaDonDienTu_v4_luuUserPass.xlsm
    264.1 KB · Đọc: 71
Lần chỉnh sửa cuối:
Cái này hay đây, cảm ơn bác chia sẻ không nghĩ vba làm được món này
 
Upvote 0
e tải lại file bài #1 và test thử với tìm kiếm 1 Quý thì kết quả như sau ạ:
- Hoá đơn bán ra thực tế 81 tờ: Run xoay tầm gần 1' -> Hiện thông báo "Xong." -> Kết quả chỉ tải dc 55 tờ, có tải được chi tiết hoá đơn.
- Hoá đơn mua vào thực tế >200 tờ: Run hiện ngay báo lỗi như ảnh đính kèm, click Debug thì hiện báo vàng như bài #57 -> Kết quả tải được đc 44 tờ, chi tiết hoá đơn trống không tải được.
Tôi cũng phát hiện cái lỗi như hình của bạn và đang sửa lại code. Xong nhờ bạn kiểm tra lại nhé.
 
Upvote 0
@ongke0711 các dạng ngày trong json anh phải sử dụng hàm ParseIso để chuyển đổi thành ngày chính xác
Ở Việt Nam ParseIso sẽ chuyển ngày và cộng thêm 7 giờ.
 
Upvote 0
Đã cập nhật sửa một đống lỗi. Các bạn test lại xem như thế nào nhé.
Bản cập nhật quá tuyệt vời. Thật sự cám ơn file này của bạn rất có ích cho kế toán.
Tôi phát sinh 1 lỗi null khi tải "Hóa đơn mua vào - Không có mã cơ quan thuế cấp"
Mã:
ws.Cells(row, c + 2).Value = CDate(Left(item(arrColName(c)), 10))
Bạn đang lấy ngày lập hóa đơn theo "ncma" có phải là ngày cơ quan thuế cấp mã không. Nếu đúng vậy thì trường hợp này sẽ null vì đang chọn "Không có mã cơ quan thuế cấp" thì đâu có "ngày cơ quan thuế cấp mã" cho trường hợp này.
Mã:
...
msttcgp = JsonObject("datas")(l)("msttcgp")
tiếp đó biến msttcgp này cũng sẽ lỗi.
 

File đính kèm

  • Test_Error_1.png
    Test_Error_1.png
    162.1 KB · Đọc: 27
Lần chỉnh sửa cuối:
Upvote 0
Sẵn chỗ này anh @HeSanbi gợi ý thêm.
Em đọc thấy có đề cập đến việc sử dụng async-xmlhttp-request dạng gửi request bất đồng bộ. Tận dụng thời gian gửi để xử lý việc khác, anh có từng tận dụng hay có viết hàm gì chỗ này không.
Em thấy nó rất phù hợp kiểu gửi request liên tục.
 
Upvote 0
Rất cảm ơn bạn chia sẻ! Bạn phát triển thêm phần tra theo MST người Mua/Bán nữa thì tuyệt!
 
Upvote 0
Sẵn chỗ này anh @HeSanbi gợi ý thêm.
Em đọc thấy có đề cập đến việc sử dụng async-xmlhttp-request dạng gửi request bất đồng bộ. Tận dụng thời gian gửi để xử lý việc khác, anh có từng tận dụng hay có viết hàm gì chỗ này không.
Em thấy nó rất phù hợp kiểu gửi request liên tục.
Tôi đã viết nó và tận dụng cho những dự án đã được chia sẻ trên diễn đàn như: TaxCode, TranslateXL, dữ liệu tài chính và chứng khoán, ...
 
Lần chỉnh sửa cuối:
Upvote 0
Xem lại giúp mình bị lỗi như thế này
 

File đính kèm

  • 1.PNG
    1.PNG
    124.4 KB · Đọc: 28
Upvote 0
Bạn đang lấy ngày lập hóa đơn theo "ncma" có phải là ngày cơ quan thuế cấp mã không. Nếu đúng vậy thì trường hợp này sẽ null vì đang chọn "Không có mã cơ quan thuế cấp" thì đâu có "ngày cơ quan thuế cấp mã" cho trường hợp này.
Mã:
...
msttcgp = JsonObject("datas")(l)("msttcgp")
tiếp đó biến msttcgp này cũng sẽ lỗi.
Đúng trường hợp này đó bạn. Để tô bẫy lỗi cho điều kiện này. :)
Tôi không trong ngành nên cũng không chắc là có lấy đúng các trường trong file xml để thể hiện trên file Excel hay chưa.
 
Lần chỉnh sửa cuối:
Upvote 0
Đúng trường hợp này đó bạn. Để tô bẫy lỗi cho điều kiện này. :)
Tôi không trong ngành nên cũng không chắc là có lấy đúng các trường trong file xml để thể hiện trên file Excel hay chưa.
Nếu ở góc độ kế toán tôi chỉ quan tâm "ngày hóa đơn" là ngày giao dịch HHDV. Tôi nghĩ ở đây là tham số "tdlap" (tôi đoán là viết tắt của "thời điểm lập". Nếu tìm theo giá trị này thì không bao giờ "null" cho tất cả trường hợp. Còn bên thuế họ sẽ căn cứ "ngày lập hóa đơn" (ntao), "ngày cấp mã cơ quan thuế"(ncma) để xem cty nào xuất hóa đơn không đúng thời điểm sẽ bị phạt. Trong thực tế không phải cty nào cũng có bộ máy kế toán cuối ngày xuất hóa đơn kịp và có khi cty phải chấp nhận xuất sai ngày. Lúc giải trình thì tùy mức độ mà bị phạt cảnh cáo hoặc theo khung phạt tiền. Nên cột "ngày lập" hóa đơn trên các file bảng kê xlsx tôi thấy thuế vẫn căn cứ vào ngày ghi trên hóa đơn.
 
Upvote 0
Điều kiện từ ngày đến ngày, Nếu ta chọn cùng ngày thì bị báo lỗi bạn, với hóa đơn có một số chi phí khác như thuế Tiêu Thụ Đặc Biệt, thế hay phí khác thì Sheet chi tiết hóa đơn không hiển thị được!
 
Upvote 0
Sẵn chỗ này anh @HeSanbi gợi ý thêm.
Em đọc thấy có đề cập đến việc sử dụng async-xmlhttp-request dạng gửi request bất đồng bộ. Tận dụng thời gian gửi để xử lý việc khác, anh có từng tận dụng hay có viết hàm gì chỗ này không.
Em thấy nó rất phù hợp kiểu gửi request liên tục.
Chắc ý tưởng theo tôi là như vầy không biết có đúng không, tạo một loạt đối tượng XMLHTTP tương ứng với số lượng URL, tiếp theo tạo một loạt đối tượng callback gán cho thuộc tính onReadyStateChange của đối tượng XMLHTTP.
Trước khi chạy, cần mở Internet Options, chọn tab Security, chọn tiếp Custom Level. Trong mục Miscellaneous, chọn Enable cho Access data sources across domains, sau đó nhấn OK để lưu lại.
1728913750396.png
1728913782321.png
1728913834665.png
1728913967521.png
 

File đính kèm

  • Book2.zip
    22.7 KB · Đọc: 16
Upvote 0
1728913750396.png

Cái này không nhất thiết, có chọn disabled cũng không sao
phải đánh dấu các SSL và TLS ở mục Internet Properties/Advenced/Settings

Lập trình HTTP bất đồng bộ không đơn giản là tạo mã là được, ví dụ có 10000 hóa đơn cần tải về, không đơn giản là cho vòng lặp khởi tạo lớp.
Yêu cầu nhất thiết:
1. Quản lý RAM và CPU: Không thể khởi tạo và gửi 10000 yêu cầu liên tục, không đủ RAM, và CPU để xử lý. Phải có giới hạn 30, 40, 100, để dừng gửi yêu cầu trong một lần chạy, và khi nào tiếp tục gửi yêu cầu. Bạn sẽ nhận được một khung thông báo lỗi "Out of stack space" nếu bỏ qua yêu cầu này.
2. Phân chia công việc, lưu trữ công việc và gán vào yêu cầu, để khi nhận được kết quả và xử lý. Không thể cứ mỗi công việc là tạo một lớp mới để viết mã. Xác định được công việc kết thúc khi nào, để giải phóng bộ nhớ kịp thời, nhường bộ nhớ cho công việc tiếp theo, trong công việc có chia ra các task riêng lẻ, quản lý các task này như thế nào.
3. Chia và xử lý các task riêng lẻ trong công việc.
4. Với các HTTP vấn đề lưu trữ và quản lý Cookie như thế nào cho hợp lý nếu có.
5. Giả sử như các yêu cầu bắt buộc chạy đồng bộ trong mã bất đồng bộ thì sao, và cũng bắt buộc gửi đồng bộ cách một khoảng thời gian thì sao.
Ví dụ trên trang masothue.com yêu cầu này là bắt buộc, để tránh bị chặn.​
6. Giải phóng bộ nhớ các công việc, các task, các HTTP đã khởi tạo như thế nào cho hợp lý.
7. .....rất nhiều.

Tải dữ liệu Hóa đơn điện tử vẫn còn đơn giản, dữ liệu tài chính và chứng khoáng mới đủ để đưa vào bài học lập trình VBA nâng cao. Vì ở đó mỗi nguồn cấp dữ liệu với mỗi phương thức chia sẻ dữ liệu khác nhau, đấy là điều mà các yêu cầu nhất thiết là cần thiết.

Tất cả những yêu cầu nhất thiết về Lập trình HTTP bất đồng bộ trên tôi đã phát triển vào các dự án, trong đó phiên bản mới nhất tôi đang phát triển để hoàn thiện tốt nhất.
 
Upvote 0
Cái này không nhất thiết, có chọn disabled cũng không sao
phải đánh dấu các SSL và TLS ở mục Internet Properties/Advenced/Settings

Lập trình HTTP bất đồng bộ không đơn giản là tạo mã là được, ví dụ có 10000 hóa đơn cần tải về, không đơn giản là cho vòng lặp khởi tạo lớp.
Yêu cầu nhất thiết:
1. Quản lý RAM và CPU: Không thể khởi tạo và gửi 10000 yêu cầu liên tục, không đủ RAM, và CPU để xử lý. Phải có giới hạn 30, 40, 100, để dừng gửi yêu cầu trong một lần chạy, và khi nào tiếp tục gửi yêu cầu. Bạn sẽ nhận được một khung thông báo lỗi "Out of stack space" nếu bỏ qua yêu cầu này.
2. Phân chia công việc, lưu trữ công việc và gán vào yêu cầu, để khi nhận được kết quả và xử lý. Không thể cứ mỗi công việc là tạo một lớp mới để viết mã. Xác định được công việc kết thúc khi nào, để giải phóng bộ nhớ kịp thời, nhường bộ nhớ cho công việc tiếp theo, trong công việc có chia ra các task riêng lẻ, quản lý các task này như thế nào.
3. Chia và xử lý các task riêng lẻ trong công việc.
4. Với các HTTP vấn đề lưu trữ và quản lý Cookie như thế nào cho hợp lý nếu có.
5. Giả sử như các yêu cầu bắt buộc chạy đồng bộ trong mã bất đồng bộ thì sao, và cũng bắt buộc gửi đồng bộ cách một khoảng thời gian thì sao.
Ví dụ trên trang masothue.com yêu cầu này là bắt buộc, để tránh bị chặn.​
6. Giải phóng bộ nhớ các công việc, các task, các HTTP đã khởi tạo như thế nào cho hợp lý.
7. .....rất nhiều.

Tải dữ liệu Hóa đơn điện tử vẫn còn đơn giản, dữ liệu tài chính và chứng khoáng mới đủ để đưa vào bài học lập trình VBA nâng cao. Vì ở đó mỗi nguồn cấp dữ liệu với mỗi phương thức chia sẻ dữ liệu khác nhau, đấy là điều mà các yêu cầu nhất thiết là cần thiết.

Tất cả những yêu cầu nhất thiết về Lập trình HTTP bất đồng bộ trên tôi đã phát triển vào các dự án, trong đó phiên bản mới nhất tôi đang phát triển để hoàn thiện tốt nhất.
Tất nhiên, cái code kia của tôi chỉ là dạng đơn giản nhất không quan tâm đến vấn đề tài nguyên máy tính, chỉ đơn thuần là hiển thị kết quả yêu cầu gửi đi đã thành công hay chưa. Nếu không cần đắn đo tài nguyên như CPU, RAM, v.v., của máy tính, thì không phải cứ khởi tạo tầm 100 đối tượng xmlhttp là đồng nghĩa với việc tạo ra 100 kết nối đồng thời đến máy chủ, cái này còn phụ thuộc vào giới hạn kết nối TCP đồng thời do Windows đặt ra nữa.
Điểm nghẽn lớn nhất ở đây là VBA do chỉ hỗ trợ đơn luồng (STA thread), response trả về hàng loạt mà mỗi lần chỉ có thể xử lý một response trong một thời điểm, trường hợp này nếu xung nhịp CPU đơn nhân càng cao thì càng tốt.
 
Upvote 0
Điều kiện từ ngày đến ngày, Nếu ta chọn cùng ngày thì bị báo lỗi bạn, với hóa đơn có một số chi phí khác như thuế Tiêu Thụ Đặc Biệt, thế hay phí khác thì Sheet chi tiết hóa đơn không hiển thị được!
Đã sửa lỗi nhập cùng ngày và các báo lỗi Null.
 
Upvote 0
Chắc ý tưởng theo tôi là như vầy không biết có đúng không, tạo một loạt đối tượng XMLHTTP tương ứng với số lượng URL, tiếp theo tạo một loạt đối tượng callback gán cho thuộc tính onReadyStateChange của đối tượng XMLHTTP.
Trước khi chạy, cần mở Internet Options, chọn tab Security, chọn tiếp Custom Level. Trong mục Miscellaneous, chọn Enable cho Access data sources across domains, sau đó nhấn OK để lưu lại.
View attachment 304770
View attachment 304771
View attachment 304772
View attachment 304773
Đúng rồi. Cái bạn làm đang giống như duyệt web mà dùng trình duyệt mở nhiều trang web cùng lúc. Nếu bạn nào đọc truyện tranh online sẽ hay làm, đọc tập 1 thì tab bên cạnh load tập 2, cuốn chiếu như vậy, chứ không chờ duyệt từng cái cho xong, như vậy thì tiết kiệm được rất nhiều thời gian.
 
Upvote 0
Web KT

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

Back
Top Bottom