[ Python và ứng dụng ] Lập trình thư viện cho VBA bằng Python
Mình đọc tiêu đề là đã thấy hấp dẫn rồi á. 🙂
Mình có tìm hiểu qua vụ này thì thấy có vẻ rất ít thông tin, có thể Python vốn là mã nguồn mở, hoặc có thể đã dùng Python rồi thì không mấy ai để ý tới VBA nữa.
Đã có một số chương trình tích hợp Python với Excel, VBA nhưng đều cần cài đặt Python mới chạy được.
Mình vọc một hồi (hồi khá lâu…) ra cách tạo thư viện cho VBA bằng Python mà không khi phân phối không cần cài đặt Python trên máy tính sử dụng thư viện.
Đại khái một số thông tin như thế này:
* Đầu tiên, được gọi là "thư viện" vì không cần cài đặt Python trên máy tính sử dụng chúng.
* Bảo mật: tương đương [URL='docs.python.org/3/faq/windows.html#is-a-pyd-file-the-same-as-a-dll']Windows DLL.
Tìm hiểu qua thông tin thấy nó cũng là mã máy gì gì đó.
* Tốc độ: tùy vào khả năng viết code. Về cơ bản nó là Python mà.
Mình vọc hồi khá lâu vì vụ bảo mật kia. Hình như chưa có ai làm, hoặc không có gì đáng quan tâm, hoặc ai đó làm rồi mà họ không đăng lên internet nên mình chưa tìm thấy.
Mình làm một ví dụ, coi như động lực để bạn nào có hứng thú thì tự tìm hiểu nha. Tự khám phá ra mới hay mà.
Bài ví dụ: Lấy dữ liệu tỷ giá ngoại tệ từ trang web Vietcombank theo khoảng thời gian.
(Tiếp ví dụ ở bài [URL='www.giaiphapexcel.com/diendan/threads/l%E1%BA%ADp-tr%C3%ACnh-trong-power-query-v%C3%A0-c%C3%A1c-v%C3%AD-d%E1%BB%A5.157214/']www.giaiphapexcel.com/diendan/threads/lập-trình-trong-power-query-và-các-ví-dụ.157214/)
Chạy thử lấy dữ liệu 01 tháng trên máy tính của mình hết cỡ 1.8 giây.
Ai biết code Delphi thử làm bài ví dụ này xem ra sao nhỉ.
Các bạn tải file về nhớ đọc và làm theo hướng dẫn nhé. >> [URL='drive.google.com/uc?export=download&id=1_var3X9w8aiiuQ4dNMG3VnKek85BPv-n']Tải File.
2936
www.giaiphapexcel.com/diendan/threads/python-v%C3%A0-%E1%BB%A9ng-d%E1%BB%A5ng-l%E1%BA%ADp-tr%C3%ACnh-th%C6%B0-vi%E1%BB%87n-cho-vba-b%E1%BA%B1ng-python.157885/
Thiết kế Tổng đãi ngộ (Total Rewards) theo khung SHRM
Khóa học “Thiết kế Tổng phần thưởng (Total Reward) chuẩn khung SHRM” giúp bạn nắm vững toàn bộ hệ thống đãi ngộ theo chuẩn...
Xem khóa học
Mình có một số bài về Python rồi đó.
Cơ bản thì biết VBA là viết được Python rồi. Chủ yếu là đọc cách dùng thư viện thôi.
Lý thuyết cơ bản thì tham khảo đọc ở đây. [URL='www.w3schools.com/python/']>> Python.
Bạn tìm hiểu kỹ, tìm hiểu thật đi. Hiện giờ còn chưa biết code của mình ở chỗ nào ấy. 🙂
Mà chắc chưa đọc kỹ bài #1 rồi.
Hôm nay mình sẽ nêu kỹ thuật ở bài #1 nhé.
Đó là kỹ thuật tạo và đăng ký một COM Server của Python.
Trong VBA (hay ứng dụng khác đều gọi được) gọi COM Server kia lên, cần dùng chức năng gì của COM Server đó thì cứ truyền tham số (nếu có) và gọi lên thôi.
Và kết quả là ta có một ứng dụng Python chạy độc lập và trả về kết quả mong muốn, vì vậy không hề ngạc nhiên về tốc độ xử lý của nó.
Cách này có ưu điểm vượt trội:
– Toàn bộ xử lý của phần "thư viện" là Python làm việc. Trong VBA (hay ở ứng dụng nào đó) chỉ đơn giản là gửi lệnh đi và nhận kết quả mà thôi.
Nó không hề phải chịu cảnh 'dưới trướng' như cách gọi từ *.dll.
– Không liên quan, không phụ thuộc gì vào ứng dụng sử dụng thư viện là 32-64bit gì cả. Bản thân tập lệnh Python được xuất ra *.exe là chạy hoàn toàn độc lập. Kỹ thuật này chỉ đơn giản là tạo ra một cây cầu mà thôi.
Mình làm một ví dụ minh họa cho dễ hiểu. Khi gọi lệnh thì msgbox là của Python, và bên VBA vẫn lấy được kết quả.
[URL='drive.google.com/uc?export=download&id=1qjzXk7NbGmCfERw_GpezMjl_FL0tQT60']>> Tải file ví dụ
Chạy File đăng ký đi anh, e chạy file này xong thì không còn lỗi nữa.
Anh thử dùng tài khoản Administrator rồi đăng ký xem được không.
Vụ đăng ký COM Server không liên quan Office.
Anh 'End task' nó đi. Rồi chạy file unregister.bat.
Sau đó chạy file register.bat.
Nếu vẫn không được thì em cũng chịu rồi. @@
Cái *.exe thông thường thì đúng là vậy. Nhưng *.pyd lại khác hoàn toàn. Không dịch ngược lại thành Python code được, chỉ có thể dùng RE mà thôi.
Bài #1 khúc bảo mật mình có để link rồi đó, hoặc có thể tìm thêm thông tin trên stackoverflow… cũng có nói nhiều về cái này. Nó cũng như dll dịch ra mã máy, có thể có khả năng RE được nhưng chi phí, và thời gian thường là quá lớn so với tự viết code từ đầu; và những người có khả năng RE được thì họ sẽ viết mới luôn.
.
Ở bài #1, em nêu về bảo mật cũng chỉ là phần nhỏ thôi. Chắc mọi người quan tâm quá nội dung đó nên cảm giác đó là ý chính. 🙂
Còn em thì tập trung vào những ưu điểm đã nêu ở bài #13.
.
Nếu nói thêm về phần bảo mật thì em thấy đó (những quan tâm ở diễn đàn về che giấu code) là hoàn toàn hợp lý (cả về thực trạng, và mục đích).
Bảo mật có thể hiểu rất đơn giản và cơ bản là bảo vệ, làm bí mật đi, che giấu cái gì đó.
Mất gà rồi mới lo làm chuồng thì không kịp nữa rồi. Ở môi trường mà việc thực hiện pháp luật chưa nghiêm, hiểu biết pháp luật chưa đầy đủ, và/ hoặc có thể mức độ răn đe của luật chưa cao thì tự bản thân cần có, cần trang bị những biện pháp tự bảo vệ lấy sản phẩm của mình.
Em ví dụ mới đây, ở chủ đề về việc in ấn, có nảy sinh vấn đề loại bỏ thông tin được tác giả chèn ở đầu/ cuối mỗi trang của tập tin PDF, đó là việc vi phạm bản quyền…
Rồi có việc khác là thành viên phát hiện việc vi phạm bản quyền (tự ý chèn link quảng cáo vào tập tin PDF của người khác), em kêu tố giác tội phạm mà họ còn không hiểu thế nào là tố giác tội phạm (Thời điểm hiện tại, Nhà nước ta đã tiếp nhận những thông tin tố giác, thông tin phản ánh trên nền tảng mạng xã hội làm căn cứ điều tra, xử lý tội phạm rồi, chưa cần đến mức phải viết đơn tố giác + kèm bằng chứng đâu).
Việc mọi người tìm cách che giấu code cũng như mỗi nhà làm khóa cổng, khóa cửa đó anh. Tự bảo vệ trước khi cần tới pháp luật (bản quyền), tự tạo ra rào chắn ngăn cản xâm phạm trái phép.
.
Không phải vậy anh.
Python là ngôn ngữ lập trình, như anh viết Pascal trên Delphi đó.
Anh viết xong chương trình trên Delphi rồi mới biên dịch thành phần mềm, thành tập tin *.dll thì mới có đoạn gọi là mã máy gì hay không, còn trước khúc biên dịch thì nó là một ngôn ngữ lập trình thôi.
Cái *.pyd cũng như vậy.
Ban đầu nó là Python code, kế đó được chuyển (convert) thành C code, tiếp đó được biên dịch thành 'Dynamic link librarie' ở dạng *.pyd, vì vậy nó mới tương đương cái *.dll của anh. Chứ không phải Python code bình thường đâu.
.
Em có thử ở máy tính khác, mặc định (UAC không chỉnh gì so với ban đầu) là chạy được luôn.
Khi đóng gói *.py thành *.exe thì sẽ đóng gói toàn bộ thư viện cần thiết và kèm theo Bootloader để khởi chạy Python như khi cài Python hoàn chỉnh.
Như em nói ở bài #13 đó, thư viện nhưng nó lại là Python chạy độc lập, vì vậy nó rất là hay luôn.
Với *.py thì chính là như vậy, nhưng *.pyd lại khác.
Ruột *.pyd là C code đấy anh.
2946
Cái *.exe chỉ đó vai trò đóng gói và chạy ứng dụng thôi, giải nén ra bình thường mà anh, nhưng rồi chỉ ngắm thôi.
Cái này mình nghĩ là hên sui, nhưng mà vậy là cũng được rồi, nếu được thì bạn nên làm clip hướng dẫn để những người muốn tìm hiểu có được chúc thông tin để tìm hiểu
Em thấy anh @excel_lv1.5 có viết Python, 1 bài giống giống bài này, lấy dữ liệu cảng vụ hàng hải (bài #15)
http://www.giaiphapexcel.com/diendan/threads/c%E1%BA%A7n-gi%C3%BAp-%C4%91%E1%BB%A1-code-vba-l%E1%BA%A5y-d%E1%BB%AF-li%E1%BB%87u-tr%C3%AAn-web-theo-ng%C3%A0y-%C4%91%C6%B0%E1%BB%A3c-ch%E1%BB%8Dn.156380/
Em có định làm bằng Power Query, nhưng không biết tham số ngày họ dấu ở đâu, nên chưa có giải pháp.
Delphi có cái thư viện nào làm việc với Web, cào dữ liệu web không bạn?
Mình ngồi nghiên cứu cả ngày mới in ra được chữ "hello world" ra màn hình cmd bằng python, thích thặc. Hi vọng học thêm 2 năm nữa sẽ viết được ứng dụng python như bài #1 của anh Befaint. 🙂
Với bạn thì có thể nhanh chứ với tôi thì không. Bởi chậm tiêu quá thôi trớt cho nhẹ đầu.
Gởi File mọi người nhớ sửa đường dẫn trong vba nhé
tự mình làm biếng xoá máy cái linh tinh, chẳng qua test choi vui thoi 🙂
Cái này 5m
Úp File cho mình thử chút xem có như bạn nói không 0.5s
Lưu ý máy mình ko cài Python
Cả hai hãy thử lấy 10 năm xem sao là biết thôi … vì viết trên môi trường nào cũng thế … dữ liệu lớn mới có thể xem xét được ( phụ thuộc mạng thì xem xét ở góc độ khác )
Muốn so sánh thì phải đưa về một kiểu mới nên so sánh. Ở các môi trường IDE, các nhà sản xuất họ lập trình dùng thủ thuật hoặc sử dụng controls đặc biệt để vẽ dữ liệu vào với tốc độ nhanh nên không phản ánh tốc độ sau biên dịch của sản phẩm lập trình sau khi build. Muốn so sánh hãy đẩy dữ liệu ra bảng tính Excel.
Vấn đề nạp danh sách trong quá trình chạy đa luồng – multi thread. Hãy nạp dữ liệu vào TThreadList. Cách dùng TThreadList [URL='docwiki.embarcadero.com/CodeExamples/Sydney/en/TThreadList_(Delphi)']tại đây.
Để chạy đa luồng, đợi cho tất cả các luồng kết thúc rồi điền dữ liệu từ TThreadList ra đâu đó thì dùng TTask. Cách làm trong Delphi như sau:
1. Thêm unit "Threading"
2. Sử dụng TTask.WaitForAll(array of ITask) để đợi cho tất cả các luồng hoàn thành, tức TThreadList đã nhận đủ dữ liệu.
3. Đẩy dữ liệu từ TThreadList ra Excel hay control nào đó.
Không biết bạn đang dùng component nào để download dữ liệu từ web, nếu trong luồng bạn chạy trang web mà gặp vấn đề thì dùng TidHTTP hoặc THTTPClient nó hỗ trợ tốt trong đa luồng.
Đó là kiến trúc lập trình còn cụ thể ở khúc nào bạn tìm kiếm là ra đầy link tham khảo.
Nếu đã lập trình được như mình chỉ thì chơi hẳn 10 năm hoặc hơn cho máu nhé. 😀
Máy tôi chạy thời gian như bạn 11 năm mất tầm 50s tính luôn xuất excel, khi crawl data web dùng multithread thì các khả năng sau có thể ảnh hưởng đến tốc độ: tốc độ mạng (thời gian gửi request, thời gian phản hồi của server), số lượng request cùng lúc quá nhiều có thể làm thời gian gửi và server phản hồi chậm hơn, sức mạnh của CPU (số lượng luồng tối đa mà con CPU có thể gửi cùng lúc, ví dụ con I3 có thể gửi 10 luồng cùng lúc, I7 có thể gửi 20 luồng cùng lúc như vậy I7 có thể nhanh hơn gấp đôi I3, mặc dù có thể set I3 gửi 20 luồng được nhưng chất lượng mỗi luồng sẽ giảm đi phân nữa do tài nguyên không đủ), tôi nghĩ khả năng là con CPU bạn yếu + code chưa tối ưu lấy 2 năm mất có 22s mà 11 năm mất 187s (tôi thường làm với multithread thấy khi lấy càng nhiều dữ liệu thì thời gian trung bình mỗi luồng sẽ giảm xuống), tôi nghĩ nếu viết chuẩn trên Delphi có thể nhanh hơn Python vì Python mặc định chỉ sử dụng có 1 nhân CPU thôi2955
.
Code multi thread thì CPU load cỡ 70-80%.
Mình thử chèn multi process vào multi thread để kéo hết 100% CPU thì cho kết quả nhanh hơn.
Python có thể dùng GPU để chạy script, vậy kết hợp thêm GPU thì chắc có thể tằng tốc nữa.
Code đơn thuần thì chỉ chạy 1 nhân CPU, nên nếu CPU có tốc độ đơn nhân cao thì sẽ chạy tốt hơn CPU có nhiều nhân nhưng tốc độ mỗi nhân thấp.
Để sử dụng tối đa sức mạnh phần cứng thì Python có multithreading, multiprocessing, chưa kể dùng được GPU để tính toán (nếu máy có GPU hỗ trợ).
Mò tài liệu python vài ngày thì thấy như sau
1/ học py sẻ rất nhanh thôi vì thư viện họ viết cho gần như hết còn mình chỉ call … 😀 :p
2/ cài py có lẻ khá vất vả … nhiều nơi la làng khi lỗi + cài nó
3/ khó khăn nhất là phân phối ứng dụng nhỏ lẻ mà ko phải cài py thì làm như bài số 1 cũng ok đóng gói hết vào đó
xong call thì tốc độ nó cũng giảm theo + file to quá cũng hơi bất tiện chút ==> ko sao cả quan trọng là ứng dụng viết ra có đặc biệt hay ko thôi
….
Chính xác là chỗ này đó. Bài #1 mình làm vậy luôn.
Bạn đẩy chỗ khởi tạo session kết nối tới server ra ngoài để không phải tạo lại cho mỗi luồng.
.
Tiếp một ứng dụng thư viên VBA bằng Python.
Lấy toàn bộ bảng giá xăng dầu từ trang [URL='www.pvoil.com.vn/truyen-thong/tin-gia-xang-dau']PVoil.
Link tải >> [URL='drive.google.com/uc?export=download&id=1c7yW-MjXQOcg5Lp8dQl38pKjyVbvwgrN']Tại đây.
2958
Bạn gửi code lên xem nào, chắc nhầm chỗ nào đó thôi.
Đơn giản nhất là bạn đặt chúng cùng một thư mục rồi dùng import tên_file_py là được.