Trích lọc dữ liệu sử dụng VBA Code

Liên hệ QC

th7

Thành viên thường trực
Tham gia
3/3/15
Bài viết
215
Được thích
52
Giới tính
Nam
Chào các bạn trong diễn đàn
Hiện tại mình có file dữ liệu bằng định dạng (.txt) là file do phần mềm bên máy mình xuất ra và nó theo một định dạng như vậy rồi.
Mình có làm một file mẫu excel (kiểu dữ liệu mong muốn cần lấy), dữ liệu này mình cần làm để phục vụ công việc trên sản xuất, do mình muốn làm nhanh nên nhờ các bạn sử dụng VBA code giúp mình
Cám ơn các bạn ghé đọc và hỗ trợ.
 

File đính kèm

  • 10203040-RS.txt
    14.3 KB · Đọc: 22
  • Book1.xlsx
    13.2 KB · Đọc: 16
Chào bạn Befaint,
Mình sẽ mô tả cụ thể hơn trong file excel luôn nha,
Cảm ơn bạn quan tâm.
 

File đính kèm

  • Mo ta chi tiet 1.xlsx
    17.3 KB · Đọc: 14
Chào bạn Befaint,
Mình sẽ mô tả cụ thể hơn trong file excel luôn nha,
Cảm ơn bạn quan tâm.
Bạn có thể làm thủ công như sau:
- Bước 1: Mở File Excel mới, vào File > Open > Browse.
- Bước 2: Làm tuần tự như hình 1.
- Bước 3: Làm tuần tự như hình 2.
- Bước 4: Làm tuần tự như hình 3.
Ta được kết quả phân tích dữ liệu, việc còn lại là copy những thứ cần vào File của bạn.

Hình 1:
A_1.JPG

Hình 2:
A_2.JPG

Hình 3:
A_3.JPG
 
Cảm ơn bạn Be09 đã hướng dẫn từng bước, mình cũng có làm rồi nhưng mà lâu qua,
Trước đây cũng có một txt tương tự, có một bạn hỗ trợ mình code, mà giờ phần mềm lên đời, xuất file hơi khác, mà cái code VBA trước đây, bạn Doveandrose viết mình ngồi xem lại cũng không hiểu nên cũng không sửa được.
Nếu có ai biết VBA xin hỗ trợ mình, Mình có đính kèm code VBA trước đây.
Cảm ơn mọi người.
 

File đính kèm

  • Code filter.txt
    2.6 KB · Đọc: 9
Chào các bạn trong diễn đàn
Hiện tại mình có file dữ liệu bằng định dạng (.txt) là file do phần mềm bên máy mình xuất ra và nó theo một định dạng như vậy rồi.
Mình có làm một file mẫu excel (kiểu dữ liệu mong muốn cần lấy), dữ liệu này mình cần làm để phục vụ công việc trên sản xuất, do mình muốn làm nhanh nên nhờ các bạn sử dụng VBA code giúp mình
Cám ơn các bạn ghé đọc và hỗ trợ.
2 file để chung 1 thư mục, mở file Excel chạy code
 

File đính kèm

  • Mo ta chi tiet 1.xlsm
    29.1 KB · Đọc: 16
2 file để chung 1 thư mục, mở file Excel chạy code
Cảm ơn Bạn HieuCD
Bạn cho mình hỏi 2 vấn đề liên quan trong file nữa nha,
- Ở câu code:
ProName = Split(sArr(3, 3), ".")(0)
Res(1, 2) = ProName & "-RS1"
ProName = 10203040 là OK rồi và mình muốn lấy RS là chữ ở trong mục Line name (Mình muốn nó tự động lấy luôn, không phải nhập bằng tay vì trong file text dữ liệu chỗ Linename có thể thay đổi, không cố đinh)
Bạn xem có hiệu chỉnh Code được không
- Còn một vấn đề nữa là file .txt thì có rất nhiều tên,
nếu mình muốn để 2 file vào một folder, mở excel lên và chạy code mà không cần sửa tên trùng nhau giữa {10203040.txt và FilesToOpen = ThisWorkbook.Path & "\10203040-RS.txt" } thì có được không?
Cảm ơn Bạn.
Đính kèm Code:
Sub Main()
Dim sArr As Variant, dArr As Variant, Res As Variant, S As Variant
Dim ProName As String, LineName As String, tmp As String, FilesToOpen As String
Dim i As Long, fR As Long, nR As Long, k As Long, ik As Long, j As Byte

FilesToOpen = ThisWorkbook.Path & "\10203040-RS.txt"
sArr = ImportTextToExcel(FilesToOpen)
dArr = Range("B7:k8").Value
ReDim Res(1 To UBound(sArr), 1 To 7)

For j = 1 To 6
Res(1, j) = dArr(1, j): Res(2, j) = dArr(2, j)
Next j
Res(2, 7) = dArr(2, 7)
ProName = Split(sArr(3, 3), ".")(0)
Res(1, 2) = ProName & "-RS1"
Res(1, 1) = "Program Name"
Res(1, 6) = "No. of components"
Res(1, 4) = "Simulated time (s)"
Res(2, 1) = "F. Position N."
Res(2, 2) = "Component Name"
Res(2, 3) = "Placement ID"
Res(2, 4) = "Description"
Res(2, 5) = "Feeder Type"
Res(2, 6) = "Component pitch"
Res(2, 7) = "Qty."

With CreateObject("scripting.dictionary")
For i = 1 To UBound(sArr)
If Left(sArr(i, 1), 2) = "F-" Then fR = i: Exit For
Next i
k = 2
For i = fR To UBound(sArr)
k = k + 1
If Left(sArr(i, 1), 2) = "F-" Then
Res(k, 1) = sArr(i, 1)
Res(k, 5) = sArr(i, 4)
Res(k, 6) = sArr(i, 5)
Key = sArr(i, 2)
S = Split(Key, " ")
Res(k, 2) = S(1): Res(k, 4) = S(0)
.Item(Key) = k
Else
For j = 1 To 6
Res(k, j) = dArr(1, j)
Next j
Res(k, 1) = "Program Name"
Res(k, 2) = ProName & "-RS2"
nR = k
Res(k, 6) = "No. of components"
Res(k, 4) = "Simulated time (s)"
End If
Next i

For i = 1 To UBound(sArr)
If sArr(i, 1) = "No." Then fR = i + 1: Exit For
Next i
For i = fR To UBound(sArr)
Key = sArr(i, 6)
If Key = "" Then Exit For
If .exists(Key) Then
ik = .Item(Key)
Res(ik, 7) = Res(ik, 7) + 1
If ik < nR Then Res(1, 7) = Res(1, 7) + 1 Else Res(nR, 7) = Res(nR, 7) + 1

If Res(ik, 3) = "" Then
Res(ik, 3) = sArr(i, 2)
Else
Res(ik, 3) = Res(ik, 3) & ", " & sArr(i, 2)
End If
End If
Next i
k = k + 1
Res(k, 6) = "Total placements"
Res(k, 7) = Res(1, 7) + Res(nR, 7)
End With
[B7].Resize(k, 6).NumberFormat = "@"
[B7].Resize(k, 7) = Res
End Sub
Function ImportTextToExcel(ByVal FilesToOpen As String) As Variant
Dim fso As Object, TextSource As Object
Dim sArr As Variant, Res As Variant
Dim Str As String, tmp As String
Dim i As Long, k As Byte, S As Byte, j As Byte, n As Byte, sC As Byte
Dim dArr As Long

Set fso = CreateObject("Scripting.FileSystemObject")
Set TextSource = fso_OpenTextFile(FilesToOpen, 1, False, -2)
sArr = Split(TextSource.ReadAll, vbCrLf)
ReDim Res(1 To UBound(sArr), 1 To 1)
For i = LBound(sArr) To UBound(sArr)
Str = sArr(i)
S = Len(Str)
If S Then
k = 0
Test = False
For j = 1 To S - 1
If Mid(Str, j, 1) <> " " Then
k = k + 1
If sC < k Then
sC = k
ReDim Preserve Res(1 To UBound(sArr), 1 To k)
End If
tmp = ""
For n = j To S - 1
If Mid(Str, n, 2) <> " " Then
tmp = tmp & Mid(Str, n, 1)
Else
Res(i + 1, k) = tmp
j = n
Exit For
End If
Next n
End If
Next j
End If
Next i
ImportTextToExcel = Res
Set fso = Nothing: Set TextSource = Nothing
End Function
 
Cảm ơn Bạn HieuCD
Bạn cho mình hỏi 2 vấn đề liên quan trong file nữa nha,
- Ở câu code:
ProName = Split(sArr(3, 3), ".")(0)
Res(1, 2) = ProName & "-RS1"
ProName = 10203040 là OK rồi và mình muốn lấy RS là chữ ở trong mục Line name (Mình muốn nó tự động lấy luôn, không phải nhập bằng tay vì trong file text dữ liệu chỗ Linename có thể thay đổi, không cố đinh)
Bạn xem có hiệu chỉnh Code được không
- Còn một vấn đề nữa là file .txt thì có rất nhiều tên,
nếu mình muốn để 2 file vào một folder, mở excel lên và chạy code mà không cần sửa tên trùng nhau giữa {10203040.txt và FilesToOpen = ThisWorkbook.Path & "\10203040-RS.txt" } thì có được không?
Cảm ơn Bạn.
Đính kèm Code:
Sub Main()
Dim sArr As Variant, dArr As Variant, Res As Variant, S As Variant
Dim ProName As String, LineName As String, tmp As String, FilesToOpen As String
Dim i As Long, fR As Long, nR As Long, k As Long, ik As Long, j As Byte

FilesToOpen = ThisWorkbook.Path & "\10203040-RS.txt"
sArr = ImportTextToExcel(FilesToOpen)
dArr = Range("B7:k8").Value
ReDim Res(1 To UBound(sArr), 1 To 7)

For j = 1 To 6
Res(1, j) = dArr(1, j): Res(2, j) = dArr(2, j)
Next j
Res(2, 7) = dArr(2, 7)
ProName = Split(sArr(3, 3), ".")(0)
Res(1, 2) = ProName & "-RS1"
Res(1, 1) = "Program Name"
Res(1, 6) = "No. of components"
Res(1, 4) = "Simulated time (s)"
Res(2, 1) = "F. Position N."
Res(2, 2) = "Component Name"
Res(2, 3) = "Placement ID"
Res(2, 4) = "Description"
Res(2, 5) = "Feeder Type"
Res(2, 6) = "Component pitch"
Res(2, 7) = "Qty."

With CreateObject("scripting.dictionary")
For i = 1 To UBound(sArr)
If Left(sArr(i, 1), 2) = "F-" Then fR = i: Exit For
Next i
k = 2
For i = fR To UBound(sArr)
k = k + 1
If Left(sArr(i, 1), 2) = "F-" Then
Res(k, 1) = sArr(i, 1)
Res(k, 5) = sArr(i, 4)
Res(k, 6) = sArr(i, 5)
Key = sArr(i, 2)
S = Split(Key, " ")
Res(k, 2) = S(1): Res(k, 4) = S(0)
.Item(Key) = k
Else
For j = 1 To 6
Res(k, j) = dArr(1, j)
Next j
Res(k, 1) = "Program Name"
Res(k, 2) = ProName & "-RS2"
nR = k
Res(k, 6) = "No. of components"
Res(k, 4) = "Simulated time (s)"
End If
Next i

For i = 1 To UBound(sArr)
If sArr(i, 1) = "No." Then fR = i + 1: Exit For
Next i
For i = fR To UBound(sArr)
Key = sArr(i, 6)
If Key = "" Then Exit For
If .exists(Key) Then
ik = .Item(Key)
Res(ik, 7) = Res(ik, 7) + 1
If ik < nR Then Res(1, 7) = Res(1, 7) + 1 Else Res(nR, 7) = Res(nR, 7) + 1

If Res(ik, 3) = "" Then
Res(ik, 3) = sArr(i, 2)
Else
Res(ik, 3) = Res(ik, 3) & ", " & sArr(i, 2)
End If
End If
Next i
k = k + 1
Res(k, 6) = "Total placements"
Res(k, 7) = Res(1, 7) + Res(nR, 7)
End With
[B7].Resize(k, 6).NumberFormat = "@"
[B7].Resize(k, 7) = Res
End Sub
Function ImportTextToExcel(ByVal FilesToOpen As String) As Variant
Dim fso As Object, TextSource As Object
Dim sArr As Variant, Res As Variant
Dim Str As String, tmp As String
Dim i As Long, k As Byte, S As Byte, j As Byte, n As Byte, sC As Byte
Dim dArr As Long

Set fso = CreateObject("Scripting.FileSystemObject")
Set TextSource = fso_OpenTextFile(FilesToOpen, 1, False, -2)
sArr = Split(TextSource.ReadAll, vbCrLf)
ReDim Res(1 To UBound(sArr), 1 To 1)
For i = LBound(sArr) To UBound(sArr)
Str = sArr(i)
S = Len(Str)
If S Then
k = 0
Test = False
For j = 1 To S - 1
If Mid(Str, j, 1) <> " " Then
k = k + 1
If sC < k Then
sC = k
ReDim Preserve Res(1 To UBound(sArr), 1 To k)
End If
tmp = ""
For n = j To S - 1
If Mid(Str, n, 2) <> " " Then
tmp = tmp & Mid(Str, n, 1)
Else
Res(i + 1, k) = tmp
j = n
Exit For
End If
Next n
End If
Next j
End If
Next i
ImportTextToExcel = Res
Set fso = Nothing: Set TextSource = Nothing
End Function
Xem file
 

File đính kèm

  • Mo ta chi tiet 1.xlsm
    36.5 KB · Đọc: 23
Cảm ơn Bạn HieuCD Nha,
Thấy tin nhắn của bạn lâu rồi mà tài khoản có vấn đề, giờ mới download, mới trả lời tin Cảm ơn bạn được, Mừng quá luôn
Vấn đề của mình bạn đã hỗ trợ xong, cảm ơn Bạn.
 
Bạn HieuCD ơi,
Cho mình hỏi vấn đề liên quan nữa Nha,
File .txt hôm bữa mình gửi là file xuất từ chương trình của mình với số lượng linh kiện ít, số vị trí gắn trên máy chỉ ở phía trước (Front)
Giờ chạy chương trình có nhiều linh kiện, máy optimize sẽ balance chương trình để Cycle time bé nên sẽ chia linh kiện ra phía sau nữa (Rear)
theo Code VBA thì khi tìm thấy "F-" thì mới làm các bước tiếp theo, giờ thực tế trên file txt có cả "R-" và "F-" đan xen,
1525236455441.png
Bạn có thể sửa lại giùm cho mình code được không?
Cảm ơn bạn!
 
Bạn HieuCD ơi,
Cho mình hỏi vấn đề liên quan nữa Nha,
File .txt hôm bữa mình gửi là file xuất từ chương trình của mình với số lượng linh kiện ít, số vị trí gắn trên máy chỉ ở phía trước (Front)
Giờ chạy chương trình có nhiều linh kiện, máy optimize sẽ balance chương trình để Cycle time bé nên sẽ chia linh kiện ra phía sau nữa (Rear)
theo Code VBA thì khi tìm thấy "F-" thì mới làm các bước tiếp theo, giờ thực tế trên file txt có cả "R-" và "F-" đan xen,
View attachment 194786
Bạn có thể sửa lại giùm cho mình code được không?
Cảm ơn bạn!
Chạy code và kiểm tra lại
Mã:
Sub Main()
  Dim sArr As Variant, dArr As Variant, Res As Variant, s As Variant
  Dim ProName As String, tmp As String, FilesToOpen As String
  Dim i As Long, fR As Long, nR As Long, k As Long, ik As Long, j As Byte
  Dim Chk As Boolean
  Chk = Application.FileDialog(msoFileDialogFilePicker).Show
  If Not Chk Then Exit Sub
  FilesToOpen = Application.FileDialog(msoFileDialogFilePicker).SelectedItems(1)
  sArr = ImportTextToExcel(FilesToOpen)

  dArr = Range("B7:H8").Value
  ReDim Res(1 To UBound(sArr), 1 To 7)
 
  For j = 1 To 6
    Res(1, j) = dArr(1, j): Res(2, j) = dArr(2, j)
  Next j
  Res(2, 7) = dArr(2, 7)
  ProName = Split(sArr(3, 4), ".")(0) & "-" & sArr(4, 8)
  Res(1, 2) = ProName & "1"
 
  With CreateObject("scripting.dictionary")
    For i = 1 To UBound(sArr)
      If sArr(i, 1) = "Feeder" Then fR = i + 1: Exit For
    Next i
    k = 2
    For i = fR To UBound(sArr)
      k = k + 1
      If sArr(i, 1) <> "Feeder" Then
        Res(k, 1) = sArr(i, 1)
        Res(k, 2) = sArr(i, 3)
        Res(k, 4) = sArr(i, 2)
        Res(k, 5) = sArr(i, 5) & " " & sArr(i, 6)
        Res(k, 6) = sArr(i, 7)
        Key = sArr(i, 2) & "#" & sArr(i, 3)
        .Item(Key) = k
      Else
        For j = 1 To 6
          Res(k, j) = dArr(1, j)
        Next j
        Res(k, 2) = ProName & "2"
        nR = k
      End If
    Next i
   
    For i = 1 To UBound(sArr)
      If sArr(i, 1) = "No." Then fR = i + 1: Exit For
    Next i
    For i = fR To UBound(sArr)
      Key = sArr(i, 6) & "#" & sArr(i, 7)
      If Key = "#" Then Exit For
      If .exists(Key) Then
        ik = .Item(Key)
        Res(ik, 7) = Res(ik, 7) + 1
        If ik < nR Then Res(1, 7) = Res(1, 7) + 1 Else Res(nR, 7) = Res(nR, 7) + 1
       
        If Res(ik, 3) = "" Then
          Res(ik, 3) = sArr(i, 2)
        Else
          Res(ik, 3) = Res(ik, 3) & ", " & sArr(i, 2)
        End If
      End If
    Next i
    k = k + 1
    Res(k, 6) = "Total placements"
    Res(k, 7) = Res(1, 7) + Res(nR, 7)
  End With
  [B7].Resize(k, 6).NumberFormat = "@"
  [B7].Resize(k, 7) = Res
End Sub

Function ImportTextToExcel(ByVal FilesToOpen As String) As Variant
  Dim fso As Object, TextSource As Object
  Dim sArr As Variant, Res As Variant, s As Variant
  Dim Str As String, tmp As String
  Dim i As Long, k As Byte, j As Byte, n As Byte, sC As Byte
 
  Set fso = CreateObject("Scripting.FileSystemObject")
  Set TextSource = fso.OpenTextFile(FilesToOpen, 1, False, -2)
  sArr = Split(TextSource.ReadAll, vbCrLf)
  ReDim Res(1 To UBound(sArr), 1 To 1)
  For i = LBound(sArr) To UBound(sArr)
    Str = Application.Trim(sArr(i))
    s = Split(Str)
    If UBound(s) > 0 Then
      k = UBound(s) + 1
      If sC < k Then
        sC = k
        ReDim Preserve Res(1 To UBound(sArr), 1 To sC)
      End If
      For j = 0 To k - 1
        Res(i + 1, j + 1) = s(j)
      Next j
    End If
  Next i
  ImportTextToExcel = Res
  Set fso = Nothing: Set TextSource = Nothing
End Function
 
Chạy code và kiểm tra lại
Mã:
Sub Main()
  Dim sArr As Variant, dArr As Variant, Res As Variant, s As Variant
  Dim ProName As String, tmp As String, FilesToOpen As String
  Dim i As Long, fR As Long, nR As Long, k As Long, ik As Long, j As Byte
  Dim Chk As Boolean
  Chk = Application.FileDialog(msoFileDialogFilePicker).Show
  If Not Chk Then Exit Sub
  FilesToOpen = Application.FileDialog(msoFileDialogFilePicker).SelectedItems(1)
  sArr = ImportTextToExcel(FilesToOpen)

  dArr = Range("B7:H8").Value
  ReDim Res(1 To UBound(sArr), 1 To 7)

  For j = 1 To 6
    Res(1, j) = dArr(1, j): Res(2, j) = dArr(2, j)
  Next j
  Res(2, 7) = dArr(2, 7)
  ProName = Split(sArr(3, 4), ".")(0) & "-" & sArr(4, 8)
  Res(1, 2) = ProName & "1"

  With CreateObject("scripting.dictionary")
    For i = 1 To UBound(sArr)
      If sArr(i, 1) = "Feeder" Then fR = i + 1: Exit For
    Next i
    k = 2
    For i = fR To UBound(sArr)
      k = k + 1
      If sArr(i, 1) <> "Feeder" Then
        Res(k, 1) = sArr(i, 1)
        Res(k, 2) = sArr(i, 3)
        Res(k, 4) = sArr(i, 2)
        Res(k, 5) = sArr(i, 5) & " " & sArr(i, 6)
        Res(k, 6) = sArr(i, 7)
        Key = sArr(i, 2) & "#" & sArr(i, 3)
        .Item(Key) = k
      Else
        For j = 1 To 6
          Res(k, j) = dArr(1, j)
        Next j
        Res(k, 2) = ProName & "2"
        nR = k
      End If
    Next i
  
    For i = 1 To UBound(sArr)
      If sArr(i, 1) = "No." Then fR = i + 1: Exit For
    Next i
    For i = fR To UBound(sArr)
      Key = sArr(i, 6) & "#" & sArr(i, 7)
      If Key = "#" Then Exit For
      If .exists(Key) Then
        ik = .Item(Key)
        Res(ik, 7) = Res(ik, 7) + 1
        If ik < nR Then Res(1, 7) = Res(1, 7) + 1 Else Res(nR, 7) = Res(nR, 7) + 1
      
        If Res(ik, 3) = "" Then
          Res(ik, 3) = sArr(i, 2)
        Else
          Res(ik, 3) = Res(ik, 3) & ", " & sArr(i, 2)
        End If
      End If
    Next i
    k = k + 1
    Res(k, 6) = "Total placements"
    Res(k, 7) = Res(1, 7) + Res(nR, 7)
  End With
  [B7].Resize(k, 6).NumberFormat = "@"
  [B7].Resize(k, 7) = Res
End Sub

Function ImportTextToExcel(ByVal FilesToOpen As String) As Variant
  Dim fso As Object, TextSource As Object
  Dim sArr As Variant, Res As Variant, s As Variant
  Dim Str As String, tmp As String
  Dim i As Long, k As Byte, j As Byte, n As Byte, sC As Byte

  Set fso = CreateObject("Scripting.FileSystemObject")
  Set TextSource = fso.OpenTextFile(FilesToOpen, 1, False, -2)
  sArr = Split(TextSource.ReadAll, vbCrLf)
  ReDim Res(1 To UBound(sArr), 1 To 1)
  For i = LBound(sArr) To UBound(sArr)
    Str = Application.Trim(sArr(i))
    s = Split(Str)
    If UBound(s) > 0 Then
      k = UBound(s) + 1
      If sC < k Then
        sC = k
        ReDim Preserve Res(1 To UBound(sArr), 1 To sC)
      End If
      For j = 0 To k - 1
        Res(i + 1, j + 1) = s(j)
      Next j
    End If
  Next i
  ImportTextToExcel = Res
  Set fso = Nothing: Set TextSource = Nothing
End Function
Cảm ơn Bạn rất nhiều,
Chúc Bạn buổi tối vui vẻ.
 
Chào Bạn HieuCD
Nhờ bạn kiểm tra lại code cho mình với: Mình mô tả vấn đề như sau,
Khi làm bị lỗi như dưới:
1525866748304.png
Trong file .txt trong mục "type" sau chữ M 8mm có vị trí chương trình nó xuất ra thêm chữ (paper - emboss) khi chuyển sang sử dụng code bị lỗi như trên hình,
Nhờ Bạn xem lại dùm mình với được không.
Cảm ơn Bạn.
 

File đính kèm

  • 10102341-A.txt
    14.3 KB · Đọc: 6
Chào Bạn HieuCD
Nhờ bạn kiểm tra lại code cho mình với: Mình mô tả vấn đề như sau,
Khi làm bị lỗi như dưới:
View attachment 195196
Trong file .txt trong mục "type" sau chữ M 8mm có vị trí chương trình nó xuất ra thêm chữ (paper - emboss) khi chuyển sang sử dụng code bị lỗi như trên hình,
Nhờ Bạn xem lại dùm mình với được không.
Cảm ơn Bạn.
Chỉnh lại toàn bộ code
Mã:
Sub Main()
  Dim sArr As Variant, dArr As Variant, Res As Variant, s As Variant
  Dim ProName As String, tmp As String, FilesToOpen As String
  Dim i As Long, fR As Long, nR As Long, k As Long, ik As Long, j As Byte
  Dim Chk As Boolean
  Chk = Application.FileDialog(msoFileDialogFilePicker).Show
  If Not Chk Then Exit Sub
  FilesToOpen = Application.FileDialog(msoFileDialogFilePicker).SelectedItems(1)
  sArr = ImportTextToExcel(FilesToOpen)
  dArr = Range("B7:H8").Value
  ReDim Res(1 To UBound(sArr), 1 To 7)
 
  For j = 1 To 6
    Res(1, j) = dArr(1, j): Res(2, j) = dArr(2, j)
  Next j
  Res(2, 7) = dArr(2, 7)
  Res(1, 2) = sArr(1, 1) & "1"
 
  With CreateObject("scripting.dictionary")
    For i = 1 To UBound(sArr)
      If sArr(i, 1) = "Feeder Position Number" Then fR = i + 1: Exit For
    Next i
    k = 2
    For i = fR To UBound(sArr)
      If sArr(i, 1) <> "" Then
      k = k + 1
      If sArr(i, 1) <> "Feeder Position Number" Then
        Key = sArr(i, 2)
        .Item(Key) = k
       
        Res(k, 1) = sArr(i, 1)
        s = Split(Key, " ")
        Res(k, 2) = s(1)
        Res(k, 4) = s(0)
        Res(k, 5) = sArr(i, 3)
        Res(k, 6) = sArr(i, 4)
      Else
        For j = 1 To 6
          Res(k, j) = dArr(1, j)
        Next j
        Res(k, 2) = sArr(1, 1) & "2"
        nR = k
      End If
      End If
    Next i
   
    For i = 1 To UBound(sArr)
      If sArr(i, 1) = "Placement ID" Then fR = i + 1: Exit For
    Next i
    For i = fR To UBound(sArr)
      Key = sArr(i, 2)
      If Key = "Feeder Position Number" Then Exit For
      If .exists(Key) Then
        ik = .Item(Key)
        Res(ik, 7) = Res(ik, 7) + 1
        If ik < nR Then Res(1, 7) = Res(1, 7) + 1 Else Res(nR, 7) = Res(nR, 7) + 1
       
        If Res(ik, 3) = "" Then
          Res(ik, 3) = sArr(i, 1)
        Else
          Res(ik, 3) = Res(ik, 3) & ", " & sArr(i, 1)
        End If
      End If
    Next i
    k = k + 1
    Res(k, 6) = "Total placements"
    Res(k, 7) = Res(1, 7) + Res(nR, 7)
  End With
  [B7].Resize(k, 6).NumberFormat = "@"
  [B7].Resize(k, 7) = Res
End Sub

Function ImportTextToExcel(ByVal FilesToOpen As String) As Variant
  Dim fso As Object, TextSource As Object
  Dim sArr As Variant, Res As Variant
  Dim str As String, tmp As String
  Dim i As Long, k As Long, j As Byte, n As Byte, sC As Byte
  Dim fCol1 As Integer, sCol1 As Integer, fCol2 As Integer, sCol2 As Integer
  Dim fCol3 As Integer, sCol3 As Integer, fCol4 As Integer, sCol4 As Integer
 
  Set fso = CreateObject("Scripting.FileSystemObject")
  Set TextSource = fso.OpenTextFile(FilesToOpen, 1, False, -2)
  sArr = Split(TextSource.ReadAll, vbCrLf)
  ReDim Res(1 To UBound(sArr), 1 To 4)
  For i = LBound(sArr) To UBound(sArr)
    str = Application.Trim(sArr(i))
    tmp = "Program Name ="
    If InStr(str, tmp) Then
      k = k + 1
      j = InStr(str, tmp) + Len(tmp) + 1
      Res(k, 1) = Application.Trim(Split(Mid(str, j, 20), ".")(0))
    Else
      tmp = "Line Name ="
      If InStr(str, tmp) Then
        j = InStr(str, tmp) + Len(tmp) + 1
        Res(k, 1) = Res(1, 1) & "-" & Application.Trim(Mid(str, j, 20))
        j = i + 1: Exit For
      End If
    End If
  Next i
 
  For i = j To UBound(sArr)
    str = sArr(i)
    tmp = "Placement"
    If InStr(str, tmp) Then
      fCol1 = InStr(str, tmp)
      sCol1 = InStr(str, "X") - fCol1
      tmp = "Component"
      fCol2 = InStr(str, tmp)
      sCol2 = InStr(str, "Centering") - fCol2
      j = i: Exit For
    End If
  Next i
 
  For i = j To UBound(sArr)
    str = sArr(i)
    If Len(Application.Trim(sArr(i))) < 2 Then j = i + 2: Exit For
    k = k + 1
    Res(k, 1) = Application.Trim(Mid(str, fCol1, sCol1))
    Res(k, 2) = Application.Trim(Mid(str, fCol2, sCol2))
  Next i
 
  For i = j To UBound(sArr)
    str = sArr(i)
    tmp = "Feeder Position"
    If InStr(str, tmp) Then
      fCol1 = InStr(str, tmp)
     
      tmp = "Component Name"
      fCol2 = InStr(str, tmp)
      sCol1 = fCol2 - fCol1
      sCol2 = InStr(str, "Comment") - fCol2
     
      tmp = "Type"
      fCol3 = InStr(str, tmp)
      tmp = "Component pitch"
      fCol4 = InStr(str, tmp)
      sCol3 = fCol4 - fCol3
      sCol4 = InStr(str, "Lane") - fCol4
      j = i: Exit For
    End If
  Next i
 
  For i = j To UBound(sArr)
    str = sArr(i)
    If Len(Application.Trim(sArr(i))) < 2 Then Exit For
    k = k + 1
    Res(k, 1) = Application.Trim(Mid(str, fCol1, sCol1))
    Res(k, 2) = Application.Trim(Mid(str, fCol2, sCol2))
    Res(k, 3) = Application.Trim(Mid(str, fCol3, sCol3))
    Res(k, 4) = Application.Trim(Mid(str, fCol4, sCol4))
  Next i
 
  ImportTextToExcel = Res
  Set fso = Nothing: Set TextSource = Nothing
End Function
 
Chỉnh lại toàn bộ code
Mã:
Sub Main()
  Dim sArr As Variant, dArr As Variant, Res As Variant, s As Variant
  Dim ProName As String, tmp As String, FilesToOpen As String
  Dim i As Long, fR As Long, nR As Long, k As Long, ik As Long, j As Byte
  Dim Chk As Boolean
  Chk = Application.FileDialog(msoFileDialogFilePicker).Show
  If Not Chk Then Exit Sub
  FilesToOpen = Application.FileDialog(msoFileDialogFilePicker).SelectedItems(1)
  sArr = ImportTextToExcel(FilesToOpen)
  dArr = Range("B7:H8").Value
  ReDim Res(1 To UBound(sArr), 1 To 7)

  For j = 1 To 6
    Res(1, j) = dArr(1, j): Res(2, j) = dArr(2, j)
  Next j
  Res(2, 7) = dArr(2, 7)
  Res(1, 2) = sArr(1, 1) & "1"

  With CreateObject("scripting.dictionary")
    For i = 1 To UBound(sArr)
      If sArr(i, 1) = "Feeder Position Number" Then fR = i + 1: Exit For
    Next i
    k = 2
    For i = fR To UBound(sArr)
      If sArr(i, 1) <> "" Then
      k = k + 1
      If sArr(i, 1) <> "Feeder Position Number" Then
        Key = sArr(i, 2)
        .Item(Key) = k
      
        Res(k, 1) = sArr(i, 1)
        s = Split(Key, " ")
        Res(k, 2) = s(1)
        Res(k, 4) = s(0)
        Res(k, 5) = sArr(i, 3)
        Res(k, 6) = sArr(i, 4)
      Else
        For j = 1 To 6
          Res(k, j) = dArr(1, j)
        Next j
        Res(k, 2) = sArr(1, 1) & "2"
        nR = k
      End If
      End If
    Next i
  
    For i = 1 To UBound(sArr)
      If sArr(i, 1) = "Placement ID" Then fR = i + 1: Exit For
    Next i
    For i = fR To UBound(sArr)
      Key = sArr(i, 2)
      If Key = "Feeder Position Number" Then Exit For
      If .exists(Key) Then
        ik = .Item(Key)
        Res(ik, 7) = Res(ik, 7) + 1
        If ik < nR Then Res(1, 7) = Res(1, 7) + 1 Else Res(nR, 7) = Res(nR, 7) + 1
      
        If Res(ik, 3) = "" Then
          Res(ik, 3) = sArr(i, 1)
        Else
          Res(ik, 3) = Res(ik, 3) & ", " & sArr(i, 1)
        End If
      End If
    Next i
    k = k + 1
    Res(k, 6) = "Total placements"
    Res(k, 7) = Res(1, 7) + Res(nR, 7)
  End With
  [B7].Resize(k, 6).NumberFormat = "@"
  [B7].Resize(k, 7) = Res
End Sub

Function ImportTextToExcel(ByVal FilesToOpen As String) As Variant
  Dim fso As Object, TextSource As Object
  Dim sArr As Variant, Res As Variant
  Dim str As String, tmp As String
  Dim i As Long, k As Long, j As Byte, n As Byte, sC As Byte
  Dim fCol1 As Integer, sCol1 As Integer, fCol2 As Integer, sCol2 As Integer
  Dim fCol3 As Integer, sCol3 As Integer, fCol4 As Integer, sCol4 As Integer

  Set fso = CreateObject("Scripting.FileSystemObject")
  Set TextSource = fso.OpenTextFile(FilesToOpen, 1, False, -2)
  sArr = Split(TextSource.ReadAll, vbCrLf)
  ReDim Res(1 To UBound(sArr), 1 To 4)
  For i = LBound(sArr) To UBound(sArr)
    str = Application.Trim(sArr(i))
    tmp = "Program Name ="
    If InStr(str, tmp) Then
      k = k + 1
      j = InStr(str, tmp) + Len(tmp) + 1
      Res(k, 1) = Application.Trim(Split(Mid(str, j, 20), ".")(0))
    Else
      tmp = "Line Name ="
      If InStr(str, tmp) Then
        j = InStr(str, tmp) + Len(tmp) + 1
        Res(k, 1) = Res(1, 1) & "-" & Application.Trim(Mid(str, j, 20))
        j = i + 1: Exit For
      End If
    End If
  Next i

  For i = j To UBound(sArr)
    str = sArr(i)
    tmp = "Placement"
    If InStr(str, tmp) Then
      fCol1 = InStr(str, tmp)
      sCol1 = InStr(str, "X") - fCol1
      tmp = "Component"
      fCol2 = InStr(str, tmp)
      sCol2 = InStr(str, "Centering") - fCol2
      j = i: Exit For
    End If
  Next i

  For i = j To UBound(sArr)
    str = sArr(i)
    If Len(Application.Trim(sArr(i))) < 2 Then j = i + 2: Exit For
    k = k + 1
    Res(k, 1) = Application.Trim(Mid(str, fCol1, sCol1))
    Res(k, 2) = Application.Trim(Mid(str, fCol2, sCol2))
  Next i

  For i = j To UBound(sArr)
    str = sArr(i)
    tmp = "Feeder Position"
    If InStr(str, tmp) Then
      fCol1 = InStr(str, tmp)
    
      tmp = "Component Name"
      fCol2 = InStr(str, tmp)
      sCol1 = fCol2 - fCol1
      sCol2 = InStr(str, "Comment") - fCol2
    
      tmp = "Type"
      fCol3 = InStr(str, tmp)
      tmp = "Component pitch"
      fCol4 = InStr(str, tmp)
      sCol3 = fCol4 - fCol3
      sCol4 = InStr(str, "Lane") - fCol4
      j = i: Exit For
    End If
  Next i

  For i = j To UBound(sArr)
    str = sArr(i)
    If Len(Application.Trim(sArr(i))) < 2 Then Exit For
    k = k + 1
    Res(k, 1) = Application.Trim(Mid(str, fCol1, sCol1))
    Res(k, 2) = Application.Trim(Mid(str, fCol2, sCol2))
    Res(k, 3) = Application.Trim(Mid(str, fCol3, sCol3))
    Res(k, 4) = Application.Trim(Mid(str, fCol4, sCol4))
  Next i

  ImportTextToExcel = Res
  Set fso = Nothing: Set TextSource = Nothing
End Function
Cảm ơn bạn HieuCD đã bỏ thời gian sửa lại Code.
Bạn ơi, khi mình bỏ file vào chạy bị lỗi trong cột "Placement ID" bị chèn thêm (lặp lại) cột vị trí ("F-..." hoặc "R-...")
Bạn có thể bỏ giúp mình không, Ở code lúc trước Bạn đã bỏ chữ "M" trong hai cột (Feeder Type và Comp.t pitch) giờ bạn có thể bỏ dùm mình không, tại vì chữ "M" này không có ý nghĩa,
Mong bạn xem qua
1525911514789.png1525911514789.png
Cảm ơn Bạn.
 
Cảm ơn bạn HieuCD đã bỏ thời gian sửa lại Code.
Bạn ơi, khi mình bỏ file vào chạy bị lỗi trong cột "Placement ID" bị chèn thêm (lặp lại) cột vị trí ("F-..." hoặc "R-...")
Bạn có thể bỏ giúp mình không, Ở code lúc trước Bạn đã bỏ chữ "M" trong hai cột (Feeder Type và Comp.t pitch) giờ bạn có thể bỏ dùm mình không, tại vì chữ "M" này không có ý nghĩa,
Mong bạn xem qua
View attachment 195213View attachment 195213
Cảm ơn Bạn.
Chỉnh code
Mã:
Sub Main()
  Dim sArr As Variant, dArr As Variant, Res As Variant, s As Variant
  Dim ProName As String, tmp As String, FilesToOpen As String
  Dim i As Long, fR As Long, nR As Long, k As Long, ik As Long, j As Byte
  Dim Chk As Boolean
  Chk = Application.FileDialog(msoFileDialogFilePicker).Show
  If Not Chk Then Exit Sub
  FilesToOpen = Application.FileDialog(msoFileDialogFilePicker).SelectedItems(1)
  sArr = ImportTextToExcel(FilesToOpen)

  dArr = Range("B7:H8").Value
  ReDim Res(1 To UBound(sArr), 1 To 7)
  For j = 1 To 6
    Res(1, j) = dArr(1, j): Res(2, j) = dArr(2, j)
  Next j
  Res(2, 7) = dArr(2, 7)
  Res(1, 2) = sArr(1, 1) & "1"
 
  With CreateObject("scripting.dictionary")
    For i = 1 To UBound(sArr)
      If sArr(i, 1) = "Feeder Position Number" Then fR = i + 1: Exit For
    Next i
    k = 2
    For i = fR To UBound(sArr)
      If sArr(i, 1) <> "" Then
      k = k + 1
      If sArr(i, 1) <> "Feeder Position Number" Then
        Key = sArr(i, 2)
        .Item(Key) = k
        Res(k, 1) = sArr(i, 1)
        s = Split(Key, " ")
        Res(k, 2) = s(1)
        Res(k, 4) = s(0)
        Res(k, 5) = Mid(sArr(i, 3), 3, Len(sArr(i, 3)))
        Res(k, 6) = Split(sArr(i, 4), " ")(0)
      Else
        For j = 1 To 6
          Res(k, j) = dArr(1, j)
        Next j
        Res(k, 2) = sArr(1, 1) & "2"
        nR = k
      End If
      End If
    Next i
   
    For i = 1 To UBound(sArr)
      If sArr(i, 1) = "Placement ID" Then fR = i + 1: Exit For
    Next i
    For i = fR To UBound(sArr)
      If sArr(i, 1) = "Feeder Position Number" Then Exit For
      Key = sArr(i, 2)
      If .exists(Key) Then
        ik = .Item(Key)
        Res(ik, 7) = Res(ik, 7) + 1
        If ik < nR Then Res(1, 7) = Res(1, 7) + 1 Else Res(nR, 7) = Res(nR, 7) + 1
       
        If Res(ik, 3) = "" Then
          Res(ik, 3) = sArr(i, 1)
        Else
          Res(ik, 3) = Res(ik, 3) & ", " & sArr(i, 1)
        End If
      End If
    Next i
    k = k + 1
    Res(k, 6) = "Total placements"
    Res(k, 7) = Res(1, 7) + Res(nR, 7)
  End With
  [B7].Resize(k, 6).NumberFormat = "@"
  [B7].Resize(k, 7) = Res
End Sub

Function ImportTextToExcel(ByVal FilesToOpen As String) As Variant
  Dim fso As Object, TextSource As Object
  Dim sArr As Variant, Res As Variant, Sign(), Sign2(), Sign3(), iCol()
  Dim str As String, tmp As String
  Dim i As Long, k As Long, j As Byte, n As Byte, sC As Byte
 
  Set fso = CreateObject("Scripting.FileSystemObject")
  Set TextSource = fso.OpenTextFile(FilesToOpen, 1, False, -2)
  sArr = Split(TextSource.ReadAll, vbCrLf)
  ReDim Res(1 To UBound(sArr), 1 To 4)
 
  Sign = Array("Program Name =", "Line Name =")
  For i = LBound(sArr) To UBound(sArr)
    str = Application.Trim(sArr(i))
    For n = LBound(Sign) To UBound(Sign)
      If InStr(str, Sign(n)) Then
        j = InStr(str, Sign(n)) + Len(Sign(n)) + 1
        If Res(1, 1) = vbEmpty Then
          Res(1, 1) = Application.Trim(Split(Mid(str, j, 20), ".")(0))
        Else
          Res(1, 1) = Res(1, 1) & "-" & Application.Trim(Mid(str, j, 20))
          j = i + 1: Exit For
        End If
      End If
    Next n
  Next i
 
  k = 1
  Sign = Array("Placement", "X", "Component Name", "Centering")
  ReDim iCol(LBound(Sign) To UBound(Sign))
  For i = j To UBound(sArr)
    str = sArr(i)
    If InStr(str, Sign(0)) Then
      For n = LBound(Sign) To UBound(Sign)
        iCol(n) = InStr(str, Sign(n))
      Next n
      j = i: Exit For
    End If
  Next i
 
  For i = j To UBound(sArr)
    str = sArr(i)
    If Len(Application.Trim(sArr(i))) < 2 Then j = i + 2: Exit For
    k = k + 1
    Res(k, 1) = Application.Trim(Mid(str, iCol(0), iCol(1) - iCol(0)))
    Res(k, 2) = Application.Trim(Mid(str, iCol(2), iCol(3) - iCol(2)))
  Next i
 
  Sign = Array("Feeder Position", "Component Name", "Component Name", "Comment", "Type", "Component pitch", "Component pitch", "Lane")
  ReDim iCol(LBound(Sign) To UBound(Sign))
  For i = j To UBound(sArr)
    str = sArr(i)
    If InStr(str, Sign(0)) Then
      For n = LBound(Sign) To UBound(Sign)
        iCol(n) = InStr(str, Sign(n))
      Next n
      j = i: Exit For
    End If
  Next i
 
  For i = j To UBound(sArr)
    str = sArr(i)
    If Len(Application.Trim(sArr(i))) < 2 Then Exit For
    k = k + 1
    For n = 1 To 4
      Res(k, n) = Application.Trim(Mid(str, iCol(n * 2 - 2), iCol(n * 2 - 1) - iCol(n * 2 - 2)))
    Next n
  Next i
 
  ImportTextToExcel = Res
  Set fso = Nothing: Set TextSource = Nothing
End Function
 
Sau 5 lần thì mọi nội dung đã được như mong muốn,
Nhìn Code bạn viết mà thèm, để viết được Code như vậy chắc tư duy cao lắm, Rất ngưỡng mộ.
cảm ơn Bạn HieuCD
 
Sau 5 lần thì mọi nội dung đã được như mong muốn,
Nhìn Code bạn viết mà thèm, để viết được Code như vậy chắc tư duy cao lắm, Rất ngưỡng mộ.
cảm ơn Bạn HieuCD
Muốn thành anh Bill thì khó chứ muốn được như các thành viên GPE này lại dễ. Cứ làm từ nhỏ đến lớn, một ngày nào đó bạn sẽ mĩm cười nói thầm rằng "Sao bài hồi đó dễ vậy chứ!"
 
Xin chào các anh chị trên diễn đàn. Chào anh HieuCD, anh ndu96081631
Mình đang làm về các trạm đo kiểm tự động và nó xuất ra các file dữ liệu dạng "txt", hoặc "CSV". Có nhiều trạm, mỗi trạm có nhiều file và mỗi file rất nhiều dòng. Mình muốn gộp vào 01 file excel, dữ liệu lấy từ các file "CSV" sẽ nối tiếp trong file excel.
Qua theo dõi các bài mà các anh đang hướng dẫn mọi người (https://www.giaiphapexcel.com/diendan/threads/trích-lọc-dữ-liệu-sử-dụng-vba-code.134511/; https://www.giaiphapexcel.com/diendan/threads/nhập-tự-động-dữ-liệu-từ-file-notepad-sang-excel.79982/) mình thấy cũng có điểm giống với điều mình đang mong muốn.
Tuy nhiên do không biết gì về VBA (trước mình có học qua một số ngôn ngữ lập trình C; Pascal; ASSAMBLY, nhưng không chuyên) nên mình không hiểu được code để sửa.
Vậy 2 anh có thể giúp mình đoạn code để làm việc này được không?
File dữ liệu nguồn (một số file điển hình) và file excel đích như mình gửi kèm.
Cám ơn 2 anh!
 

File đính kèm

  • Test.rar
    18.4 KB · Đọc: 8
Xin chào các anh chị trên diễn đàn. Chào anh HieuCD, anh ndu96081631
Mình đang làm về các trạm đo kiểm tự động và nó xuất ra các file dữ liệu dạng "txt", hoặc "CSV". Có nhiều trạm, mỗi trạm có nhiều file và mỗi file rất nhiều dòng. Mình muốn gộp vào 01 file excel, dữ liệu lấy từ các file "CSV" sẽ nối tiếp trong file excel.
Qua theo dõi các bài mà các anh đang hướng dẫn mọi người (https://www.giaiphapexcel.com/diendan/threads/trích-lọc-dữ-liệu-sử-dụng-vba-code.134511/; https://www.giaiphapexcel.com/diendan/threads/nhập-tự-động-dữ-liệu-từ-file-notepad-sang-excel.79982/) mình thấy cũng có điểm giống với điều mình đang mong muốn.
Tuy nhiên do không biết gì về VBA (trước mình có học qua một số ngôn ngữ lập trình C; Pascal; ASSAMBLY, nhưng không chuyên) nên mình không hiểu được code để sửa.
Vậy 2 anh có thể giúp mình đoạn code để làm việc này được không?
File dữ liệu nguồn (một số file điển hình) và file excel đích như mình gửi kèm.
Cám ơn 2 anh!
Tìm trên diễn đàn cách dùng ADO mở file CSV không thấy nên chấp nhận chạy chậm
Số dòng kết bị giới hạn, nếu có thông báo thì gởi file để viết tiếp code
Mã:
Sub TongHop()
  Dim Wb As Workbook
  Dim pathStr As String, MyFile As String
  Dim Res() As String, sArr As Variant, dArr As Variant, S As Variant
  Dim i As Long, k As Long, eR As Long, n As Long, j As Byte
  
  Application.ScreenUpdating = False
  ReDim dArr(1 To 2, 1 To 1)
  pathStr = ThisWorkbook.Path 'Nhap duong dan truc tiep neu nam khac thu muc
  MyFile = Dir(pathStr & "\*.CSV")
  Do While MyFile <> ""
    k = k + 1
    ReDim Preserve dArr(1 To 2, 1 To k)
    dArr(1, k) = MyFile
    MyFile = Dir()
  Loop

  For n = 1 To k
    Set Wb = Workbooks.Open(pathStr & "\" & dArr(1, n), , True)
    If Len(Range("A1").Value) Then
      i = Range("A" & Rows.Count).End(xlUp).Row
      dArr(2, n) = Range("A1:A" & i).Value
      eR = eR + i
    End If
    Wb.Close
  Next n
  
  If eR Then
    k = 0
    ReDim Res(1 To eR, 1 To 5)
    For n = 1 To UBound(dArr, 2)
      sArr = dArr(2, n)
      If IsArray(sArr) Then
        For i = 1 To UBound(sArr)
          If Len(sArr(i, 1)) Then
            k = k + 1
            S = Split(sArr(i, 1), ";")
            For j = 0 To UBound(S)
              Res(k, j + 1) = S(j)
            Next j
          End If
        Next i
      End If
    Next n
  End If
  i = Range("A" & Rows.Count).End(xlUp).Row
  If i > 2 Then Range("A3:E" & i).ClearContents
  If k > 1048570 Then
    MsgBox ("Du leu qua lon, can viet lai code, tam lay mot so dong")
    k = 1048570
  End If
  Range("A3:E3").Resize(k) = Res
  Application.ScreenUpdating = True
End Sub
 
Web KT
Back
Top Bottom