Lấy dữ liệu từ file txt trong nhiều thư mục khác nhau sang excel

Liên hệ QC

tranvanhung2009

Thành viên hoạt động
Tham gia
1/3/11
Bài viết
128
Được thích
18
Xin chào anh chị trong diễn đàn.
Em có 1 file excel cần tổng hợp các file txt trong 1 thư mục khác nhau. Trong thư mục tổng "laydulieu" chứa nhiều thư mục con "L10_4coc_ad=3", "L10_4coc_ad=4" ... trong các thư mục con này gồm 2 thư mục con nữa là "P" và "S".
Em đã sưu tầm được code để lấy được dữ liệu từ các file txt trong các thư mục con này. Tuy nhiên vẫn phải chỉ định vào thư mục cụ thể. Nhờ anh chị sửa đoạn code trong file excel đính kèm để mình có thể chỉnh sửa đoạn code trong file đính kèm. Khi mình chỉ định thư mục tổng là "laydulieu" sau đó code tự tìm đến các thư mục tương ứng và điền dữ liễu vào 2 sheet tương ứng là Dulieu_P và Dulieu_S.
Em xin chân thành cám ơn các anh chị!
 

File đính kèm

  • Laydulieu.rar
    1.3 MB · Đọc: 16
Mình đã tìm được đoạn code này khá hay. Tuy nhiên để vận dụng vào đọc dữ liệu các file txt trong thư mục mình chưa làm được. Mong được mọi người giúp đỡ.

Option Explicit

Sub ListAllFilesInAllFolders()

Dim MyPath As String, MyFolderName As String, MyFileName As String
Dim i As Integer, F As Boolean
Dim objShell As Object, objFolder As Object, AllFolders As Object, AllFiles As Object
Dim MySheet As Worksheet
Dim key
On Error Resume Next

'************************
'Select folder
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.BrowseForFolder(0, "", 0, 0)
If Not objFolder Is Nothing Then
MyPath = objFolder.self.Path & "\"
Else
Exit Sub
End If
Set objFolder = Nothing
Set objShell = Nothing

'************************
'List all folders

Set AllFolders = CreateObject("Scripting.Dictionary")
Set AllFiles = CreateObject("Scripting.Dictionary")
AllFolders.Add (MyPath), ""
i = 0
Do While i < AllFolders.Count
key = AllFolders.Keys
MyFolderName = Dir(key(i), vbDirectory)
Do While MyFolderName <> ""
If MyFolderName <> "." And MyFolderName <> ".." Then
If (GetAttr(key(i) & MyFolderName) And vbDirectory) = vbDirectory Then
AllFolders.Add (key(i) & MyFolderName & "\"), ""
End If
End If
MyFolderName = Dir
Loop
i = i + 1
Loop

'List all files
For Each key In AllFolders.Keys
MyFileName = Dir(key & "*.txt")
'MyFileName = Dir(Key & "*.PDF") 'only PDF files
Do While MyFileName <> ""
AllFiles.Add (key & MyFileName), ""
MyFileName = Dir
Loop
Next

'************************
'List all files in Files sheet

For Each MySheet In ThisWorkbook.Worksheets
If MySheet.Name = "Files" Then
Sheets("Files").Cells.Delete
F = True
Exit For
Else
F = False
End If
Next
If Not F Then Sheets.Add.Name = "Files"

Sheets("Files").[a1].Resize(AllFolders.Count, 1) = WorksheetFunction.Transpose(AllFolders.Keys)
Sheets("Files").[b1].Resize(AllFiles.Count, 1) = WorksheetFunction.Transpose(AllFiles.Keys)
Set AllFolders = Nothing
Set AllFiles = Nothing
End Sub
 
Xin chào anh chị trong diễn đàn.
Em có 1 file excel cần tổng hợp các file txt trong 1 thư mục khác nhau. Trong thư mục tổng "laydulieu" chứa nhiều thư mục con "L10_4coc_ad=3", "L10_4coc_ad=4" ... trong các thư mục con này gồm 2 thư mục con nữa là "P" và "S".
Em đã sưu tầm được code để lấy được dữ liệu từ các file txt trong các thư mục con này. Tuy nhiên vẫn phải chỉ định vào thư mục cụ thể. Nhờ anh chị sửa đoạn code trong file excel đính kèm để mình có thể chỉnh sửa đoạn code trong file đính kèm. Khi mình chỉ định thư mục tổng là "laydulieu" sau đó code tự tìm đến các thư mục tương ứng và điền dữ liễu vào 2 sheet tương ứng là Dulieu_P và Dulieu_S.
Em xin chân thành cám ơn các anh chị!
Chạy sub Main . . .
Mã:
Option Explicit
Sub Main()
  Dim FSo As Object, strFolder$, sFolder As Object, oFile As Object, TS As Object
  Dim rngP As Range, rngS As Range
 
  'On Error Resume Next
  Set FSo = CreateObject("Scripting.FileSystemObject")
  strFolder = GetFolder()
  If strFolder = Empty Then Exit Sub
  Set rngP = Dulieu_P.Range("A2")
  Set rngS = Dulieu_S.Range("A2")
  For Each sFolder In FSo.GetFolder(strFolder).SubFolders
    If FSo.FolderExists(sFolder & "\P") Then
      For Each oFile In FSo.GetFolder(sFolder & "\P").files
        If UCase(FSo.GetExtensionName(oFile)) Like "TXT" Then
          Set TS = FSo.OpenTextFile(oFile, 1, , -2)
          Call ImportTextFiles(rngP, TS, 0)
        End If
      Next
    End If
    If FSo.FolderExists(sFolder & "\S") Then
      For Each oFile In FSo.GetFolder(sFolder & "\S").files
        If UCase(FSo.GetExtensionName(oFile)) Like "TXT" Then
          Set TS = FSo.OpenTextFile(oFile, 1, , -2)
          Call ImportTextFiles(rngS, TS, 0)
        End If
      Next
    End If
  Next
  Set FSo = Nothing: Set sFolder = Nothing
  Set oFile = Nothing: Set TS = Nothing
End Sub

Function GetFolder(Optional strPath As String = Empty) As String
  With Application.FileDialog(msoFileDialogFolderPicker)
    .Title = "Chon Folder chua các file cân tông hop"
    .AllowMultiSelect = False
    .InitialFileName = strPath
    If .Show = -1 Then GetFolder = .SelectedItems(1)
  End With
End Function

Private Sub ImportTextFiles(ByRef rngP, ByRef TS, ByVal k&)
  Dim Arr(), lines, items
  Dim r&, c&, linecount&, text$

  lines = Split(TS.ReadAll, vbCrLf)
  If UBound(lines) > 0 Then
    linecount = UBound(lines)
    ReDim Arr(1 To linecount, 1 To 1)
    For r = 1 To linecount
      text = lines(r)
      If text <> "" Then
        If text <> String(Len(text), vbTab) Then
          k = k + 1
          items = Split(text, vbTab)
          If UBound(Arr, 2) < UBound(items) + 1 Then ReDim Preserve Arr(1 To linecount, 1 To UBound(items) + 1)
          For c = 1 To UBound(Arr, 2)
            Arr(k, c) = items(c - 1)
          Next c
        End If
      End If
    Next r
  End If
  If k Then
    rngP.Resize(k, UBound(Arr, 2)).Value = Arr
    Set rngP = rngP.Offset(k + 1)
  End If
End Sub
 
Chạy sub Main . . .
Mã:
Option Explicit
Sub Main()
  Dim FSo As Object, strFolder$, sFolder As Object, oFile As Object, TS As Object
  Dim rngP As Range, rngS As Range
 
  'On Error Resume Next
  Set FSo = CreateObject("Scripting.FileSystemObject")
  strFolder = GetFolder()
  If strFolder = Empty Then Exit Sub
  Set rngP = Dulieu_P.Range("A2")
  Set rngS = Dulieu_S.Range("A2")
  For Each sFolder In FSo.GetFolder(strFolder).SubFolders
    If FSo.FolderExists(sFolder & "\P") Then
      For Each oFile In FSo.GetFolder(sFolder & "\P").files
        If UCase(FSo.GetExtensionName(oFile)) Like "TXT" Then
          Set TS = FSo.OpenTextFile(oFile, 1, , -2)
          Call ImportTextFiles(rngP, TS, 0)
        End If
      Next
    End If
    If FSo.FolderExists(sFolder & "\S") Then
      For Each oFile In FSo.GetFolder(sFolder & "\S").files
        If UCase(FSo.GetExtensionName(oFile)) Like "TXT" Then
          Set TS = FSo.OpenTextFile(oFile, 1, , -2)
          Call ImportTextFiles(rngS, TS, 0)
        End If
      Next
    End If
  Next
  Set FSo = Nothing: Set sFolder = Nothing
  Set oFile = Nothing: Set TS = Nothing
End Sub

Function GetFolder(Optional strPath As String = Empty) As String
  With Application.FileDialog(msoFileDialogFolderPicker)
    .Title = "Chon Folder chua các file cân tông hop"
    .AllowMultiSelect = False
    .InitialFileName = strPath
    If .Show = -1 Then GetFolder = .SelectedItems(1)
  End With
End Function

Private Sub ImportTextFiles(ByRef rngP, ByRef TS, ByVal k&)
  Dim Arr(), lines, items
  Dim r&, c&, linecount&, text$

  lines = Split(TS.ReadAll, vbCrLf)
  If UBound(lines) > 0 Then
    linecount = UBound(lines)
    ReDim Arr(1 To linecount, 1 To 1)
    For r = 1 To linecount
      text = lines(r)
      If text <> "" Then
        If text <> String(Len(text), vbTab) Then
          k = k + 1
          items = Split(text, vbTab)
          If UBound(Arr, 2) < UBound(items) + 1 Then ReDim Preserve Arr(1 To linecount, 1 To UBound(items) + 1)
          For c = 1 To UBound(Arr, 2)
            Arr(k, c) = items(c - 1)
          Next c
        End If
      End If
    Next r
  End If
  If k Then
    rngP.Resize(k, UBound(Arr, 2)).Value = Arr
    Set rngP = rngP.Offset(k + 1)
  End If
End Sub
Em xin chân thành cám ơn Thầy ạ!
 
Chạy sub Main . . .
Mã:
Option Explicit
Sub Main()
  Dim FSo As Object, strFolder$, sFolder As Object, oFile As Object, TS As Object
  Dim rngP As Range, rngS As Range
 
  'On Error Resume Next
  Set FSo = CreateObject("Scripting.FileSystemObject")
  strFolder = GetFolder()
  If strFolder = Empty Then Exit Sub
  Set rngP = Dulieu_P.Range("A2")
  Set rngS = Dulieu_S.Range("A2")
  For Each sFolder In FSo.GetFolder(strFolder).SubFolders
    If FSo.FolderExists(sFolder & "\P") Then
      For Each oFile In FSo.GetFolder(sFolder & "\P").files
        If UCase(FSo.GetExtensionName(oFile)) Like "TXT" Then
          Set TS = FSo.OpenTextFile(oFile, 1, , -2)
          Call ImportTextFiles(rngP, TS, 0)
        End If
      Next
    End If
    If FSo.FolderExists(sFolder & "\S") Then
      For Each oFile In FSo.GetFolder(sFolder & "\S").files
        If UCase(FSo.GetExtensionName(oFile)) Like "TXT" Then
          Set TS = FSo.OpenTextFile(oFile, 1, , -2)
          Call ImportTextFiles(rngS, TS, 0)
        End If
      Next
    End If
  Next
  Set FSo = Nothing: Set sFolder = Nothing
  Set oFile = Nothing: Set TS = Nothing
End Sub

Function GetFolder(Optional strPath As String = Empty) As String
  With Application.FileDialog(msoFileDialogFolderPicker)
    .Title = "Chon Folder chua các file cân tông hop"
    .AllowMultiSelect = False
    .InitialFileName = strPath
    If .Show = -1 Then GetFolder = .SelectedItems(1)
  End With
End Function

Private Sub ImportTextFiles(ByRef rngP, ByRef TS, ByVal k&)
  Dim Arr(), lines, items
  Dim r&, c&, linecount&, text$

  lines = Split(TS.ReadAll, vbCrLf)
  If UBound(lines) > 0 Then
    linecount = UBound(lines)
    ReDim Arr(1 To linecount, 1 To 1)
    For r = 1 To linecount
      text = lines(r)
      If text <> "" Then
        If text <> String(Len(text), vbTab) Then
          k = k + 1
          items = Split(text, vbTab)
          If UBound(Arr, 2) < UBound(items) + 1 Then ReDim Preserve Arr(1 To linecount, 1 To UBound(items) + 1)
          For c = 1 To UBound(Arr, 2)
            Arr(k, c) = items(c - 1)
          Next c
        End If
      End If
    Next r
  End If
  If k Then
    rngP.Resize(k, UBound(Arr, 2)).Value = Arr
    Set rngP = rngP.Offset(k + 1)
  End If
End Sub
Em còn 1 vấn đề muốn hỏi thêm Thầy nữa là: số thứ tự của file được chọn trong thư mục nó không theo thứ tự đặt tự động trong windown. Nên khó kiểm soát được kết quả. Cho em hỏi có lựa chọn nào để code chọn file theo thứ tự trong windown không ạ? Chữ màu đỏ là code đã chọn thứ tự file. Còn trong windown thì theo số thứ tự của tên fileaa.png
 
Em còn 1 vấn đề muốn hỏi thêm Thầy nữa là: số thứ tự của file được chọn trong thư mục nó không theo thứ tự đặt tự động trong windown. Nên khó kiểm soát được kết quả. Cho em hỏi có lựa chọn nào để code chọn file theo thứ tự trong windown không ạ? Chữ màu đỏ là code đã chọn thứ tự file. Còn trong windown thì theo số thứ tự của tên fileView attachment 271417
Kiểm tra lại . . .
Mã:
Option Explicit
Sub Main()
  Dim FSo As Object, strFolder$, sFolder As Object, aFolder()
  Dim rngP As Range, rngS As Range, i&, k&
 
  'On Error Resume Next
  Set FSo = CreateObject("Scripting.FileSystemObject")
  strFolder = GetFolder()
  If strFolder = Empty Then Exit Sub
  Dulieu_P.UsedRange.ClearContents
  Dulieu_S.UsedRange.ClearContents
  Set rngP = Dulieu_P.Range("A2")
  Set rngS = Dulieu_S.Range("A2")
  For Each sFolder In FSo.GetFolder(strFolder).SubFolders
    k = k + 1
    ReDim Preserve aFolder(1 To k)
    aFolder(k) = sFolder
  Next
  Call QuickSort(aFolder, k, True) 'True: A->Z, False: Z->A
  For i = LBound(aFolder) To UBound(aFolder)
    If FSo.FolderExists(aFolder(i) & "\P") Then
      Call GetTxtFile(rngP, FSo, aFolder(i) & "\P")
    End If
    If FSo.FolderExists(aFolder(i) & "\S") Then
      Call GetTxtFile(rngS, FSo, aFolder(i) & "\S")
    End If
  Next
End Sub

Private Sub GetTxtFile(rng, FSo, ByVal iPath$)
  Dim oFile As Object, TS As Object, aFile(), q&, r&

  For Each oFile In FSo.GetFolder(iPath).files
    q = q + 1
    ReDim Preserve aFile(1 To q)
    aFile(q) = oFile
  Next
  Call QuickSort(aFile, q, True) 'True: A->Z, False: Z->A
  For r = LBound(aFile) To UBound(aFile)
    If UCase(FSo.GetExtensionName(aFile(r))) Like "TXT" Then
      Set TS = FSo.OpenTextFile(aFile(r), 1, , -2)
      Call ImportTextFiles(rng, TS, 0)
    End If
  Next
End Sub

Private Sub QuickSort(sArr, k, Optional bASC As Boolean = True)
  'bASC=True: A->Z , bASC=False: Z->A
  Dim arr, C&(), tmp$, sRow&, fR&, i&, r&
 
  fR = LBound(sArr)
  arr = sArr
  ReDim C(fR To k)
  For i = fR To k - 1
    tmp = sArr(i)
    For r = i + 1 To k
      If (tmp > sArr(r)) = bASC Then C(i) = C(i) + 1 Else C(r) = C(r) + 1
    Next r
  Next i
  For i = fR To k
    sArr(C(i) + fR) = arr(i)
  Next i
End Sub

Function GetFolder(Optional strPath As String = Empty) As String
  With Application.FileDialog(msoFileDialogFolderPicker)
    .Title = "Chon Folder chua các file cân tông hop"
    .AllowMultiSelect = False
    .InitialFileName = strPath
    If .Show = -1 Then GetFolder = .SelectedItems(1)
  End With
End Function

Private Sub ImportTextFiles(ByRef rng, ByRef TS, ByVal k&)
  Dim arr(), lines, items
  Dim r&, C&, linecount&, text$

  lines = Split(TS.ReadAll, vbCrLf)
  If UBound(lines) > 0 Then
    linecount = UBound(lines)
    ReDim arr(1 To linecount, 1 To 1)
    For r = 1 To linecount
      text = lines(r)
      If text <> "" Then
        If text <> String(Len(text), vbTab) Then
          k = k + 1
          items = Split(text, vbTab)
          If UBound(arr, 2) < UBound(items) + 1 Then ReDim Preserve arr(1 To linecount, 1 To UBound(items) + 1)
          For C = 1 To UBound(arr, 2)
            arr(k, C) = items(C - 1)
          Next C
        End If
      End If
    Next r
  End If
  If k Then
    rng.Resize(k, UBound(arr, 2)).Value = arr
    Set rng = rng.Offset(k + 1)
  End If
End Sub
 
Kiểm tra lại . . .
Mã:
Option Explicit
Sub Main()
  Dim FSo As Object, strFolder$, sFolder As Object, aFolder()
  Dim rngP As Range, rngS As Range, i&, k&
 
  'On Error Resume Next
  Set FSo = CreateObject("Scripting.FileSystemObject")
  strFolder = GetFolder()
  If strFolder = Empty Then Exit Sub
  Dulieu_P.UsedRange.ClearContents
  Dulieu_S.UsedRange.ClearContents
  Set rngP = Dulieu_P.Range("A2")
  Set rngS = Dulieu_S.Range("A2")
  For Each sFolder In FSo.GetFolder(strFolder).SubFolders
    k = k + 1
    ReDim Preserve aFolder(1 To k)
    aFolder(k) = sFolder
  Next
  Call QuickSort(aFolder, k, True) 'True: A->Z, False: Z->A
  For i = LBound(aFolder) To UBound(aFolder)
    If FSo.FolderExists(aFolder(i) & "\P") Then
      Call GetTxtFile(rngP, FSo, aFolder(i) & "\P")
    End If
    If FSo.FolderExists(aFolder(i) & "\S") Then
      Call GetTxtFile(rngS, FSo, aFolder(i) & "\S")
    End If
  Next
End Sub

Private Sub GetTxtFile(rng, FSo, ByVal iPath$)
  Dim oFile As Object, TS As Object, aFile(), q&, r&

  For Each oFile In FSo.GetFolder(iPath).files
    q = q + 1
    ReDim Preserve aFile(1 To q)
    aFile(q) = oFile
  Next
  Call QuickSort(aFile, q, True) 'True: A->Z, False: Z->A
  For r = LBound(aFile) To UBound(aFile)
    If UCase(FSo.GetExtensionName(aFile(r))) Like "TXT" Then
      Set TS = FSo.OpenTextFile(aFile(r), 1, , -2)
      Call ImportTextFiles(rng, TS, 0)
    End If
  Next
End Sub

Private Sub QuickSort(sArr, k, Optional bASC As Boolean = True)
  'bASC=True: A->Z , bASC=False: Z->A
  Dim arr, C&(), tmp$, sRow&, fR&, i&, r&
 
  fR = LBound(sArr)
  arr = sArr
  ReDim C(fR To k)
  For i = fR To k - 1
    tmp = sArr(i)
    For r = i + 1 To k
      If (tmp > sArr(r)) = bASC Then C(i) = C(i) + 1 Else C(r) = C(r) + 1
    Next r
  Next i
  For i = fR To k
    sArr(C(i) + fR) = arr(i)
  Next i
End Sub

Function GetFolder(Optional strPath As String = Empty) As String
  With Application.FileDialog(msoFileDialogFolderPicker)
    .Title = "Chon Folder chua các file cân tông hop"
    .AllowMultiSelect = False
    .InitialFileName = strPath
    If .Show = -1 Then GetFolder = .SelectedItems(1)
  End With
End Function

Private Sub ImportTextFiles(ByRef rng, ByRef TS, ByVal k&)
  Dim arr(), lines, items
  Dim r&, C&, linecount&, text$

  lines = Split(TS.ReadAll, vbCrLf)
  If UBound(lines) > 0 Then
    linecount = UBound(lines)
    ReDim arr(1 To linecount, 1 To 1)
    For r = 1 To linecount
      text = lines(r)
      If text <> "" Then
        If text <> String(Len(text), vbTab) Then
          k = k + 1
          items = Split(text, vbTab)
          If UBound(arr, 2) < UBound(items) + 1 Then ReDim Preserve arr(1 To linecount, 1 To UBound(items) + 1)
          For C = 1 To UBound(arr, 2)
            arr(k, C) = items(C - 1)
          Next C
        End If
      End If
    Next r
  End If
  If k Then
    rng.Resize(k, UBound(arr, 2)).Value = arr
    Set rng = rng.Offset(k + 1)
  End If
End Sub
Em cám ơn Thầy nhiều! Code chạy rất chuẩn.
Một lần nữa, em cám ơn Thầy!
 
Em còn 1 vấn đề nữa là phần sắp xếp file theo thứ tự của File trong Foder S hoặc P.
Thứ tự mong muốn là: sắp xếp tăng dần theo chuỗi số.
Ví dụ: 4.1; 4.2; 4.3 ... 4.10, 4.11

Trong code tự chạy theo thứ tự: 4.1, 4.10, 4.11; 4.2; 4.3 ... (Không đúng với sắp xếp trong windown Thầy ạ!
 
Em còn 1 vấn đề nữa là phần sắp xếp file theo thứ tự của File trong Foder S hoặc P.
Thứ tự mong muốn là: sắp xếp tăng dần theo chuỗi số.
Ví dụ: 4.1; 4.2; 4.3 ... 4.10, 4.11

Trong code tự chạy theo thứ tự: 4.1, 4.10, 4.11; 4.2; 4.3 ... (Không đúng với sắp xếp trong windown Thầy ạ!
Chưa kiểm tra hết các khả năng sort trong folder :)
Mã:
Option Explicit
Sub Main()
  Dim FSo As Object, strFolder$, sFolder As Object, aFolder()
  Dim rngP As Range, rngS As Range, i&, k&
 
  'On Error Resume Next
  Set FSo = CreateObject("Scripting.FileSystemObject")
  strFolder = GetFolder()
  If strFolder = Empty Then Exit Sub
  Dulieu_P.UsedRange.ClearContents
  Dulieu_S.UsedRange.ClearContents
  Set rngP = Dulieu_P.Range("A2")
  Set rngS = Dulieu_S.Range("A2")
  For Each sFolder In FSo.GetFolder(strFolder).SubFolders
    k = k + 1
    ReDim Preserve aFolder(1 To k)
    aFolder(k) = sFolder
  Next
  Call SortIndex(aFolder, k, True, True, ".")
  For i = LBound(aFolder) To UBound(aFolder)
    If FSo.FolderExists(aFolder(i) & "\P") Then
      Call GetTxtFile(rngP, FSo, aFolder(i) & "\P")
    End If
    If FSo.FolderExists(aFolder(i) & "\S") Then
      Call GetTxtFile(rngS, FSo, aFolder(i) & "\S")
    End If
  Next
End Sub

Private Sub GetTxtFile(rng, FSo, ByVal iPath$)
  Dim oFile As Object, TS As Object, aFile(), q&, r&

  For Each oFile In FSo.GetFolder(iPath).files
    q = q + 1
    ReDim Preserve aFile(1 To q)
    aFile(q) = oFile
  Next
  Call SortIndex(aFile, q, True, True, ".")
  For r = LBound(aFile) To UBound(aFile)
    If UCase(FSo.GetExtensionName(aFile(r))) Like "TXT" Then
      Set TS = FSo.OpenTextFile(aFile(r), 1, , -2)
      Call ImportTextFiles(rng, TS, 0)
    End If
  Next
End Sub

Private Sub ImportTextFiles(ByRef rng, ByRef TS, ByVal k&)
  Dim arr(), lines, items, r&, C&, linecount&, text$

  lines = Split(TS.ReadAll, vbCrLf)
  If UBound(lines) > 0 Then
    linecount = UBound(lines)
    ReDim arr(1 To linecount, 1 To 1)
    For r = 1 To linecount
      text = lines(r)
      If text <> "" Then
        If text <> String(Len(text), vbTab) Then
          k = k + 1
          items = Split(text, vbTab)
          If UBound(arr, 2) < UBound(items) + 1 Then ReDim Preserve arr(1 To linecount, 1 To UBound(items) + 1)
          For C = 1 To UBound(arr, 2)
            arr(k, C) = items(C - 1)
          Next C
        End If
      End If
    Next r
  End If
  If k Then
    rng.Resize(k, UBound(arr, 2)).Value = arr
    Set rng = rng.Offset(k + 1)
  End If
End Sub

Private Sub SortIndex(sArr, ByVal eR&, Optional ByVal bASC As Boolean = True _
              , Optional ByVal bIndex As Boolean = False, Optional ByVal deli$ = ".")
' Mac dinh bASC=True, neu bASC=True:    A->Z , bASC=False: Z->A
' bIndex=True:  Sort voi Chi Muc dau chuoi ky tu, mac dinh = False
' deli:         Ky tu phan cap Chi Muc, mac dinh = "."
  Dim arr, C&(), tmp$, sRow&, fR&, i&, r&
 
  fR = LBound(sArr)
  If bIndex = False Then
    arr = sArr
  Else
    Call CreateArr(sArr, arr, fR, eR, deli)
  End If
  ReDim C(fR To eR)
  For i = fR To eR - 1
    tmp = arr(i)
    For r = i + 1 To eR
      If (tmp > arr(r)) = bASC Then C(i) = C(i) + 1 Else C(r) = C(r) + 1
    Next r
  Next i
  If bIndex = True Then arr = sArr
  For i = fR To eR
    sArr(C(i) + fR) = arr(i)
  Next i
End Sub

Private Sub CreateArr(sArr, arr, fR, eR, deli$)
  Dim S, a(), t&(), tmp$, i&, j&

  ReDim t(0 To 9) 'Toi da 9+1=10 Cap Chi Muc
  ReDim a(fR To eR, 1 To 2)
  ReDim arr(fR To eR)
  For i = fR To eR
    tmp = sArr(i)
    S = Split(tmp & " ", " ")
    a(i, 1) = S(0)
    If UBound(S) > 1 Then a(i, 2) = Replace(tmp, a(i, 1) & " ", "")
    S = Split(a(i, 1), deli)
    For j = 0 To UBound(S)
      If t(j) < Len(S(j)) Then t(j) = Len(S(j))
    Next j
    a(i, 1) = S
  Next i
  For i = fR To eR
    S = a(i, 1)
    For j = 0 To UBound(S)
      If IsNumeric(S(j)) Then S(j) = Format(CLng(S(j)), String(t(j), "0"))
    Next j
    If a(i, 2) = Empty Then
      arr(i) = Join(S, deli)
    Else
      arr(i) = Join(S, deli) & " " & a(i, 2)
    End If
  Next i
End Sub

Function GetFolder(Optional strPath As String = Empty) As String
  With Application.FileDialog(msoFileDialogFolderPicker)
    .Title = "Chon Folder chua các file cân tông hop"
    .AllowMultiSelect = False
    .InitialFileName = strPath
    If .Show = -1 Then GetFolder = .SelectedItems(1)
  End With
End Function
 
Chưa kiểm tra hết các khả năng sort trong folder :)
Mã:
Option Explicit
Sub Main()
  Dim FSo As Object, strFolder$, sFolder As Object, aFolder()
  Dim rngP As Range, rngS As Range, i&, k&
 
  'On Error Resume Next
  Set FSo = CreateObject("Scripting.FileSystemObject")
  strFolder = GetFolder()
  If strFolder = Empty Then Exit Sub
  Dulieu_P.UsedRange.ClearContents
  Dulieu_S.UsedRange.ClearContents
  Set rngP = Dulieu_P.Range("A2")
  Set rngS = Dulieu_S.Range("A2")
  For Each sFolder In FSo.GetFolder(strFolder).SubFolders
    k = k + 1
    ReDim Preserve aFolder(1 To k)
    aFolder(k) = sFolder
  Next
  Call SortIndex(aFolder, k, True, True, ".")
  For i = LBound(aFolder) To UBound(aFolder)
    If FSo.FolderExists(aFolder(i) & "\P") Then
      Call GetTxtFile(rngP, FSo, aFolder(i) & "\P")
    End If
    If FSo.FolderExists(aFolder(i) & "\S") Then
      Call GetTxtFile(rngS, FSo, aFolder(i) & "\S")
    End If
  Next
End Sub

Private Sub GetTxtFile(rng, FSo, ByVal iPath$)
  Dim oFile As Object, TS As Object, aFile(), q&, r&

  For Each oFile In FSo.GetFolder(iPath).files
    q = q + 1
    ReDim Preserve aFile(1 To q)
    aFile(q) = oFile
  Next
  Call SortIndex(aFile, q, True, True, ".")
  For r = LBound(aFile) To UBound(aFile)
    If UCase(FSo.GetExtensionName(aFile(r))) Like "TXT" Then
      Set TS = FSo.OpenTextFile(aFile(r), 1, , -2)
      Call ImportTextFiles(rng, TS, 0)
    End If
  Next
End Sub

Private Sub ImportTextFiles(ByRef rng, ByRef TS, ByVal k&)
  Dim arr(), lines, items, r&, C&, linecount&, text$

  lines = Split(TS.ReadAll, vbCrLf)
  If UBound(lines) > 0 Then
    linecount = UBound(lines)
    ReDim arr(1 To linecount, 1 To 1)
    For r = 1 To linecount
      text = lines(r)
      If text <> "" Then
        If text <> String(Len(text), vbTab) Then
          k = k + 1
          items = Split(text, vbTab)
          If UBound(arr, 2) < UBound(items) + 1 Then ReDim Preserve arr(1 To linecount, 1 To UBound(items) + 1)
          For C = 1 To UBound(arr, 2)
            arr(k, C) = items(C - 1)
          Next C
        End If
      End If
    Next r
  End If
  If k Then
    rng.Resize(k, UBound(arr, 2)).Value = arr
    Set rng = rng.Offset(k + 1)
  End If
End Sub

Private Sub SortIndex(sArr, ByVal eR&, Optional ByVal bASC As Boolean = True _
              , Optional ByVal bIndex As Boolean = False, Optional ByVal deli$ = ".")
' Mac dinh bASC=True, neu bASC=True:    A->Z , bASC=False: Z->A
' bIndex=True:  Sort voi Chi Muc dau chuoi ky tu, mac dinh = False
' deli:         Ky tu phan cap Chi Muc, mac dinh = "."
  Dim arr, C&(), tmp$, sRow&, fR&, i&, r&
 
  fR = LBound(sArr)
  If bIndex = False Then
    arr = sArr
  Else
    Call CreateArr(sArr, arr, fR, eR, deli)
  End If
  ReDim C(fR To eR)
  For i = fR To eR - 1
    tmp = arr(i)
    For r = i + 1 To eR
      If (tmp > arr(r)) = bASC Then C(i) = C(i) + 1 Else C(r) = C(r) + 1
    Next r
  Next i
  If bIndex = True Then arr = sArr
  For i = fR To eR
    sArr(C(i) + fR) = arr(i)
  Next i
End Sub

Private Sub CreateArr(sArr, arr, fR, eR, deli$)
  Dim S, a(), t&(), tmp$, i&, j&

  ReDim t(0 To 9) 'Toi da 9+1=10 Cap Chi Muc
  ReDim a(fR To eR, 1 To 2)
  ReDim arr(fR To eR)
  For i = fR To eR
    tmp = sArr(i)
    S = Split(tmp & " ", " ")
    a(i, 1) = S(0)
    If UBound(S) > 1 Then a(i, 2) = Replace(tmp, a(i, 1) & " ", "")
    S = Split(a(i, 1), deli)
    For j = 0 To UBound(S)
      If t(j) < Len(S(j)) Then t(j) = Len(S(j))
    Next j
    a(i, 1) = S
  Next i
  For i = fR To eR
    S = a(i, 1)
    For j = 0 To UBound(S)
      If IsNumeric(S(j)) Then S(j) = Format(CLng(S(j)), String(t(j), "0"))
    Next j
    If a(i, 2) = Empty Then
      arr(i) = Join(S, deli)
    Else
      arr(i) = Join(S, deli) & " " & a(i, 2)
    End If
  Next i
End Sub

Function GetFolder(Optional strPath As String = Empty) As String
  With Application.FileDialog(msoFileDialogFolderPicker)
    .Title = "Chon Folder chua các file cân tông hop"
    .AllowMultiSelect = False
    .InitialFileName = strPath
    If .Show = -1 Then GetFolder = .SelectedItems(1)
  End With
End Function
Em đã kiểm tra rồi Thầy ạ. Phần foder sắp xếp đúng, nhưng phần file trong foder vẫn chưa được. Vẫn ở trạng thái ban đầu Thầy ạ. Thứ tự chỉ mục phần sau 4. tăng dần từ 1 đến 20 có nghĩa là 4.1 ; 4.2; 4.3 ; .... 4.10; 4.11; .... ; 4.20 (Tăng theo thứ tự số đếm phần chỉ mục sau)
Hiện tại chương trình đang hiểu là 4.1; 4.10; 4.11 ... 4.2; 4.20 ; ... 4.3 ...

Vì file.txt nhập vào tương đối nhiều. Kính nhờ Thầy cho em thêm cột A để điền tên đường dẫn file.txt để em kiểm tra lại cho tiện được không ạ?
 
Lần chỉnh sửa cuối:
Em đã kiểm tra rồi Thầy ạ. Phần foder sắp xếp đúng, nhưng phần file trong foder vẫn chưa được. Vẫn ở trạng thái ban đầu Thầy ạ. Thứ tự chỉ mục phần sau 4. tăng dần từ 1 đến 20 có nghĩa là 4.1 ; 4.2; 4.3 ; .... 4.10; 4.11; .... ; 4.20 (Tăng theo thứ tự số đếm phần chỉ mục sau)
Hiện tại chương trình đang hiểu là 4.1; 4.10; 4.11 ... 4.2; 4.20 ; ... 4.3 ...

Vì file.txt nhập vào tương đối nhiều. Kính nhờ Thầy cho em thêm cột A để điền tên đường dẫn file.txt để em kiểm tra lại cho tiện được không ạ?
Chỉnh Tiếp . . .
Mã:
Option Explicit
Sub Main()
  Dim FSo As Object, strFolder$, sFolder As Object, aFolder()
  Dim rngP As Range, rngS As Range, i&, k&
  'On Error Resume Next
  Set FSo = CreateObject("Scripting.FileSystemObject")
  strFolder = GetFolder()
  If strFolder = Empty Then Exit Sub
  Dulieu_P.UsedRange.ClearContents
  Dulieu_S.UsedRange.ClearContents
  Set rngP = Dulieu_P.Range("B2")
  Set rngS = Dulieu_S.Range("B2")
  For Each sFolder In FSo.GetFolder(strFolder).SubFolders
    k = k + 1
    ReDim Preserve aFolder(1 To k)
    aFolder(k) = sFolder
  Next
  Call SortIndex(aFolder, k, True, True, ".")
  For i = LBound(aFolder) To UBound(aFolder)
    If FSo.FolderExists(aFolder(i) & "\P") Then
      Call GetTxtFile(rngP, FSo, aFolder(i) & "\P")
    End If
    If FSo.FolderExists(aFolder(i) & "\S") Then
      Call GetTxtFile(rngS, FSo, aFolder(i) & "\S")
    End If
  Next
End Sub

Private Sub GetTxtFile(rng, FSo, ByVal iPath$)
  Dim oFile As Object, TS As Object, aFile(), q&, r&, fileName$

  For Each oFile In FSo.GetFolder(iPath).files
    q = q + 1
    ReDim Preserve aFile(1 To q)
    aFile(q) = oFile
  Next
  Call SortIndex(aFile, q, True, True, ".")
  For r = LBound(aFile) To UBound(aFile)
    If UCase(FSo.GetExtensionName(aFile(r))) Like "TXT" Then
      Set TS = FSo.OpenTextFile(aFile(r), 1, , -2)
      'aFile(r) = FSo.GetBaseName(aFile(r)) 'Chi lay ten file
      Call ImportTextFiles(rng, TS, aFile(r), 0)
    End If
  Next
End Sub

Private Sub ImportTextFiles(ByRef rng, ByRef TS, ByVal fileName, ByVal k&)
  Dim arr(), lines, items, r&, C&, linecount&, text$

  lines = Split(TS.ReadAll, vbCrLf)
  If UBound(lines) > 0 Then
    linecount = UBound(lines)
    ReDim arr(1 To linecount, 1 To 1)
    For r = 1 To linecount
      text = lines(r)
      If text <> "" Then
        If text <> String(Len(text), vbTab) Then
          k = k + 1
          items = Split(text, vbTab)
          If UBound(arr, 2) < UBound(items) + 1 Then ReDim Preserve arr(1 To linecount, 1 To UBound(items) + 1)
          For C = 1 To UBound(arr, 2)
            arr(k, C) = items(C - 1)
          Next C
        End If
      End If
    Next r
  End If
  If k Then
    rng.Offset(, -1).Resize(k).Value = fileName
    rng.Resize(k, UBound(arr, 2)).Value = arr
    Set rng = rng.Offset(k + 1)
  End If
End Sub

Private Sub SortIndex(sArr, ByVal eR&, Optional ByVal bASC As Boolean = True _
              , Optional ByVal bIndex As Boolean = False, Optional ByVal deli$ = ".")
' Mac dinh bASC=True, neu bASC=True:    A->Z , bASC=False: Z->A
' bIndex=True:  Sort voi Chi Muc dau chuoi ky tu, mac dinh = False
' deli:         Ky tu phan cap Chi Muc, mac dinh = "."
  Dim arr, C&(), tmp$, sRow&, fR&, i&, r&
 
  fR = LBound(sArr)
  If bIndex = False Then
    arr = sArr
  Else
    Call CreateArr(sArr, arr, fR, eR, deli)
  End If
  ReDim C(fR To eR)
  For i = fR To eR - 1
    tmp = arr(i)
    For r = i + 1 To eR
      If (tmp > arr(r)) = bASC Then C(i) = C(i) + 1 Else C(r) = C(r) + 1
    Next r
  Next i
  If bIndex = True Then arr = sArr
  For i = fR To eR
    sArr(C(i) + fR) = arr(i)
  Next i
End Sub

Private Sub CreateArr(sArr, arr, fR, eR, deli$)
  Dim S, a(), t&(), tmp$, i&, j&

  ReDim t(0 To 9) 'Toi da 9+1=10 Cap Chi Muc
  ReDim a(fR To eR, 1 To 2)
  ReDim arr(fR To eR)
  For i = fR To eR
    S = Split(sArr(i), "\")
    tmp = S(UBound(S)) 'Ten thu muc hoac ten file
    S = Split(tmp & " ", " ")
    a(i, 1) = S(0)
    If UBound(S) > 1 Then a(i, 2) = Replace(tmp, a(i, 1) & " ", "")
    S = Split(a(i, 1), deli)
    For j = 0 To UBound(S)
      If t(j) < Len(S(j)) Then t(j) = Len(S(j))
    Next j
    a(i, 1) = S
  Next i
  For i = fR To eR
    S = a(i, 1)
    For j = 0 To UBound(S)
      If IsNumeric(S(j)) Then S(j) = Format(CLng(S(j)), String(t(j), "0"))
    Next j
    If a(i, 2) = Empty Then
      arr(i) = Join(S, deli)
    Else
      arr(i) = Join(S, deli) & " " & a(i, 2)
    End If
  Next i
End Sub

Function GetFolder(Optional strPath As String = Empty) As String
  With Application.FileDialog(msoFileDialogFolderPicker)
    .Title = "Chon Folder chua các file cân tông hop"
    .AllowMultiSelect = False
    .InitialFileName = strPath
    If .Show = -1 Then GetFolder = .SelectedItems(1)
  End With
End Function
 
Chỉnh Tiếp . . .
Mã:
Option Explicit
Sub Main()
  Dim FSo As Object, strFolder$, sFolder As Object, aFolder()
  Dim rngP As Range, rngS As Range, i&, k&
  'On Error Resume Next
  Set FSo = CreateObject("Scripting.FileSystemObject")
  strFolder = GetFolder()
  If strFolder = Empty Then Exit Sub
  Dulieu_P.UsedRange.ClearContents
  Dulieu_S.UsedRange.ClearContents
  Set rngP = Dulieu_P.Range("B2")
  Set rngS = Dulieu_S.Range("B2")
  For Each sFolder In FSo.GetFolder(strFolder).SubFolders
    k = k + 1
    ReDim Preserve aFolder(1 To k)
    aFolder(k) = sFolder
  Next
  Call SortIndex(aFolder, k, True, True, ".")
  For i = LBound(aFolder) To UBound(aFolder)
    If FSo.FolderExists(aFolder(i) & "\P") Then
      Call GetTxtFile(rngP, FSo, aFolder(i) & "\P")
    End If
    If FSo.FolderExists(aFolder(i) & "\S") Then
      Call GetTxtFile(rngS, FSo, aFolder(i) & "\S")
    End If
  Next
End Sub

Private Sub GetTxtFile(rng, FSo, ByVal iPath$)
  Dim oFile As Object, TS As Object, aFile(), q&, r&, fileName$

  For Each oFile In FSo.GetFolder(iPath).files
    q = q + 1
    ReDim Preserve aFile(1 To q)
    aFile(q) = oFile
  Next
  Call SortIndex(aFile, q, True, True, ".")
  For r = LBound(aFile) To UBound(aFile)
    If UCase(FSo.GetExtensionName(aFile(r))) Like "TXT" Then
      Set TS = FSo.OpenTextFile(aFile(r), 1, , -2)
      'aFile(r) = FSo.GetBaseName(aFile(r)) 'Chi lay ten file
      Call ImportTextFiles(rng, TS, aFile(r), 0)
    End If
  Next
End Sub

Private Sub ImportTextFiles(ByRef rng, ByRef TS, ByVal fileName, ByVal k&)
  Dim arr(), lines, items, r&, C&, linecount&, text$

  lines = Split(TS.ReadAll, vbCrLf)
  If UBound(lines) > 0 Then
    linecount = UBound(lines)
    ReDim arr(1 To linecount, 1 To 1)
    For r = 1 To linecount
      text = lines(r)
      If text <> "" Then
        If text <> String(Len(text), vbTab) Then
          k = k + 1
          items = Split(text, vbTab)
          If UBound(arr, 2) < UBound(items) + 1 Then ReDim Preserve arr(1 To linecount, 1 To UBound(items) + 1)
          For C = 1 To UBound(arr, 2)
            arr(k, C) = items(C - 1)
          Next C
        End If
      End If
    Next r
  End If
  If k Then
    rng.Offset(, -1).Resize(k).Value = fileName
    rng.Resize(k, UBound(arr, 2)).Value = arr
    Set rng = rng.Offset(k + 1)
  End If
End Sub

Private Sub SortIndex(sArr, ByVal eR&, Optional ByVal bASC As Boolean = True _
              , Optional ByVal bIndex As Boolean = False, Optional ByVal deli$ = ".")
' Mac dinh bASC=True, neu bASC=True:    A->Z , bASC=False: Z->A
' bIndex=True:  Sort voi Chi Muc dau chuoi ky tu, mac dinh = False
' deli:         Ky tu phan cap Chi Muc, mac dinh = "."
  Dim arr, C&(), tmp$, sRow&, fR&, i&, r&
 
  fR = LBound(sArr)
  If bIndex = False Then
    arr = sArr
  Else
    Call CreateArr(sArr, arr, fR, eR, deli)
  End If
  ReDim C(fR To eR)
  For i = fR To eR - 1
    tmp = arr(i)
    For r = i + 1 To eR
      If (tmp > arr(r)) = bASC Then C(i) = C(i) + 1 Else C(r) = C(r) + 1
    Next r
  Next i
  If bIndex = True Then arr = sArr
  For i = fR To eR
    sArr(C(i) + fR) = arr(i)
  Next i
End Sub

Private Sub CreateArr(sArr, arr, fR, eR, deli$)
  Dim S, a(), t&(), tmp$, i&, j&

  ReDim t(0 To 9) 'Toi da 9+1=10 Cap Chi Muc
  ReDim a(fR To eR, 1 To 2)
  ReDim arr(fR To eR)
  For i = fR To eR
    S = Split(sArr(i), "\")
    tmp = S(UBound(S)) 'Ten thu muc hoac ten file
    S = Split(tmp & " ", " ")
    a(i, 1) = S(0)
    If UBound(S) > 1 Then a(i, 2) = Replace(tmp, a(i, 1) & " ", "")
    S = Split(a(i, 1), deli)
    For j = 0 To UBound(S)
      If t(j) < Len(S(j)) Then t(j) = Len(S(j))
    Next j
    a(i, 1) = S
  Next i
  For i = fR To eR
    S = a(i, 1)
    For j = 0 To UBound(S)
      If IsNumeric(S(j)) Then S(j) = Format(CLng(S(j)), String(t(j), "0"))
    Next j
    If a(i, 2) = Empty Then
      arr(i) = Join(S, deli)
    Else
      arr(i) = Join(S, deli) & " " & a(i, 2)
    End If
  Next i
End Sub

Function GetFolder(Optional strPath As String = Empty) As String
  With Application.FileDialog(msoFileDialogFolderPicker)
    .Title = "Chon Folder chua các file cân tông hop"
    .AllowMultiSelect = False
    .InitialFileName = strPath
    If .Show = -1 Then GetFolder = .SelectedItems(1)
  End With
End Function
Chỉnh Tiếp . . .
Mã:
Option Explicit
Sub Main()
  Dim FSo As Object, strFolder$, sFolder As Object, aFolder()
  Dim rngP As Range, rngS As Range, i&, k&
  'On Error Resume Next
  Set FSo = CreateObject("Scripting.FileSystemObject")
  strFolder = GetFolder()
  If strFolder = Empty Then Exit Sub
  Dulieu_P.UsedRange.ClearContents
  Dulieu_S.UsedRange.ClearContents
  Set rngP = Dulieu_P.Range("B2")
  Set rngS = Dulieu_S.Range("B2")
  For Each sFolder In FSo.GetFolder(strFolder).SubFolders
    k = k + 1
    ReDim Preserve aFolder(1 To k)
    aFolder(k) = sFolder
  Next
  Call SortIndex(aFolder, k, True, True, ".")
  For i = LBound(aFolder) To UBound(aFolder)
    If FSo.FolderExists(aFolder(i) & "\P") Then
      Call GetTxtFile(rngP, FSo, aFolder(i) & "\P")
    End If
    If FSo.FolderExists(aFolder(i) & "\S") Then
      Call GetTxtFile(rngS, FSo, aFolder(i) & "\S")
    End If
  Next
End Sub

Private Sub GetTxtFile(rng, FSo, ByVal iPath$)
  Dim oFile As Object, TS As Object, aFile(), q&, r&, fileName$

  For Each oFile In FSo.GetFolder(iPath).files
    q = q + 1
    ReDim Preserve aFile(1 To q)
    aFile(q) = oFile
  Next
  Call SortIndex(aFile, q, True, True, ".")
  For r = LBound(aFile) To UBound(aFile)
    If UCase(FSo.GetExtensionName(aFile(r))) Like "TXT" Then
      Set TS = FSo.OpenTextFile(aFile(r), 1, , -2)
      'aFile(r) = FSo.GetBaseName(aFile(r)) 'Chi lay ten file
      Call ImportTextFiles(rng, TS, aFile(r), 0)
    End If
  Next
End Sub

Private Sub ImportTextFiles(ByRef rng, ByRef TS, ByVal fileName, ByVal k&)
  Dim arr(), lines, items, r&, C&, linecount&, text$

  lines = Split(TS.ReadAll, vbCrLf)
  If UBound(lines) > 0 Then
    linecount = UBound(lines)
    ReDim arr(1 To linecount, 1 To 1)
    For r = 1 To linecount
      text = lines(r)
      If text <> "" Then
        If text <> String(Len(text), vbTab) Then
          k = k + 1
          items = Split(text, vbTab)
          If UBound(arr, 2) < UBound(items) + 1 Then ReDim Preserve arr(1 To linecount, 1 To UBound(items) + 1)
          For C = 1 To UBound(arr, 2)
            arr(k, C) = items(C - 1)
          Next C
        End If
      End If
    Next r
  End If
  If k Then
    rng.Offset(, -1).Resize(k).Value = fileName
    rng.Resize(k, UBound(arr, 2)).Value = arr
    Set rng = rng.Offset(k + 1)
  End If
End Sub

Private Sub SortIndex(sArr, ByVal eR&, Optional ByVal bASC As Boolean = True _
              , Optional ByVal bIndex As Boolean = False, Optional ByVal deli$ = ".")
' Mac dinh bASC=True, neu bASC=True:    A->Z , bASC=False: Z->A
' bIndex=True:  Sort voi Chi Muc dau chuoi ky tu, mac dinh = False
' deli:         Ky tu phan cap Chi Muc, mac dinh = "."
  Dim arr, C&(), tmp$, sRow&, fR&, i&, r&
 
  fR = LBound(sArr)
  If bIndex = False Then
    arr = sArr
  Else
    Call CreateArr(sArr, arr, fR, eR, deli)
  End If
  ReDim C(fR To eR)
  For i = fR To eR - 1
    tmp = arr(i)
    For r = i + 1 To eR
      If (tmp > arr(r)) = bASC Then C(i) = C(i) + 1 Else C(r) = C(r) + 1
    Next r
  Next i
  If bIndex = True Then arr = sArr
  For i = fR To eR
    sArr(C(i) + fR) = arr(i)
  Next i
End Sub

Private Sub CreateArr(sArr, arr, fR, eR, deli$)
  Dim S, a(), t&(), tmp$, i&, j&

  ReDim t(0 To 9) 'Toi da 9+1=10 Cap Chi Muc
  ReDim a(fR To eR, 1 To 2)
  ReDim arr(fR To eR)
  For i = fR To eR
    S = Split(sArr(i), "\")
    tmp = S(UBound(S)) 'Ten thu muc hoac ten file
    S = Split(tmp & " ", " ")
    a(i, 1) = S(0)
    If UBound(S) > 1 Then a(i, 2) = Replace(tmp, a(i, 1) & " ", "")
    S = Split(a(i, 1), deli)
    For j = 0 To UBound(S)
      If t(j) < Len(S(j)) Then t(j) = Len(S(j))
    Next j
    a(i, 1) = S
  Next i
  For i = fR To eR
    S = a(i, 1)
    For j = 0 To UBound(S)
      If IsNumeric(S(j)) Then S(j) = Format(CLng(S(j)), String(t(j), "0"))
    Next j
    If a(i, 2) = Empty Then
      arr(i) = Join(S, deli)
    Else
      arr(i) = Join(S, deli) & " " & a(i, 2)
    End If
  Next i
End Sub

Function GetFolder(Optional strPath As String = Empty) As String
  With Application.FileDialog(msoFileDialogFolderPicker)
    .Title = "Chon Folder chua các file cân tông hop"
    .AllowMultiSelect = False
    .InitialFileName = strPath
    If .Show = -1 Then GetFolder = .SelectedItems(1)
  End With
End Function
Em xin chân thành cám ơn Thầy! Code chạy đã chuẩn và đúng ý của em rồi.
Một lần nữa xin được cám ơn Thầy!
Chúc Thầy sức khỏe, thành công trong cuộc sống!
 
Web KT
Back
Top Bottom