Chia sẻ: Hàm lấy dữ liệu từ file text vào Excel và ghi từ Excel sang file text.

Liên hệ QC

Maika8008

Thành viên gạo cội
Tham gia
12/6/20
Bài viết
4,763
Được thích
5,718
Donate (Momo)
Donate
Giới tính
Nam
Thấy nhiều người có nhu cầu lấy dữ liệu từ file dạng text như .txt, .xml,... sang Excel để xử lý tổng hợp, báo cáo, đồng thời cũng xuất dữ liệu từ Excel lưu sang file dạng text, cho nên tôi viết 2 hàm để làm điều ấy.

1. Hàm ấy dữ liệu từ file text vào Excel: Kết quả trả về của hàm là 1 cửa sổ Excel mới chứa dữ liệu lấy được. Có thể gọi hàm từ code VBA để lưu vào mảng hoặc ghi ra sheet, hoặc gõ trực tiếp trên cell của trang tính. Khi gọi hàm trực tiếp trên trang tính thì tại cell chứa công thức sẽ chỉ chuỗi "Xong roi! và sau đó chuyển sang cửa sổ kết quả.
Rich (BB code):
Function GetText_FromFile(ByVal sFullName As String, Optional ByVal OptSeparator = vbTab)
'sFullName - ten file voi duong dan day du
'OptSeparator - Tuy chon dau phan cach du lieu giua cac truong (field) trong 1 dong (record). Mac dinh la vbTab

Dim st As Object, ExApp As Object, ExBook As Object
Dim sMyFile$, sText$
Dim aTmp, aLine, aRsl
Dim iLine&, i&, j&, iCol&

    On Error GoTo Loi
    sMyFile = sFullName
    Set st = CreateObject("ADODB.Stream")
    
    With st
        .Charset = "utf-8"
        .Open
        .LoadFromFile (sMyFile)
        sText = .ReadText(-1)
        
        If InStr(1, sText, Chr(10)) Then
            aTmp = Split(sText, Chr(10))
            iLine = UBound(aTmp)
            ReDim aRsl(1 To iLine, 1 To 1000)
            For i = 0 To iLine - 1
                aLine = Split(aTmp(i), OptSeparator)
                If UBound(aLine) > iCol Then iCol = UBound(aLine)
                For j = 0 To UBound(aLine)
                    aRsl(i + 1, j + 1) = aLine(j)
                Next
            Next i
            If UBound(aRsl) > 0 And iCol = 0 Then iCol = 1
            ReDim Preserve aRsl(1 To iLine, 1 To iCol)
            Set ExApp = CreateObject("Excel.Application")
            Set ExBook = ExApp.Workbooks.Add
            ExApp.Visible = True
            ExBook.Sheets(1).Range("A1").Resize(UBound(aRsl), UBound(aRsl, 2)).Value = aRsl
            GetText_FromFile = "Xong roi!"
            ExBook.Activate
        Else
            GetText_FromFile = sText
        End If
        .Close
    End With
    
    Set st = Nothing
    Exit Function
Loi:
    Set st = Nothing
    MsgBox "Da co loi." & vbNewLine & "Ma loi: " & Err.Number & vbNewLine & Err.Description
End Function

2. Hàm ghi từ Excel sang file text: Kết quả trả về của hàm file text theo định dạng do người chỉ định trong đối số của hàm và lưu cùng đường dẫn với file chứa hàm. Có thể gọi hàm từ code VBA hoặc gõ trực tiếp trên cell của trang tính. Khi gọi hàm trực tiếp trên trang tính thì tại cell chứa công thức sẽ trả về đường dẫn file kết quả.
Mã:
Function WriteText_ToExistsFile(ByVal MyRange As Range, ByVal SFile As String, _
                                Optional ByVal dExt As String = ".txt", _
                                Optional ByVal OptJoin As Boolean = True)
'MyRange - Vung du lieu can ghi vao file text
'sFile - File nguon .txt (hoac co the laf 1 file dang text bat ky: sql, bat, css,...)
'dExt - Phan mo rong cua file muon luu lai: Mac dinh la ".txt", giong file nguon. Muon luu dang khac thi ghi ro ".sql", ".bat", ...
'OptJoin - Tuy chon noi du lieu file nguon voi du lieu moi (True: noi du lieu cu, False: ghi moi, xoa du lieu cu)

Dim st As Object, aData
Dim i&, j&, iDot&, iSCells
Dim sMyFile$, sFileSaveAs$, sWrite$

    On Error GoTo Loi
    sMyFile = ThisWorkbook.Path & "\" & SFile  'File nguon
    iDot = InStr(1, dExt, ".")
    If iDot = 0 Then
        sFileSaveAs = ThisWorkbook.Path & "\" & Left(SFile, InStr(1, SFile, ".")) & dExt
    Else
        sFileSaveAs = ThisWorkbook.Path & "\" & Left(SFile, InStr(1, SFile, ".") - 1) & dExt
    End If
    aData = MyRange.Value           'Du lieu muon ghi vao file text
    iSCells = MyRange.Cells.Count
    
    Set st = CreateObject("ADODB.Stream")
    With st
        .Type = 2
        .Charset = "utf-8"
        .Open
        If OptJoin = True Then
            .LoadFromFile (sMyFile)   'Mo file
            .ReadText -1    'Doc file
        End If
        If iSCells = 1 Then
            .WriteText aData & Chr(10)
        Else
            For i = 1 To UBound(aData, 1)
                For j = 1 To UBound(aData, 2)
                    sWrite = sWrite & IIf(aData(i, j) = "", "NULL", aData(i, j)) & vbTab
                Next
                .WriteText sWrite & Chr(10): sWrite = ""
            Next
        End If
        On Error Resume Next
        .SaveToFile sFileSaveAs, 2 'Luu file
        .Close
    End With
    Set st = Nothing
    WriteText_ToExistsFile = "Da luu file tai " & sFileSaveAs
    Exit Function
Loi:
    Set st = Nothing
    MsgBox "Da co loi." & vbNewLine & "Ma loi: " & Err.Number & vbNewLine & Err.Description

End Function

Tất nhiên khi viết tôi chưa lường hết các nhu cầu người dùng về cách lấy text và cũng không thể tránh khỏi lỗi chạy. Nếu sử dụng có lỗi hoặc nhu cầu gì thêm, các bạn báo lại cho tôi biết để chỉnh sửa.
 
Sao mình đính kèm File mẫu đi anh, cho người mới họ dễ dàng hơn. Thân !
 
Upvote 0

Text có rất nhiều encoding.
Tập tin text đâu phải lúc nào encoding cũng là utf-8 đâu anh.

Ví dụ

1657168263813.png

Kết quả:
A1 là code của anh, kết quả bị lỗi nhé.

1657168253472.png

Cần nhận biết được encoding là gì mới lấy được dữ liệu chuẩn.
 

File đính kèm

  • Text_.txt
    36 bytes · Đọc: 9
Upvote 0
Text có rất nhiều encoding.
Tập tin text đâu phải lúc nào encoding cũng là utf-8 đâu anh.

Ví dụ

View attachment 278493

Kết quả:
A1 là code của anh, kết quả bị lỗi nhé.

View attachment 278494

Cần nhận biết được encoding là gì mới lấy được dữ liệu chuẩn.
Vụ đó tôi chưa biết. Cứ tạm thời utf-8 cái đã cho đơn giản... hà hà.
Bài đã được tự động gộp:

Sao mình đính kèm File mẫu đi anh, cho người mới họ dễ dàng hơn. Thân !
Có gì đâu ngoài 2 cái hàm. Có thể chép vài dòng dữ liệu nào đó rồi thử cũng được mừ.
P/S: tôi mò mẫm thử lấy từ file Word ra nhưng ra đầu lâu xương sọ không à. Không biết thực sự có lấy chữ tiếng Việt từ file Word ra được không?
 
Lần chỉnh sửa cuối:
Upvote 0
Nhân tiện tôi đang viết cái Class cFso trên Delphi trong đó có txt File nên cũng thử chút

Tôi vẻ ra cho thôi ... viết thêm code check cái File đó If là a thì chạy Else chạy B = thế thôi :p

Xem hình tôi cũng đang thử tí

1657197577420.png


Và nhiều Hàm khác nữa chuyên xử lý txt ... lấy mọi kiểu dữ liệu vào 1 Array xong còn lại ta muốn làm gì thì tùy ý

1657197980452.png
 
Lần chỉnh sửa cuối:
Upvote 0
code trên Delphi họ viết cho hết rồi còn tôi chỉ khai báo có 1 dòng code thôi
nên ko viết nhiều dòng cho nhọc ... Tôi viết thêm bài này vì sợ ai đó suy nghĩ trong phạm vi x ... cho tôi copy code trên sẻ là điều hoang tưởng ... mà chỉ cảm Ơn File của bài số 3 ...... 1 chút cho tôi ý tưởng code thế thôi

Chấm hết
 
Upvote 0
Chủ thớt và mọi người giúp e cái này với ạ: E có một thư mục chứa nhiều file text. E muốn lấy dữ liệu từ các file text này vào một sheet, dữ liệu mỗi file trên một hàng, phân cách cột là dấu xuống dòng trong file text. Đồng thời lấy được tên file text vào cột đầu tiên thì càng tốt ạ.
Mong các bác giúp e ạ. E cản ơn ạ.
 
Upvote 0
Chủ thớt và mọi người giúp e cái này với ạ: E có một thư mục chứa nhiều file text. E muốn lấy dữ liệu từ các file text này vào một sheet, dữ liệu mỗi file trên một hàng, phân cách cột là dấu xuống dòng trong file text. Đồng thời lấy được tên file text vào cột đầu tiên thì càng tốt ạ.
Mong các bác giúp e ạ. E cản ơn ạ.
Được.
Nhưng bạn nên lập chủ đề mới để khỏi chồng lấn.
 
Upvote 0
Được.
Nhưng bạn nên lập chủ đề mới để khỏi chồng lấn.
Bác giúp em với ạ
 
Lần chỉnh sửa cuối:
Upvote 0
Bác giúp e với ạ
1. Dứt khoát là cứ e với e thì không giúp. Nếu hà tiện khi viết tiếng Việt thì thôi, đường ai nấy đi.
2. Nếu đã đáp ứng mục 1 thì => Chủ đề của bạn bên kia không có file text nào cả nên tôi chưa làm gì. Chừng nào có file, biết cấu trúc dữ liệu nguồn, biết muốn lấy qua file Excel kiểu nào thì mới làm.
 
Upvote 0
1. Dứt khoát là cứ e với e thì không giúp. Nếu hà tiện khi viết tiếng Việt thì thôi, đường ai nấy đi.
2. Nếu đã đáp ứng mục 1 thì => Chủ đề của bạn bên kia không có file text nào cả nên tôi chưa làm gì. Chừng nào có file, biết cấu trúc dữ liệu nguồn, biết muốn lấy qua file Excel kiểu nào thì mới làm.
Em xin lỗi ạ, lần đầu đăng bài nên chưa nhớ, sau này em sẽ chú ý ạ.
 
Upvote 0
Nhân tiện tôi đang viết cái Class cFso trên Delphi trong đó có txt File nên cũng thử chút

Tôi vẻ ra cho thôi ... viết thêm code check cái File đó If là a thì chạy Else chạy B = thế thôi :p

Xem hình tôi cũng đang thử tí

View attachment 278518


Và nhiều Hàm khác nữa chuyên xử lý txt ... lấy mọi kiểu dữ liệu vào 1 Array xong còn lại ta muốn làm gì thì tùy ý

View attachment 278519
Bác Mạnh có cách viết rất yomos. Đọc hoài lâu lâu vẫn chưa hiểu lắm.
 
Upvote 0
Thấy nhiều người có nhu cầu lấy dữ liệu từ file dạng text như .txt, .xml,... sang Excel để xử lý tổng hợp, báo cáo, đồng thời cũng xuất dữ liệu từ Excel lưu sang file dạng text, cho nên tôi viết 2 hàm để làm điều ấy.

....

Tất nhiên khi viết tôi chưa lường hết các nhu cầu người dùng về cách lấy text và cũng không thể tránh khỏi lỗi chạy. Nếu sử dụng có lỗi hoặc nhu cầu gì thêm, các bạn báo lại cho tôi biết để chỉnh sửa.

Có thời gian bác phân tích, so sánh xem giữa các cách đọc file TEXT như: ADODB Stream, FSO, GET vba, Line Input (Free File) xem thử về mặt tốc độ đọc file dung lượng lớn, file non-unicode v.v.. xem điểm mạnh/ yếu của các cách đó như thế nào, trường hợp nào lấy công cụ nào ra xài. :)
 
Upvote 0
Có thời gian bác phân tích, so sánh xem giữa các cách đọc file TEXT như: ADODB Stream, FSO, GET vba, Line Input (Free File) xem thử về mặt tốc độ đọc file dung lượng lớn, file non-unicode v.v.. xem điểm mạnh/ yếu của các cách đó như thế nào, trường hợp nào lấy công cụ nào ra xài. :)
Mất công quá bác ơi. Thôi, em chả, em chả!
 
Upvote 0
khi nào viết xong hãy thử chạy 1 dòng For cho nó Lưu 99999 dòng xem nó hết mấy giây

Tôi thử Lưu Kiều Văn Mạnh & i = thì file nó ra theo hình sau ... chỉ mất khoãng 2 giây chi đó
File có 775 MB thôi
1657271145861.png
 
Upvote 0
Là sao, tôi không biết? Bạn làm ơn giải thích chút đi!
Để chút tối rảnh tôi test lại, có thể tôi sai vấn đề này. Nếu dùng ADO để đọc dữ liệu vào Recordset thì phải dùng thêm file schema.ini để ADO nó tham chiếu kiểu dữ liệu từng cột được khai báo trong file schema.ini, nếu không có file này thì ADO sẽ dựa vào dữ liệu của 8 dòng đầu tiên để suy ra kiểu dữ liệu (Data Type).
Còn đối với ADO Stream thì tôi chưa test nên không biết nó có đọc sai kiểu dữ liệu không.
 
Upvote 0
Rảnh tôi mới thử code của bài số 1 một tẹo xem sao thì tôi vẻ ra cho mà viết tiếp nè
Áp dụng cho Office 2010 to 365 với số dòng là 1048576

1/ Hãy thử lưu xuống File *.txt với số dòng là 1048570 thôi bỏ đi 6 dòng
2/ Hãy thử lấy nó lên Xem sao ??? ....
...... xử lý cái dòng thứ 2 ấy:p
 
Upvote 0
Tôi tách ra 1 chủ đề khác cùng thể loại ... Ai quan tâm qua Link sau :p
 
Upvote 0
Web KT

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

Back
Top Bottom