Tổng hợp file .txt từ nhiều Folders vào file Excel
Em chào thầy, cô và các anh chị trên diễn đàn GPE
Do công việc của em cần tổng hợp nhiều file .txt có cấu trúc giống nhau từ các thành viên gửi về mỗi thành viên là một Folder. Do vậy nhờ thầy, cô và anh chị trên diễn đàn viết giúp em chương trình VBA để tổng hợp các file .txt này từ các Folder vào file Excel ạ
Yêu cầu của chương trình là khi chọn vào Buttom TỔNG HỢP chương trình sẽ cho phép chọn nhiều Folder chứa các file .txt cần tổng hợp, khi chọn xong chương trình tổng hợp theo yêu cầu sau:
Ở cột A "Tên Folder" chương trình sẽ ghi lần lượt tên Folder chứa file cần tổng hợp vào cột này khi tổng hợp
Ở cột B "Tên File" chương trình sẽ ghi lần lượt tên File chữa dữ liệu cần tổng hợp vào cột này khi tổng hợp
Ở cột C "Số TT", Cột D "X", Cột E "Y" chương trình tổng hợp và ghi dữ liệu có trong các file vào
Như file mẫu em gửi kèm ạ
Em cảm ơn thầy, cô và các anh chị trên diễn đàn nhiều ạ
Nếu chịu khó mày mò thì bài viết này có thể đáp ứng được yêu cầu của bạn. Bạn tham gia GPE cũng đã khoảng 10 năm sao không tự nghiên cứu để tự xử lý những yêu cầu công việc của mình cho khỏe.
www.giaiphapexcel.com/diendan/threads/t%E1%BB%95ng-quan-v%E1%BB%81-filesystemobject.95898/
Lâu lắm mới thấy anh quanghai1969 xuất hiện trên diễn đàn em tham gia diễn đàn cũng lâu và cũng được rất nhiều thầy, cô và các anh chị giúp đỡ em cũng mày mò nghiên cứu về VBA nhưng vẫn chỉ dừng lại là ứng dụng và tùy biến từ những chương trình được các thành viên giúp đỡ anh ạ. Về bản chất của VBA như thế nào thì em lại không hiểu rõ do vậy có những chương trình em không biết phải bắt đầu từ đâu. Nên up lên hỏi trên diễn đàn và nhờ giúp đỡ để phục vụ cho công việc của mình
Em cảm ơn anh quanghai1969 đã giúp đỡ em rất nhiều từ các chương trình trước. Mong anh và các thành viên diễn đàn giúp em chương trình này ạ
Mình chỉ muốn giúp bạn hướng đi để tự giải quyết bài này. Code bên dưới sẽ cho bạn tên file đầy đủ của file để có thể dùng lệnh OpenTextFile của FSO để xử lý dữ liệu của file text. Phần tên file và tên folder cũng có kèm theo.
Chúc thành công
Sub Main()
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
With Application.FileDialog(msoFileDialogFolderPicker)
If .Show Then
GetAllFiles .SelectedItems(1), fso
End If
End With
End Sub
Function GetAllFiles(ByVal StrFolder As String, fso As Object)
Dim objFolder As Object, objSubFolder As Object, File As Object
Set objFolder = fso.GetFolder(StrFolder)
For Each File In objFolder.Files
MsgBox File.path 'ten day du cua file
MsgBox File.Name 'ten file
MsgBox objFolder.Name 'ten thu muc
Next
For Each objSubFolder In objFolder.SubFolders
GetAllFiles objSubFolder.path, fso
Next objSubFolder
End Function
Bạn có thể tổng hợp file qua công cụ Power query của Excel có file tham khảo cách bên dưới, thay đổi lại đường dẫn cho phù hợp trong máy của bạn ở sheet KQ ô H2. Nhược điểm công cụ này thì chỉ hỗ trợ từ Excel 2010 trở đi, do bạn gửi là Excel 2003 nên mình chỉ gửi file tham khảo
Khi bạn sử dụng thành thạo công Power Query, Power Pivot khi đó rất nhiều vấn đề không cần tới VBA hỗ trợ
Vì thấy phiên bản của bạn dùng được power query thì mình hướng dẫn như sau:
Vào Data tab/Get data/ From File/From Folder
Bạn chọn thư mục chứa các file text, nó sẽ list tất cả files bạn cần gộp, sau đó bạn tại combobox: Combine thì chọn Combine & Load
Chọn OK đến khi dữ liệu được fill, bạn sẽ thấy nó có các cột như file text và thêm 1 cột là file name
Bạn muốn thêm cột cho đường dẫn folder thì vào Query tab chọn Edit, 1 cửa sổ power query hiện ra
Bạn vào Advance Edit, xem và thêm vào sau chỗ Source.Name bằng "Folder Path" là được. Lưu ý là làm theo cụm giống source.name nhé
Tuyệt vời quá anh ạ hôm qua xem anh làm em thấy công tác tổng hợp dữ liệu của em không còn là vấn đề khó khăn nữa. Chúc anh sức khỏe nhé
Nếu được anh có thể cho em xin đia chỉ Mail của anh hoặc facebook để gặp vấn đề gì xin phép được làm phiền anh
Em cảm ơn anh!Với Power query thì việc tổng họp dữ liệu không thành vấn đề, bài trước mình đã nói với bạn chỉ cần tìm hiểu công cụ này sẽ có rất nhiều thứ không cần VBA hỗ trợ. Nếu muốn thành thạo Power query thì phải tìm hiểu thêm công thức xử lý liệu còn gọi là Power query M Function, khi thành thạo tôi đảm bảo với bạn tất cả những thứ VBA làm được thì Power Query làm được, vì chúng xin ra là xử lý dữ liệu thô thành dữ liệu sạch. Khi muốn dữ liệu sạch thành những con số biết nói chuyện thì dùng Power Pivot + Power View, còn muốn sinh động hơn nữa thì dùng Power BI
Còn file của mình gửi máy bạn không chạy được là do chưa set up vài tuỳ chọn, mình có ultra vào máy bạn hôm qua xem lại đã làm thành công, đính chính lại mình vs quanluu1989 là 2 người khác nhau.
Xin cảm ơn
Vấn đề ở chỗ có thể tìm ra 1 lệnh duy nhất trong VBA để duyệt tới và chọn nhiều thư mục hay không. Tất nhiên không có 1 lệnh như thế. Còn nếu tự viết code thì có gì khó đâu.
Không có việc gì khó. Chỉ sợ ……………. đầu lười suy nghĩ.
Nếu lập trình Windows API thì có thể dùng vd. (chỉ là ý tưởng sơ qua thôi) interface IShellFolder + method EnumObjects + … Nhưng nói cho cùng thì sao phải khổ thế? Sao phải đi con đường đầy chông gai? Vì thực ra ta chỉ cần lấy về tên các thư mục được chọn, tức các chuỗi. Tất nhiên user phải có khả năng di chuyển tới thư mục đích trên drive cụ thể để chọn các thư mục con trong thư mục đích.
Thuật toán là:
1. Đặt trên UserForm 1 ListView với View = lvWIcon, 1 ComboBox, Label với Caption = "<"
2. Trong UserForm_Initialize dùng FileSystemObject để lấy các drive vào combobox. và chọn mục đầu tiên.
3. Trong combobox_change thì đọc ra thư mục hiện hành trên drive được chọn và nhập vào biến toàn cục currFolder. Đồng thời gọi sub listFolder
4. Sub listFolder: Trước hết xóa hết các item của ListView. Tiếp theo dùng FileSystemObject để lấy danh sách các thư mục con của thư mục currFolder. Với mỗi thư mục con thì tạo item cho ListView với Caption = tên thư mục con.
5. Với DoubleClick của ListView: đọc ra item đang được chọn với tên của thư mục được chọn -> đổi currFolder thành đường dẫn tới thư mục đang được chọn -> gọi listFolder.
6. Label2_Click: từ currFolder xác định thư mục cha của thư mục currFolder. Nếu có cha thì đổi currFolder thành thư mục cha rồi gọi listFolder. Nếu không có cha vì currFolder là thư mục chính trên drive thì không làm gì.
Như vậy user chuyển drive bằng cách chọn trong ComboBox. Đúp chuột lên item của ListView để chuyển thư mục currFolder thành thư mục được click và hiện các thư mục con trong ListView. Click Label2 để chuyển tới thư mục cha của thư mục hiện hành. Nếu user nhấn OK thì 1 mảng với tên các thư mục được chọn sẽ được trả về. Trong ví dụ thì các tên sẽ được hiện bằng Debug.Print.
Lưu ý:
1. Nếu lập trình trong Delphi thì Delphi có control ListView. Nhưng cũng có thể dùng API để tự tạo ListView. Nói cho cùng thì Delphi cũng tạo ListView bằng API. Trong VBA cũng có thể tạo ListView bằng API.
Tóm lại thuật toán là thế. Còn implement trong Delphi, VB, VBA thì tùy. Cũng có thể không dùng ListView mà thêm các Label thay cho thêm các item vào ListView. Tất nhiên phải sắp xếp các Label theo hàng và cột. Và thay đúp chuột trên ListView bằng đúp chuột trên các Label.
Thuật toán chỉ là 1 nhưng các chi tiết implement thuật toán đó có thể tùy biến (ngôn ngữ lập trình, controls).
2. Hiện code hiện cả thùng rác và các thư mục "cấm" của system. Đây chỉ là ví dụ, chi tiết thì ai thích người ấy tự làm.
3. Code chưa xử lý nhiều trường hợp lỗi có thể sảy ra vì nó chỉ là ví dụ.
4. Có thể chọn icon cho các item của ListView để đẹp mắt. Tôi không làm vì đây chỉ là ví dụ.
5. Code được test trên Windows XP Home 32 bit + Excel 2010 32 bit, và Windows 10 64 bit + Excel 2007 32 bit.
www.giaiphapexcel.com/diendan/threads/t%E1%BB%95ng-h%E1%BB%A3p-file-txt-t%E1%BB%AB-nhi%E1%BB%81u-folders-v%C3%A0o-file-excel.143706/page-4#posts
Khóa học Power PI – Ứng dung trong Nhân sự
TỔNG QUAN KHÓA HỌC: POWER BI CHO NGÀNH NHÂN SỰ Khóa học Power BI cho Nhân sự được thiết kế dành riêng cho các...
Xem khóa học
Về code dài ngắn, khổ hay không, chưa chắc cái nào hơn cái nào. Chắc chắn code của ta không phức tạp với những người biết VBA, chắc chắn không dài. Vậy ai khổ đây, hay đọc mà không hiểu nhỉ. Không đơn giản hơn. Đọc code thì thấy code của ta thì tất cả các dòng rất nhiều người có thể tự viết. Cái mấu chốt chỉ là ý tưởng.
Không hiểu ý thì nói cho hiểu nhé. Ta cố tình không dùng API vì API với nhiều người vẫn còn xa lạ. Không phải ta không biết SHBrowseForFolder nhưng đó là API rồi. Nói chung là không hiểu được ý của người ta thì nên im lặng.
1. Về code của khongtu19bk khi mở thì ví dụ ta có thư mục C:. Ví dụ trong C: có thư mục Excel. Nếu ta muốn liệt kê các thư mục con của Ecel thì lại phải nhấn nút Open -> duyệt tới và chọn Excel. Trong code của tôi chỉ là đúp chuột trên Excel.
2. Trong code của khongtu19bk nếu muốn chọn vài thư mục con thì phải click từng thư mục. Trong code của tôi có thể click 1 thư mục -> giữ Shift và click thư mục khác. Cũng có thể click "điểm trống" ở phía trên bên trái 1 thư mục rồi giữ nhấn và kéo tới điểm khác. Toàn bộ các icon trong vùng hình chữ nhật sẽ được chọn. Tất nhiên có thể giữ Ctrl và click từng icon để chọn nhiều.
Có đúng như thao tác trong Excplorer không? Y hệt hoặc gần y hệt như trong Explorer. Với code của khongtu19bk thì không như thế.
3. Với code của tôi mà thêm icon thì nhìn như trong các thư mục trên đĩa không? Đâu có là danh sách các tên trong từng dòng?
Đọc code, nhìn biểu diễn mà không nhìn thấy sự khác nhay giữa 2 code, không hiểu gì thì quá yếu.
Nói chung giỏi gì thì chuyên về cái đó đi, những cái không hiểu thì ngồi im mà nghe người khác nói. Ta đã chỉ ra cái vụ unicode hồi nào với BOM và không BOM, cãi chầy cối rồi cuối cùng vẫn không biết mở tập tin sao cho đúng. Còn lý lẽ: thế ai đó không biết chọn encoding thì sao. Thì cho nghỉ việc thôi chứ sao nữa. Thế sếp giao cho việc mà cần mở CSV trong Excel mà lại không biết mở thì sao? Thì xin nghỉ việc chứ sao nữa. Lý lẽ là tôi có tập tin unicode nhưng tôi mở trong Word nhưng không biết chọn encoding sao cho đúng thì chỉ là lý sự cùn. Không biết mở thì học cách mở. Học mà vẫn không biết thì xin nghỉ việc. Thế thôi.
Dù sao đây chỉ là ví dụ khác với ví dụ của khongtu19bk. Còn hơn nhiều những người chỉ biết mỗi cách LOOP hoặc copy code của người khác từ trên mạng về và tìm cách dịch sang VBA. Con người ta ăn nhau ở cái ý tưởng, cách tư duy, chịu suy nghĩ. Còn trưng code của người khác để người ta nhìn vào thấy hoa mắt, dùng các từ shlwapi.dll, shell32.dll tới msi.dll cho dân đen nhìn thấy mà sợ thì chỉ là trò làm cho bạn gái lác mắt mà thôi. Ta không phải thuộc loại đó.
Dù sao ta cũng đưa ra 1 ý tưởng, và có code đàng hoàng. Còn hơn viết 1 loạt bài chỉ ở mức ăn tục nói phét, chưa đưa ra được 1 dòng code, thì đừng lên mặt dạy người khác nhé.
Trên Delphi, C++, .NET thì thư viện không có sẳn control nào như thế, nhưng ngoài thị trường thì hằng hà sa số các cty, cá nhân viết bán hoặc free các custom control, class dạng này. Nhiều không đếm xuể…
Trên Delphi, bạn Mạnh thử TFileOpenDialog với options fdoPickFolders Or fdoAllowMultiSelect thử xem sao. Do máy cùi bắp vp của tui không có cài RAD Studio nên không thử được.
Còn custom component làm sẵn thì bạn Mạnh tham khảo vài cái ở đây thử:
1. https://www.gtro.com/delphi/gtrocheckshelltreeview_e.php
2. [URL='www.ssware.com/articles/shbrowseforfolder-unmasked-everything-you-wanted-to-know-about-the-windows-folder-browser-component.htm']www.ssware.com/articles/shb…bout-the-windows-folder-browser-component.htm
3. http://www.jam-software.com/shellbrowser_delphi/
….
Nếu muốn dùng cho VBA thì phải build DLL cho VBA gọi thôi, không còn cách nào khác, hay viết OCX.
Không phải thù dai. Tranh luận đúng sai là chuyện thường, nhưng tôi không thích kiểu tranh luận cù nhầy.
Nếu ở bài #72 bạn viết thế này thì tôi sẽ chẳng trả lời bạn gì cả. Vì thực chất tôi không trả lời cho chủ chủ đề, cho bạn hay bất cứ ai khác ngoài kieu manh. Và tôi cho là hiểu ý kieu manh như thế. Chỉ có kieu manh mới có quyền giải thích cụ thể hơn cho tôi về yêu cầu của mình. Viết bài trong một chủ đề nào đó không có nghĩa là trả lời cho vấn đề của chủ chủ đề. Đôi khi là sự trao đổi với người khác trong số những người đọc chủ đề. Tôi không quan tâm bạn muốn gì nên bạn không cần phải giải thích cho tôi.
Trong bài #72 bạn có thể thông báo các mong đợi của mình cho mọi người. Nhưng bạn chọn cách chê bai, nói khóe bài của tôi. Ai là người thù dai đây bạn. Bạn không cần trả lời vì đây là câu hỏi tu từ. Và tôi cũng không cần câu trả lời. Khi viết trả lời cho kieu manh thậm chí tôi không đọc tất cả các bài, không biết tới sự tồn tại của ý tưởng của khongtu19bk. Bài của tôi không có ý là nên dùng thay cho bất cứ cái gì. Nó chỉ nhằm mục đích chỉ ra là: có thể tự viết code để lấy về nhiều thư mục, và có đặc điểm giống như ta thao tác chọn nhiều thư mục con trong Explorer, và code đó hoàn toàn có thể ngắn gọn và dễ hiểu. Chỉ ra khả năng, và sự đơn giản của nó. Thế thôi. Tôi không nói là dùng nó để thay thế cái gì.
Tôi nhắc lại là tôi đã không quan tâm bạn muốn gì. Tôi trả lời cho mỗi kieu manh thôi. Những thằng chả đưa ra một code cụ thể nào mà chỉ ngồi nói phét thì tôi khinhh. Giỏi thì đưa ra code của mình cho mọi người học tập. Cho mọi người thấy cái thiên tài của mình. Cho mọi người ngưỡng mộ. Còn nếu không đưa ra được code thì ngồi im nghe người khác nói. Nếu thay vì code chỉ phun ra những từ "kêu to" thì quá tầm thường. Chỉ hù họa được bọn không biết gì, các bé mới lớn mà thôi. Quá tầm thường.
Nhắc lại: Nếu giỏi thì tung code ra cho mọi người ngưỡng mộ. Còn không thì đừng chê bai, nói khóe. Ghét nhất những bọn ăn tục nói phét, cù nhầy, lý sự cùn.
Tôi hiểu cái nỗi khổ của bạn.
Nếu mắt không nhìn thấy, mũi không ngửi thấy thì lòng thanh thản. Còn nếu người ta chỉ nhử nhử cái đùi gà trước mặt nhưng không cho, trong tầm tay mà không với tới được, thì ……………. không có cái khổ nào như cái khổ này. 😀
Bạn đã nói là chỉ cần chút gợi ý ABC thôi để bạn từ đó phát triển lên. Vậy tôi cho bạn ABC. Trước hết hãy chạy EXE xem đúng ý chưa. Tất nhiên chỉ ABC còn tôi không còn hứng phát triển lên. Vd. viết phục vụ Unicode. Tôi chỉ dùng Delphi 5 thôi. Tất nhiên có những bộ controls unicode cho Delphi 5 nhưng hồi xưa tôi cài để vọc chứ bây giờ không dùng. Nói chung mấy trò API này khoảng hơn 20 năm trước tôi chơi hàng ngày. Bây giờ già rồi không chơi nữa. Vì chơi về system, API thì chơi hết rồi.
Chú ý:
– muốn chọn thư mục nào thì click vào nó. Muốn bỏ chọn do chọn nhầm thì click lần nữa vào nó. Nhưng không click ngay được sau khi chọn nhầm để bỏ chọn. Phải click thư mục khác mà mình muốn chọn rồi sau đó click thư mục chọn nhầm. CheckBox sẽ được đánh dấu nếu thư mục được chọn.
– chỉ click tên thư mục chứ không click checkbox. Code tự đánh dấu checkbox. Mà thậm chí click checkbox thì kết quả sẽ sai do code tự đánh dấu.
– khi nhấn OK mà có các thư mục được chọn thì chúng sẽ được nạp vào Memo.
– chương trình không phục vụ Unicode vì tôi viết trong Delphi 5.
– đã chạy thử trên XP Home + Excel 2010 32 bit, và Windows 10 64 bit + Excel 2007 32 bit.
Nếu vừa ý thì tôi sẽ gửi cho code viết trong Delphi 5.
Thôi thôi. Bạn muốn ABC để nghiên cứu nên tôi bỏ công ra cho ABC. Bạn tự làm tiếp thôi.
Tất cả các hàm API mà tôi dùng thì bạn cũng từng đọc, từng dùng rồi. Chả có hàm nào lạ với bạn cả. Còn 2 macro TreeView_*** (Nếu thích bạn có thể thay bằng SendMessage – hãy đọc help trong Delphi để biết) cũng có luôn trong Delphi 5, và như vậy chắc cũng có trong Delphi mới hơn. Chả có hàm nào bạn chưa dùng cả. Mấu chốt chỉ là ý tưởng mà thôi. Code cũng ngắn cũn cỡn nên chắc là không làm bạn mệt.
1564071054
À trong code chỉ có 1 chỗ duy nhất là
Tôi nghĩ là nên thay bằng
A, B là tôi viết tắt.
Chỉ có duy nhất 1 chỗ có dạng IF … AND … > 0 THEN