Cần giúp đỡ viết code VBA về việc lấy tên và nội dung nhiều file text vào trong excel (5 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

thungdols

Thành viên chính thức
Tham gia
27/3/09
Bài viết
66
Được thích
2
em có bài toán khó này mong các bác, các anh cùng các chị giúp đỡ. Nội dung em để trong file đính kèm. Chân thành cám ơn sự giúp đỡ của mọi người. Em cũng đã tìm hiểu 1 số phương pháp lấy dữ liệu từ các file text trên diễn đàn rồi. Nhưng chẳng có cái nào phù hợp với yêu cầu của em cả. với yêu cầu nhỏ là tên file text để 1 cột, nội dung file text thì nhiều cột.... em có làm ví dụ trong file nén. bao gồm file text và kết quả. Chân thành cám ơn sự giúp đỡ của mọi người
 

File đính kèm

Lần chỉnh sửa cuối:
anh chị giúp em với .... cám ơn các anh chị
 
Lần chỉnh sửa cuối:
sao không thấy ai giúp em vậy?? Làm ơn giúp em đi mà. em gửi lời cám ơn trước.**~****~****~**
 
Lần chỉnh sửa cuối:
Bạn thư xem nhé. Mình sẽ sửa câu trả lời sau để rõ ràng hơn cho bạn hiểu. Bạn nên để mỗi mặt hàng trên 1 dòng sẽ dễ hơn. Code này chưa có ErrorHandling, bạn tự thêm nhé :)

PHP:
Sub test()
    Dim strFileName As Variant
    Dim i, j As Integer
    Dim oFSO As FileSystemObject
    Set oFSO = New FileSystemObject
    Dim oFS As TextStream
    Dim content As String
    Dim splittedContent() As String
    Dim tenHang As String
    Dim soLuong As String
    Dim tenFile As String
    Dim count As Integer
    count = 1
        'mo hop thoai chon text file
    strFileName = Application.GetOpenFilename("Text Files (*.txt), *.txt",  Title:="Select files", MultiSelect:=True)
    Application.ScreenUpdating = False
        If IsArray(strFileName) Then
        For i = LBound(strFileName) To UBound(strFileName)
            'doc file
            Set oFS = oFSO.OpenTextFile(strFileName(i))
            content = oFS.ReadAll
            
            For Each Line In Split(content, vbNewLine)
               tenHang = ""
                splittedContent = Split(Line, " ")

               For j = 0 To UBound(splittedContent) - 2
                    tenHang = tenHang + splittedContent(j) + " "
                Next j
               
                tenHang = RTrim(tenHang)
                soLuong = splittedContent(UBound(splittedContent))
                tenFile = GetFilenameFromPath(strFileName(i))

               With ActiveSheet
                    .Cells(count, 1) = Left(tenFile, Len(tenFile) - 4)
                    .Cells(count, 2) = tenHang
                    .Cells(count, 3) = soLuong
                End With

                count = count + 1
            Next
            oFS.Close
       Next i
    End If 
    Application.ScreenUpdating = True
End Sub
Function GetFilenameFromPath(ByVal strPath As String) As String
' Returns the rightmost characters of a string upto but not including the rightmost '\'' e.g. 'c:\winnt\win.ini' returns 'win.ini'
    If Right$(strPath, 1) <> "\" And Len(strPath) > 0 Then
        GetFilenameFromPath = GetFilenameFromPath(Left$(strPath, Len(strPath) - 1)) + Right$(strPath, 1)
    End If
End Function
 

File đính kèm

Lần chỉnh sửa cuối:
em có bài toán khó này mong các bác, các anh cùng các chị giúp đỡ. Nội dung em để trong file đính kèm. Chân thành cám ơn sự giúp đỡ của mọi người. Em cũng đã tìm hiểu 1 số phương pháp lấy dữ liệu từ các file text trên diễn đàn rồi. Nhưng chẳng có cái nào phù hợp với yêu cầu của em cả. với yêu cầu nhỏ là tên file text để 1 cột, nội dung file text thì nhiều cột.... em có làm ví dụ trong file nén. bao gồm file text và kết quả. Chân thành cám ơn sự giúp đỡ của mọi người

Rảnh rỗi "moi" lại bài này xem chơi!
Bài tuy dễ nhưng có 1 THÁCH ĐỐ cho mọi người: Bằng cách nào giải quyết bài toán của tác giả trong 1 vòng lập duy nhất (không dùng Transpose)
Ẹc... Ẹc...
 
Rảnh rỗi "moi" lại bài này xem chơi!
Bài tuy dễ nhưng có 1 THÁCH ĐỐ cho mọi người: Bằng cách nào giải quyết bài toán của tác giả trong 1 vòng lập duy nhất (không dùng Transpose)
Ẹc... Ẹc...

Đây là lời giải của em (hơi dài + code linh tinh - nhưng chạy, không dùng Transpose, có thể dùng 1 vòng lặp hoặc không dùng vòng lặp nào - nếu recursive ko bị tính là vòng lặp)

PHP:
public countGlobal as Integer
Sub moFile()
countGlobal = 1
Dim strFileName As Variant
strFileName = Application.GetOpenFilename("Text Files (*.txt), *.txt", _
                  Title:="Select files", MultiSelect:=True)
                      readFiles strFileName:=strFileName, count:=1
End Sub
Function readFiles(ByVal strFileName As Variant, ByVal count As Integer) As String
   Dim content As String
    Dim tenFile As String
    Dim oFSO As FileSystemObject
    Set oFSO = New FileSystemObject
    Dim oFS As TextStream
        If count <= UBound(strFileName) Then
        Set oFS = oFSO.OpenTextFile(strFileName(count))
        content = oFS.ReadAll
                count = count + 1
        tenFile = Left(GetFilenameFromPath(strFileName(count - 1)), Len(GetFilenameFromPath(strFileName(count - 1))) - 4)
                processFile content:=content, lineNum:=0, strFileName:=tenFile
        readFiles strFileName:=strFileName, count:=count
            End If 
   readFiles = content
End Function
Function processFile(content As String, lineNum As Integer, strFileName As String)
    Dim splitted() As String
    Dim sl As Integer
    Dim th As String
    splitted = Split(content, vbNewLine)
        If lineNum <= UBound(splitted) Then
        sl = extractSoLuong(splitted(lineNum))
        th = extractTenHang2(splitted(lineNum))
       Debug.Print countGlobal & "."; strFileName & " - "; sl & " x " & th
        With ActiveWorkbook.Sheets(1)
                    .Cells(countGlobal, 1) = strFileName
                    .Cells(countGlobal, 2) = th
                    .Cells(countGlobal, 3) = sl
        End With
        countGlobal = countGlobal + 1
        lineNum = lineNum + 1
        processFile content:=content, lineNum:=lineNum, strFileName:=strFileName
            End If    processFile = sl
End Function
Function extractSoLuong(line)
    Dim elem() As String
        elem = Split(line, " ")
    extractSoLuong = elem(UBound(elem))
End Function
Function extractTenHang(line)
    Dim elem() As String
    elem = Split(line, " ")
        For j = 0 To UBound(elem) - 2
            tenHang = tenHang + elem(j) + " "
    Next j 
   extractTenHang = RTrim(tenHang)
End Function
Function extractTenHang2(line)
    extractTenHang2 = Left(line, InStrRev(line, "x") - 2)
End Function
 

File đính kèm

Lần chỉnh sửa cuối:
Đây là lời giải của em (hơi dài + code linh tinh - nhưng chạy, không dùng Transpose, có thể dùng 1 vòng lặp hoặc không dùng vòng lặp nào - nếu recursive ko bị tính là vòng lặp)

Xét về mặt kỹ thuật thì đệ quy cũng là vòng lập... và đương nhiên ý tôi không phải là cách này
Tôi nói 1 VÒNG LẬP nghĩa là 1 vòng lập thật sự, không ăn gian
Ẹc... Ẹc...
----------------
Lưu ý: Khi bạn dùng 1 công cụ nào đó được viết sẵn của MS như Advanced Filter chẳng hạn, thì ta có thể xem là không có vòng lập (bên trong công cụ ấy có vòng lập hay không ta không quan tâm)
 
Lần chỉnh sửa cuối:
Xét về mặt kỹ thuật thì đệ quy cũng là vòng lập... và đương nhiên ý tôi không phải là cách này
Tôi nói 1 VÒNG LẬP nghĩa là 1 vòng lập thật sự, không ăn gian
Ẹc... Ẹc...
----------------
Lưu ý: Khi bạn dùng 1 công cụ nào đó được viết sẵn của MS như Advanced Filter chẳng hạn, thì ta có thể xem là không có vòng lập (bên trong công cụ ấy có vòng lập hay không ta không quan tâm)

Haha, em đã biết chắc là sẽ thế :)) nên mới nói nếu không tính recursive ^^. Sẽ thử dùng WorksheetFunction xem sao :))

em thì chẳng biết mù gì về VBA. nhưng em thấy áp dụng code VBA vào để lấy nội dung file text vào excell cũng áp dụng được vào lấy nội dung tin nhắn từ điện thoại vào excell. em tìm trên diễn đàn thấy có code của anh ndu96081631 em áp dụng vào thấy cũng ok. Mỗi tội nó lấy cả toàn bộ code của tin nhắn. Mong anh ndu96081631 hộ em làm chỉ lấy ở cột A là tên của người gửi tin nhắn như trong ví dụ của em là X, nội dung của tin nhắn thì ở cột B. Cám ơn anh trước nhé.

Bạn nên lập 1 chủ đề mới.
 
Haha, em đã biết chắc là sẽ thế :)) nên mới nói nếu không tính recursive ^^. Sẽ thử dùng WorksheetFunction xem sao :))



Bạn nên lập 1 chủ đề mới.

Bạn dùng WorksheetFunction là tùy ý, nhưng tôi thì không dùng cách này.
Một vòng lập là để duyệt qua các file TXT, phần còn lại sẽ không thêm vòng lập nào nữa
(Tôi dùng 1 đối tượng... khác. Nói chung là code cũng đơn giản. Các bạn cứ suy nghĩ, nếu không được tôi sẽ đưa đáp án của tôi)
 
Bạn dùng WorksheetFunction là tùy ý, nhưng tôi thì không dùng cách này.
Một vòng lập là để duyệt qua các file TXT, phần còn lại sẽ không thêm vòng lập nào nữa
(Tôi dùng 1 đối tượng... khác. Nói chung là code cũng đơn giản. Các bạn cứ suy nghĩ, nếu không được tôi sẽ đưa đáp án của tôi)

Bác cho cái deadline có gì các bạn còn cố gắng :D
 
Bạn dùng WorksheetFunction là tùy ý, nhưng tôi thì không dùng cách này.
Một vòng lập là để duyệt qua các file TXT, phần còn lại sẽ không thêm vòng lập nào nữa
(Tôi dùng 1 đối tượng... khác. Nói chung là code cũng đơn giản. Các bạn cứ suy nghĩ, nếu không được tôi sẽ đưa đáp án của tôi)
em thử sức với code này :
Mã:
Option Explicit
Sub GPE()
    Dim FileName, i&, tmpStr$, str$, stype$
        FileName = Application.GetOpenFilename(, , , , True)
        If IsArray(FileName) Then
           For i = LBound(FileName) To UBound(FileName)
                tmpStr = FileName(i)
                stype = Right(tmpStr, Len(tmpStr) - InStrRev(tmpStr, "\"))
                stype = Left(stype, InStr(1, stype, ".") - 1)
                stype = stype & vbTab
            '........................................................................................................................
                tmpStr = CreateObject("scripting.filesystemObject").OpenTextFile(FileName(i)).ReadAll
                tmpStr = Replace(tmpStr, ",", vbCrLf)
                tmpStr = Replace(tmpStr, "x", vbTab)
                tmpStr = Replace(tmpStr, vbLf, stype)
                tmpStr = stype & Trim(tmpStr)
                str = str & tmpStr & vbCrLf
            Next
         
            '.................................................................................................
        With CreateObject("new:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
            .Clear: .SetText str: .PutInClipboard
        End With
        Range("A10").PasteSpecial
     End If
End Sub
code của em chỉ xuât hiện duy nhất 1 cặp "FOR ..NEXT" thì em hiểu chỉ có duy nhất 1 vòng lặp, còn số vòng lặp thực sự là bao nhiêu thì em chịu luôn :D
 
Lần chỉnh sửa cuối:
em thử sức với code này :
Mã:
Option Explicit
Sub GPE()
    Dim FileName, i&, tmpStr$, str$, stype$
        FileName = Application.GetOpenFilename(, , , , True)
        If IsArray(FileName) Then
           For i = LBound(FileName) To UBound(FileName)
                tmpStr = FileName(i)
                stype = Right(tmpStr, Len(tmpStr) - InStrRev(tmpStr, "\"))
                stype = Left(stype, InStr(1, stype, ".") - 1)
                stype = stype & vbTab
            '........................................................................................................................
                tmpStr = CreateObject("scripting.filesystemObject").OpenTextFile(FileName(i)).ReadAll
                tmpStr = Replace(tmpStr, ",", vbCrLf)
                tmpStr = Replace(tmpStr, "x", vbTab)
                tmpStr = Replace(tmpStr, vbLf, stype)
                tmpStr = stype & Trim(tmpStr)
                str = str & tmpStr & vbCrLf
            Next
         
            '.................................................................................................
        With CreateObject("new:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
            .Clear: .SetText str: .PutInClipboard
        End With
        Range("A10").PasteSpecial
     End If
End Sub
code của em chỉ xuât hiện duy nhất 1 cặp "FOR ..NEXT" thì em hiểu chỉ có duy nhất 1 vòng lặp, còn số vòng lặp thực sự là bao nhiêu thì em chịu luôn :D

Dùng DataObject <---- Chính xác là cái tôi muốn nói đến
Code của tôi:
Mã:
Function TexttoTable(ByVal txtFile As String, ByVal LineChar As String, ByVal TabChar As String) As String
  Dim n As Long
  Dim sName As String, text As String
  Dim FSO As Object
  On Error GoTo ExitSub
  Set FSO = CreateObject("Scripting.FileSystemObject")
  sName = Mid(txtFile, InStrRev(txtFile, "\") + 1)
  sName = Left(sName, Len(sName) - 4)
  With FSO.OpenTextFile(txtFile, 1, , -2)
    text = .ReadAll
    .Close
  End With
  text = Replace(text, TabChar, vbTab)
  text = Replace(text, LineChar, vbLf & sName & vbTab)
  TexttoTable = sName & vbTab & text
  Set FSO = Nothing
ExitSub:
End Function
Mã:
Sub Main()
  Dim vFile, fileItem, arr()
  Dim n As Long
  Dim txtFile As String
  Dim clbObj As Object
  Set clbObj = CreateObject("new:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
  vFile = Application.GetOpenFilename("Text Files, *.txt", , , , True)
  If IsArray(vFile) Then
    For Each fileItem In vFile
      txtFile = CStr(fileItem)
      n = n + 1
      ReDim Preserve arr(1 To n)
      arr(n) = TexttoTable(txtFile, ", ", " x ")
    Next
    With clbObj
      .Clear
      .SetText Join(arr, vbLf)
      .PutInClipboard
    End With
    Range("A1").PasteSpecial
  End If
  Set clbObj = Nothing
End Sub
Chỉ mới là bước triển khai giải thuật thôi, chưa tính đến chuyện bẫy lỗi tinh vi đâu
 
Web KT

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

Back
Top Bottom