thnghiachau
Chỉ biết ngồi BÈ và PHÁN chuyện!!!
- Tham gia
- 14/9/09
- Bài viết
- 844
- Được thích
- 710
- Giới tính
- Nam
- Nghề nghiệp
- Search
Mở file xem cấu trúc dữ liệu sẽ té ngửaTôi chưa xem tập tin của bạn. Tôi trả lời theo tin tưởng là bạn đã giải thích vấn đề mạch lạc, không có uẩnn khúc "nhưng mà..."
Có hai cách để thực hiện, tuỳ theo tập tin lớn hay vừa phải.
1. nếu không lớn lắm thì dùng cách stream cả file vào một string. Sau đó dùng vbCRLF để split string ra thành từng dòng. Tìm số dấu phẩy. Lấy Max
2. nếu tập tin lớn thì bắt buộc phải đọc từng dòng.
Mở file bằng FileSSystemObject cũng được mà mở theo channel thì giản dị hơn.
Đại khái:
Dim fName As String, sLine As String
Dim cMax As Long, cCur As Long
strFile = "C:\Test\abcdef.txt"
Open fName For Input As #1
Do Until EOF(1)
Line Input #1, sLine
cCur = Len(sLine) - Len(Replace(sLine, ",", "")) + 1
If cCur > cMax Then cMax = cCur
Loop
Close #1
' cMax là số cột
Nếu trong dữ liệu có dấu phẩy thì hơi rắc rối hơn. Phải dùng RegEx để duyệt chuỗi.
Làm sao biết 10 cột?Chào GPE,
Xin cho hỏi có cách nào để xác định File text có bao nhiêu cột như trong tập tin đính kèm bằng VBA không ạ?
Ví dụ trong tập tin đính kèm là có 10 cột.
Xin cám ơn.
Em bon chen tý, bác thử xem:Chào GPE,
Xin cho hỏi có cách nào để xác định File text có bao nhiêu cột như trong tập tin đính kèm bằng VBA không ạ?
Ví dụ trong tập tin đính kèm là có 10 cột.
Xin cám ơn.
Option Explicit
Public Function co_lùm(ByVal sPath As String, ByVal sBookName As String) As Integer
Dim sFileName As String, book As Workbook
sFileName = sPath & "\" & sBookName
Call Workbooks.OpenText(sFileName, Origin:=65001, Tab:=True, Comma:=False, Semicolon:=False)
Set book = Workbooks(Workbooks.Count)
co_lùm = book.Worksheets(1).UsedRange.Columns.Count
book.Close False
End Function
Sub tét()
Dim i As Integer
i = co_lùm("C:\Users\N\Downloads", "abcdef.txt")
MsgBox i
End Sub
Làm sao biết 10 cột?
ý kiến này khá là "hay" đây...Em bon chen tý, bác thử xem:
Mã:Option Explicit Public Function co_lùm(ByVal sPath As String, ByVal sBookName As String) As Integer Dim sFileName As String, book As Workbook sFileName = sPath & "\" & sBookName Call Workbooks.OpenText(sFileName, Origin:=65001, Tab:=True, Comma:=False, Semicolon:=False) Set book = Workbooks(Workbooks.Count) co_lùm = book.Worksheets(1).UsedRange.Columns.Count book.Close False End Function Sub tét() Dim i As Integer i = co_lùm("C:\Users\N\Downloads", "abcdef.txt") MsgBox i End Sub
Cám ơn Bác nhiều...Tôi chưa xem tập tin của bạn. Tôi trả lời theo tin tưởng là bạn đã giải thích vấn đề mạch lạc, không có uẩnn khúc "nhưng mà..."
Có hai cách để thực hiện, tuỳ theo tập tin lớn hay vừa phải.
1. nếu không lớn lắm thì dùng cách stream cả file vào một string. Sau đó dùng vbCRLF để split string ra thành từng dòng. Tìm số dấu phẩy. Lấy Max
2. nếu tập tin lớn thì bắt buộc phải đọc từng dòng.
Mở file bằng FileSSystemObject cũng được mà mở theo channel thì giản dị hơn.
Đại khái:
Dim fName As String, sLine As String
Dim cMax As Long, cCur As Long
strFile = "C:\Test\abcdef.txt"
Open fName For Input As #1
Do Until EOF(1)
Line Input #1, sLine
cCur = Len(sLine) - Len(Replace(sLine, ",", "")) + 1
If cCur > cMax Then cMax = cCur
Loop
Close #1
' cMax là số cột
Nếu trong dữ liệu có dấu phẩy thì hơi rắc rối hơn. Phải dùng RegEx để duyệt chuỗi.
Một ý tưởng hay... nhưng mà phải duyệt từng hàng và từng ký tự trong mỗi hàng
để được như vậy thì phải thêm "điều kiện" để biết được khi nào là bắt đầu cột khác... Bởi vì trong một cột, dữ liệu có thể có khoảng trắng chèn vào!Có làm sao đâu bạn.
Khai báo 2 danh sách: vị trí bắt đầu, và số lượng ký tự. Vậy là được.
Theo kiểu mà befaint gợi ý ở bài #10, tôi nhớ là trước đây cũng có một bài như vậy và nó ở link này. Link.để được như vậy thì phải thêm "điều kiện" để biết được khi nào là bắt đầu cột khác... Bởi vì trong một cột, dữ liệu có thể có khoảng trắng chèn vào!
Hazzz... vậy mình chắc phải qui định ít nhất là 2 khoảng trắng cuối cột trước khi vào cột mới?
Anh dùng option gì trong Notepad++ để hiện thị thay thế "khoảng trắng" vậy.File này phân cách cột bằng các khoảng trắng, không phải Tab, không phải dấu phẩy nên dùng kiểu của anh Vetmini không ra. Tôi thường dùng cách của Vetmini (dùng FreeFile) đối với file Text (CSV), nhưng dạng này thì chưa ra.
View attachment 273816
Function TotalColumn(ByVal strFullNameTextFile As String) As integer
Const FORREADING = 1
Dim strLineText As String
Dim i As Long
Dim objDic As Object
Set objDic = CreateObject("Scripting.Dictionary")
objDic.Add 1, "" '1stPos of Col
With CreateObject("Scripting.FileSystemObject").OpenTextFile(strFullNameTextFile, FORREADING)
Do While .AtEndOfStream <> True
strLineText = .ReadLine
' Get Pos of Column of Existing Text File => size of Column
i = 3
Do While i <= Len(strLineText)
If Mid(strLineText, i - 2, 2) = " " And Mid(strLineText, i, 1) <> " " Then
If Not objDic.Exists(i) Then objDic.Add i, ""
End If
i = i + 1
Loop
Loop
.Close
End With
TotalColumn = objDic.Count
End Function
Có lẽ là vậy theo bác @befaint nhỉ...
Dạ, Em muốn từ việc "biết cách tìm số cột" mà mình sẽ tìm ra ý tưởng cho việc lấy dữ liệu ah.Và nội dung trên mình nêu là để xử lý lấy dữ liệu, chứ viết code đếm cột làm gì. @@
Cám ơn anh, em coi code trong bài anh gởi đã ra cái em muốn rồi ah...Theo kiểu mà befaint gợi ý ở bài #10, tôi nhớ là trước đây cũng có một bài như vậy và nó ở link này. Link.
Bạn xem và chỉnh sửa lại. File của bạn đơn giản hơn file trong bài trên.
Muốn phân tích file text thì phải biết trước delimiter của cacxs trường là gì. Ở trên, tôi chỉ minh hoạ điển hình nếu nó là dấu phẩy.Mở file xem cấu trúc dữ liệu sẽ té ngửa
Làm sao biết 10 cột?
Python có nhiều dính dáng đến Unix. Trong Unix, Lisp và Perl xử lý text rất êm.Cái này cho vào Python chạy ngon.
Tôi có nói, nếu dạng phức tạp thì phải dùng RegEx để tính.File này phân cách cột bằng các khoảng trắng, không phải Tab, không phải dấu phẩy nên dùng kiểu của anh Vetmini không ra. Tôi thường dùng cách của Vetmini (dùng FreeFile) đối với file Text (CSV), nhưng dạng này thì chưa ra.
...
Khi sử dụng FileSystemObject thì data từng hàng sẽ OK@Thớt: nếu không bắt buộc phải dùng FileSystemObject thì không nên dùng. Mở file bằng đường lối channel truyền thống ít lệ thuộc vào hệ thống điều hành.
Dạ... Cám ơn Bác nhiều...Người ta dùng Line Input, bạn sửa thành Input rồi kêu ca. Bạn chuyển lại về Line Input xem sao.
View attachment 273832
Trong công việc bạn phải giải quyết nhiều vấn đề, chọn phương pháp nào là do bạn quyết định, không ai bắt bạn phải dùng phương pháp này hay cấm dùng phương pháp kia.Dạ... Cám ơn Bác nhiều...
Đúng là con sai rồi ah....
Nhân tiện cho con hỏi thêm: Nếu muốn mở file text (UNICODE) thì câu lệnh
Open strFullNameTextFile For Input As #1
mình phải chỉnh lại như thế nào ah?
Cám ơn Bác nhiều
Con xin cám ơn Bác đã hướng dẫn.Trong công việc bạn phải giải quyết nhiều vấn đề, chọn phương pháp nào là do bạn quyết định, không ai bắt bạn phải dùng phương pháp này hay cấm dùng phương pháp kia.
Nếu là tôi tôi sẽ dùng Open của VBA trong các trường hợp đơn giản. Trong trường hợp unicoded thì tôi dùng CreateObject với FileSystemObject. Nếu cứ cố tình làm khổ mình thì tôi có lẽ dùng Open nhưng với mode = Binary.
Open sFile For Binary As #1
Lúc này dùng Get để đọc dữ liệu. Có lẽ phải đọc toàn bộ. Sau đó nếu muốn chia thành từng dòng, mỗi dòng chia theo từng đoạn ngăn cách bởi dấu phẩy, chấm phẩy hay gì đó thì phải tự làm, vd. dùng Instr để tìm chỗ phân cách. Nếu bạn muốn vọc thì thử xem.
Dùng FileSystemObject cũng giải quyết được công việc thì chả lý gì lại cứ phải Open của VBA. Trừ phi phải thi thố, đố nhau kiểu: dùng ít FOR nhất, code ít chữ nhất, không được dùng FileSystemObject. Nếu thế thì bạn chờ người khác.
Ở trên tôi có nói là FileSystemObject là công cụ của Wondows Script....
Dùng FileSystemObject cũng giải quyết được công việc thì chả lý gì lại cứ phải Open của VBA. Trừ phi phải thi thố, đố nhau kiểu: dùng ít FOR nhất, code ít chữ nhất, không được dùng FileSystemObject. Nếu thế thì bạn chờ người khác.
Từ chỗ tôi không nghe thấy. Nói thực ra thì anh hàng xóm của người ta có thể là ân nhân đối với nhiều người. Nhưng mình cứ nghĩ tới năm 1979 khi mà nhà cửa, trường học, bệnh viện của mình bị dội bom, người mình bị giết ... Nếu mình có chút đồng cảm thì không bao giờ mình cười trên đau khổ của người khác. Họ cũng có hàng xóm như mình.ah, bên Bác có "nghe ầm ầm từ Ukraine không vậy?
Không có chỗ nào tôi nói là BẮT BUỘC phải dùng FileSystemObject. Tôi chỉ nói là nếu tôi thì tôi dùng. Còn ai đó không thể dùng mà cứ phải bắt buộc Open thì tôi cũng chỉ ra là làm được. Nhưng vất vả thêm thôi. Chứ nói như bác thì ta tìm tất cả các code trên GPE mà dùng FileSystemObject rồi khuyên mọi người chuyển sang channel truyền thống?Ở trên tôi có nói là FileSystemObject là công cụ của Wondows Script.
Đọc file qua channel truyền thống là để tránh phụ thuộc vào nền tảng.
Điển hình, máy Mac của tôi không chạy được những code sử dụng API/ActiveX.
Bác quên rằng tôi là tín đồ của "If it ain't broke, don't fix it".... Chứ nói như bác thì ta tìm tất cả các code trên GPE mà dùng FileSystemObject rồi khuyên mọi người chuyển sang channel truyền thống?
Ý anh ấy không bảo anh sửa, mà bảo anh xúi người khác sửa. (Theo ngữ cảnh thì thêm chữ "chả lẽ")Bác quên rằng tôi là tín đồ của "If it ain't broke, don't fix it".
Hơi đâu mà lôi đồ cũ ra sửa lại.
Chữ "chả lẽ" là của tôi, nhưng dựa vào ngữ cảnh câu sau (nguyên văn ngoại trừ chữ đỏ):"chả lẽ" là của anh chứ của tôi làm gì có "chả lẽ"![]()
Chứ nói như bác thì (chả lẽ) ta tìm tất cả các code trên GPE mà dùng FileSystemObject rồi khuyên mọi người chuyển sang channel truyền thống?
Bác nói đúng. Con rất là ghét chiến tranh dù là bất cứ lý do nào... nhưng mình là "dân đen" thì không dám nói chính trị vậy... hic... Nếu mình có chút đồng cảm thì không bao giờ mình cười trên đau khổ của người khác. Họ cũng có hàng xóm như mình.