Theo em là bác dùng left, right, midBin có chuỗi cần tách lấy dữ liệu trong chuỗi mong anh chị và các bạn giúp đỡ cách xử lý chuỗi này.
Xin cảm ơn mọi người.
View attachment 273131
Cám ơn bác @BuiQuangThuan, Bin có dùng hàm MID kết hợp với hàm Search để lấy giá trị VCSC[27] trong chuỗi A2. Nhưng cái khó ở VCSC[30] có 3 giá trị làm thế nào để phân biệt được giá trị đầu và giá trị cuối trong chuỗi. Nên hơi bị bế tắt ah.Theo em là bác dùng left, right, mid
Mới có 1 chuỗi thì không biết được quy luật, sang chuỗi sau mà thay đổi thì tèo.Theo em là bác dùng left, right, mid
Gõ vào ô cột B2 : =TRIM(SUBSTITUTE(SUBSTITUTE(A2,CHAR(13)," "),CHAR(10)," "))Mới có 1 chuỗi thì không biết được quy luật, sang chuỗi sau mà thay đổi thì tèo.
Em cũng tính vậy nếu nhiều chuỗi, còn chỉ một chuỗi thì khỏi cần tính anh ạ.Gõ vào ô cột B2 : =TRIM(SUBSTITUTE(SUBSTITUTE(A2,CHAR(13)," "),CHAR(10)," "))
Copy/Paste Values
Dùng text-to-columns.
Cám ơn bác @VetMini. Thú thật đây là mã trạng thái của nhân viên giao hàng quét lên gồm:mã trạng thái, ngày quét và giờ quét. Mỗi dòng là trạng thái của một lô hàng, nên số lượng mã có thể thay đổi không cố định.Gõ vào ô cột B2 : =TRIM(SUBSTITUTE(SUBSTITUTE(A2,CHAR(13)," "),CHAR(10)," "))
Copy/Paste Values
Dùng text-to-columns.
đây là mã trạng thái của nhân viên giao hàng quét lên
Cám ơn bác @befaint đã quan tâm. Tệp xuất từ phần mềm ra chỉ giống như cột A2. Do số lượng nhiều Bin chỉ lấy đại diện một vài mẫu để thực hành.Bạn gửi file dữ liệu ban đầu ấy (File xuất ra từ phần mềm).
Nhìn bên ngoài thì có thể giống, nhưng chưa chắc định dạng sẽ giống đâu.Tệp xuất từ phần mềm ra chỉ giống như cột A2.
Hình như cái máy quét này dùng hệ thống Mac hay Unix gì đó. Ký hiệu xuống dòng là Carriage Return (13). Ký hiệu xuống dòng căn bản của Windows là Line Feed (10).Nhìn bên ngoài thì có thể giống, nhưng chưa chắc định dạng sẽ giống đâu.
Không biết công thức của tôi có làm bạn sợ không ( hơi phức tạp )Cám ơn bác @VetMini. Thú thật đây là mã trạng thái của nhân viên giao hàng quét lên gồm:mã trạng thái, ngày quét và giờ quét. Mỗi dòng là trạng thái của một lô hàng, nên số lượng mã có thể thay đổi không cố định.
Bin gửi lại tệp có thêm một số chuỗi khác nữa phía sau.
Cám ơn.
Sub totite()
Const COTDULIEU = "A"
Const DONGBATDAU = 3
Dim a(1 To 100, 1 To 50) ' hope that the delivery note has less than 100 items, and less than 50 cycles
For Each cll In Range(COTDULIEU & DONGBATDAU, COTDULIEU & Range(COTDULIEU & ":" & COTDULIEU).Find("*", searchorder:=xlByRows, searchdirection:=xlPrevious).Row)
i = i + 1 ' prepare next line transaction
j = 1 ' reset column for next line transaction
For Each itm In Split(Application.Trim(Replace(Replace(Replace(cll.Value, Chr(13), "^"), Chr(13), "^"), "^^", "^")), "^") ' horrible!
If itm <> "" Then
details = Split(Application.Trim(Replace(itm, "@", " ")), " ") ' always 0:partID, 1,2: date, 4: whatever)
dte = CDate(details(1) & " " & details(2)) ' gets date time
itmCol = Application.Match(details(0), Application.Index(a, i, 0), 0)
If Not IsNumeric(itmCol) Then ' item already there
' new item within transaction
itmCol = j
a(i, itmCol) = details(0)
j = j + 4 ' update postion for next item in this line transaction
End If
If dte > a(i, itmCol + 1) + a(i, itmCol + 2) Then
a(i, itmCol + 1) = Fix(dte) ' date only
a(i, itmCol + 2) = dte - a(i, j + 1)
a(i, itmCol + 3) = Replace(Split(details(3), "-")(1), ")", "")
End If
End If
Next itm
Next cll
Range(COTDULIEU & DONGBATDAU).Offset(, 1).Resize(i, j).Value = a
End Sub
Sub totite2()
Const COTDULIEU = "A"
Const DONGBATDAU = 3
Const ROWMAX = 100
Const COLMAX = 50
Dim a(1 To ROWMAX, 1 To COLMAX) ' hope that the delivery note has less than 100 items, and less than 50 cycles
With CreateObject("Scripting.Dictionary")
For Each cll In Range(COTDULIEU & DONGBATDAU).CurrentRegion.Resize(, 1)
' resized to ensure that only one column is involved
' hình như ô A2 cũng có chứa gì đó, currentregion chép cả nó. Cần chỉnh
i = i + 1 ' prepare next line transaction
j = 1 ' reset column for next line transaction
For Each itm In Split(Replace(Replace(Replace(cll.Value, Chr(13), "^"), Chr(13), "^"), "^^", "^"), "^") ' horrible!
details = Application.Trim(Split(Replace(itm, "@", " "), " ")) ' always 0:partID, 1,2: date, 4: whatever)
dte = CDate(details(1) & " " & details(2)) ' gets date time
If Not .Exists(details(0)) Then
a(i, j) = details(0)
a(i, j + 1) = Fix(dte) ' date only
a(i, j + 2) = dte - a(i, j + 1)
a(i, j + 3) = Replace(Split(details(3), "-")(1), ")", "")
'Add details(0), i & ":" & j
j = j + 4 ' update postion for next item in this line transaction
Else
' thêm code ở đây
End If
Next itm
Next cll
End With
' gán mảng ở đây
End Sub
Dữ liệu xuất từ phần mềm với số ký tự từng thành phần theo đúng chuẩnCám ơn bác @VetMini. Thú thật đây là mã trạng thái của nhân viên giao hàng quét lên gồm:mã trạng thái, ngày quét và giờ quét. Mỗi dòng là trạng thái của một lô hàng, nên số lượng mã có thể thay đổi không cố định.
Bin gửi lại tệp có thêm một số chuỗi khác nữa phía sau.
Cám ơn.
Sub ABC()
Dim sArr(), res$(), vc27$, vc30$, vc$, sRow&, tmp$, N&, i&, j&, c&
vc27 = "VCSC[27]": vc30 = "VCSC[30]"
With Sheets("Sheet1")
sArr = .Range("A3", .Range("A" & Rows.Count).End(xlUp)).Value
End With
sRow = UBound(sArr)
ReDim res(1 To sRow, 1 To 10)
For i = 1 To sRow
tmp = sArr(i, 1)
N = Len(tmp)
c = 5
For j = 1 To N Step 36
vc = Mid(tmp, j, 8)
If Mid(tmp, j, 8) = vc27 Then
res(i, 1) = vc
res(i, 2) = Mid(tmp, j + 9, 5)
res(i, 3) = Mid(tmp, j + 15, 5)
res(i, 4) = Mid(tmp, j + 30, 4)
End If
If Mid(tmp, j, 8) = vc30 Then
res(i, c) = vc30
res(i, c + 1) = Mid(tmp, j + 9, 5)
res(i, c + 2) = Mid(tmp, j + 15, 5)
If c = 5 Then c = 8
End If
Next j
Next i
Sheets("Sheet1").Range("C3").Resize(sRow, 10) = res
End Sub
Cám ơn bác @befaint đã quan tâm. Tệp xuất từ phần mềm ra chỉ giống như cột A2. Do số lượng nhiều Bin chỉ lấy đại diện một vài mẫu để thực hành.
Mong nhận được hỗ trợ.
Xin cảm ơn bác @VetMini đã luôn quan tâm và giúp đỡCode thực hiện. Bài này thuật toán chỉ thường thoi, nhưng dữ liệu tùm lùm code rắc rối bỏ bố.
Tôi chỉ chú trọng dữ liệu, không có hứng về mẫu mã. Bạn tự tạo mẫu mã lấy.
Mã:Sub totite() Const COTDULIEU = "A" Const DONGBATDAU = 3 Dim a(1 To 100, 1 To 50) ' hope that the delivery note has less than 100 items, and less than 50 cycles For Each cll In Range(COTDULIEU & DONGBATDAU, COTDULIEU & Range(COTDULIEU & ":" & COTDULIEU).Find("*", searchorder:=xlByRows, searchdirection:=xlPrevious).Row) i = i + 1 ' prepare next line transaction j = 1 ' reset column for next line transaction For Each itm In Split(Application.Trim(Replace(Replace(Replace(cll.Value, Chr(13), "^"), Chr(13), "^"), "^^", "^")), "^") ' horrible! If itm <> "" Then details = Split(Application.Trim(Replace(itm, "@", " ")), " ") ' always 0:partID, 1,2: date, 4: whatever) dte = CDate(details(1) & " " & details(2)) ' gets date time itmCol = Application.Match(details(0), Application.Index(a, i, 0), 0) If Not IsNumeric(itmCol) Then ' item already there ' new item within transaction itmCol = j a(i, itmCol) = details(0) j = j + 4 ' update postion for next item in this line transaction End If If dte > a(i, itmCol + 1) + a(i, itmCol + 2) Then a(i, itmCol + 1) = Fix(dte) ' date only a(i, itmCol + 2) = dte - a(i, j + 1) a(i, itmCol + 3) = Replace(Split(details(3), "-")(1), ")", "") End If End If Next itm Next cll Range(COTDULIEU & DONGBATDAU).Offset(, 1).Resize(i, j).Value = a End Sub
Trước đó, tôi viết code sau, sử dụng dictionary, nhưng viết nửa chừng thì nhớ ra máy mình không có script engine của Windows, và bỏ dở. Tôi chuyển viết code như trên, dùng hàm macth để dò mảng.
Code này đang viết dở, nếu bạn có hứng thì cứ tiếp nó.
Mã:Sub totite2() Const COTDULIEU = "A" Const DONGBATDAU = 3 Const ROWMAX = 100 Const COLMAX = 50 Dim a(1 To ROWMAX, 1 To COLMAX) ' hope that the delivery note has less than 100 items, and less than 50 cycles With CreateObject("Scripting.Dictionary") For Each cll In Range(COTDULIEU & DONGBATDAU).CurrentRegion.Resize(, 1) ' resized to ensure that only one column is involved ' hình như ô A2 cũng có chứa gì đó, currentregion chép cả nó. Cần chỉnh i = i + 1 ' prepare next line transaction j = 1 ' reset column for next line transaction For Each itm In Split(Replace(Replace(Replace(cll.Value, Chr(13), "^"), Chr(13), "^"), "^^", "^"), "^") ' horrible! details = Application.Trim(Split(Replace(itm, "@", " "), " ")) ' always 0:partID, 1,2: date, 4: whatever) dte = CDate(details(1) & " " & details(2)) ' gets date time If Not .Exists(details(0)) Then a(i, j) = details(0) a(i, j + 1) = Fix(dte) ' date only a(i, j + 2) = dte - a(i, j + 1) a(i, j + 3) = Replace(Split(details(3), "-")(1), ")", "") 'Add details(0), i & ":" & j j = j + 4 ' update postion for next item in this line transaction Else ' thêm code ở đây End If Next itm Next cll End With ' gán mảng ở đây End Sub
Cám ơn bác @HieuCD đã giúp đỡ.Dữ liệu xuất từ phần mềm với số ký tự từng thành phần theo đúng chuẩn
Mã:Sub ABC() Dim sArr(), res$(), vc27$, vc30$, vc$, sRow&, tmp$, N&, i&, j&, c& vc27 = "VCSC[27]": vc30 = "VCSC[30]" With Sheets("Sheet1") sArr = .Range("A3", .Range("A" & Rows.Count).End(xlUp)).Value End With sRow = UBound(sArr) ReDim res(1 To sRow, 1 To 10) For i = 1 To sRow tmp = sArr(i, 1) N = Len(tmp) c = 5 For j = 1 To N Step 36 vc = Mid(tmp, j, 8) If Mid(tmp, j, 8) = vc27 Then res(i, 1) = vc res(i, 2) = Mid(tmp, j + 9, 5) res(i, 3) = Mid(tmp, j + 15, 5) res(i, 4) = Mid(tmp, j + 30, 4) End If If Mid(tmp, j, 8) = vc30 Then res(i, c) = vc30 res(i, c + 1) = Mid(tmp, j + 9, 5) res(i, c + 2) = Mid(tmp, j + 15, 5) If c = 5 Then c = 8 End If Next j Next i Sheets("Sheet1").Range("C3").Resize(sRow, 10) = res End Sub
1) Mình muốn tìm thêm một số mã khác thì thêm ở đây đúng không ah? vc27 = "VCSC[27]": vc30 = "VCSC[30]": Đúng rùi nhưng phải viết thêm lệnh để lấy thêm mã mớiCám ơn bác @HieuCD đã giúp đỡ.
Tuy nhiên Bin có vài chỗ chưa rõ mong bác giải thích giúp.
1) Mình muốn tìm thêm một số mã khác thì thêm ở đây đúng không ah?
vc27 = "VCSC[27]": vc30 = "VCSC[30]" <= Thêm mã cần tìm ở đây
2) Số 10 ở đây có phải là số cột không? Nếu thêm 1 mã và có thêm 2 cột kết quả nữa thì có phải chỉnh số 10 thành số 12 phải không?
ReDim res(1 To sRow, 1 To 10)
3) ý nghĩa của c=5/ c=8 này là gì?
For i = 1 To sRow
tmp = sArr(i, 1)
N = Len(tmp)
c = 5
...
If c = 5 Then c = 8
4) To N Step 36 này ý nghĩa là gì? Có phải là 36 lần lặp lại không?
For j = 1 To N Step 36
5) Làm cách nào để mình có thể tìm ra được quy luật này? Ý nghĩa của đoạn mã này? Tại sao chỉ cần đến res(i,4)=...là đủ
res(i, 1) = vc
res(i, 2) = Mid(tmp, j + 9, 5)
res(i, 3) = Mid(tmp, j + 15, 5)
res(i, 4) = Mid(tmp, j + 30, 4)
Biết là sẽ làm phiền nhưng do muốn học hỏi thêm. Mong bác dành chút thời gian chỉ điểm giúp.
Nếu bác có số điện thoại cho Bin xin nha. Bin có nhiều cái cũng muốn trao đổi riêng.
Cám ơn và chúc sức khỏe.
Cám ơn bác @HieuCD rất nhiều.1) Mình muốn tìm thêm một số mã khác thì thêm ở đây đúng không ah? vc27 = "VCSC[27]": vc30 = "VCSC[30]": Đúng rùi nhưng phải viết thêm lệnh để lấy thêm mã mới
2) Số 10 ở đây có phải là số cột không? Nếu thêm 1 mã và có thêm 2 cột kết quả nữa thì có phải chỉnh số 10 thành số 12 phải không? ReDim res(1 To sRow, 1 To 10: Chính xác 100%
3) ý nghĩa của c=5/ c=8 này là gì? C là thứ tự cột kết quả của mã VCSC[30], cột 5 là "dòng" đầu tiên cột 8 là "dòng" cuối của mã VCSC[30]. Nếu thêm mã mới phải xác định cột kết quả mới
4) To N Step 36 này ý nghĩa là gì? Có phải là 36 lần lặp lại không?: 36 là số ký tự của 1 mã, step 36 là mỗi bước nhảy 36 ký tự là 1 mã
5) Làm cách nào để mình có thể tìm ra được quy luật này? Ý nghĩa của đoạn mã này? Tại sao chỉ cần đến res(i,4)=...là đủ
res(i, 1) = vc
res(i, 2) = Mid(tmp, j + 9, 5)
res(i, 3) = Mid(tmp, j + 15, 5)
res(i, 4) = Mid(tmp, j + 30, 4)
Phải đếm thủ công các con số 9, 5, 15, 5 ....
Là kết quả của VCSC[27] nên chỉ có 4 cột
VCSC[30] lấy đầu và cuối nên có biến C xác định cột kết quả, còn lại chỉ lấy 1 nên nhập trực tiếp thứ tự cộtCám ơn bác @HieuCD rất nhiều.
Em vẫn có một thắc mắc là, giá trị VCSC[30] thay đổi vị trí, số lượng thì đoạn mã nào bác làm công việc này. Bin xem nhiều lần vẫn còn có thắc mắc này.
Và Bin có thêm thử một giá trị nữa VCSC[26] vào cột 11 và có viết lại code nhưng chạy không được, bác xem hộ Bin chỗ nào bị sai giúp với.
View attachment 273338
=========================================================
Sub ABC2()
Dim sArr(), res$(), vc27$, vc30$, vc26$, vc$, sRow&, tmp$, N&, i&, j&, c&
vc27 = "VCSC[27]": vc30 = "VCSC[30]": vc26 = "VCSC[26]"
With Sheets("Sheet1")
sArr = .Range("A3", .Range("A" & Rows.Count).End(xlUp)).Value
End With
sRow = UBound(sArr)
ReDim res(1 To sRow, 1 To 14)
For i = 1 To sRow
tmp = sArr(i, 1)
N = Len(tmp)
c = 5
c = 11
For j = 1 To N Step 36
vc = Mid(tmp, j, 8)
If Mid(tmp, j, 8) = vc27 Then
res(i, 1) = vc
res(i, 2) = Mid(tmp, j + 9, 5)
res(i, 3) = Mid(tmp, j + 15, 5)
res(i, 4) = Mid(tmp, j + 30, 4)
ElseIf Mid(tmp, j, 8) = vc30 Then
res(i, c) = vc30
res(i, c + 1) = Mid(tmp, j + 9, 5)
res(i, c + 2) = Mid(tmp, j + 15, 5)
If c = 5 Then c = 8
If Mid(tmp, j, 8) = vc26 Then
res(i, c) = vc
res(i, 2) = Mid(tmp, j + 9, 5)
res(i, 3) = Mid(tmp, j + 15, 5)
res(i, 4) = Mid(tmp, j + 30, 4)
If c = 11 Then
End If
Next j
Next i
Sheets("Sheet1").Range("C3").Resize(sRow, 14) = res
End Sub
=========================================================
Sub ABC2()
Dim sArr(), res$(), vc27$, vc30$, vc26$, vc$, sRow&, tmp$, N&, i&, j&, c&
vc27 = "VCSC[27]": vc30 = "VCSC[30]": vc26 = "VCSC[26]"
With Sheet1
sArr = .Range("A3", .Range("A" & Rows.Count).End(xlUp)).Value
End With
sRow = UBound(sArr)
ReDim res(1 To sRow, 1 To 14)
For i = 1 To sRow
tmp = sArr(i, 1)
N = Len(tmp)
c = 5
For j = 1 To N Step 36
vc = Mid(tmp, j, 8)
If Mid(tmp, j, 8) = vc27 Then
res(i, 1) = vc
res(i, 2) = Mid(tmp, j + 9, 5)
res(i, 3) = Mid(tmp, j + 15, 5)
res(i, 4) = Mid(tmp, j + 30, 4)
ElseIf Mid(tmp, j, 8) = vc30 Then
res(i, c) = vc30
res(i, c + 1) = Mid(tmp, j + 9, 5)
res(i, c + 2) = Mid(tmp, j + 15, 5)
If c = 5 Then c = 8
ElseIf Mid(tmp, j, 8) = vc26 Then
res(i, 11) = vc
res(i, 12) = Mid(tmp, j + 9, 5)
res(i, 13) = Mid(tmp, j + 15, 5)
res(i, 14) = Mid(tmp, j + 30, 4)
End If
Next j
Next i
Sheet1.Range("C3").Resize(sRow, 14) = res
End Sub
Nếu bạn đóng chủ đề lại, có ai đó vào sau cần tham khảo và trao đổi thêm thì biết làm thế nào nhỉ.em xin phép đóng chủ đề hỏi này ở đây.
Dạ không, ý là ngưng hỏi ở phía Bin thôi ah. Không biết mình hay dùng từ gì để không bị hiểu nhầm là xóa/đóng luôn ah.Nếu bạn đóng chủ đề lại, có ai đó vào sau cần tham khảo và trao đổi thêm thì biết làm thế nào nhỉ.
Lần sau cứ cảm ơn những thành viên đã giúp bạn là tốt rồi, đừng đóng chủ đề lại nữa nhé.Dạ không, ý là ngưng hỏi ở phía Bin thôi ah. Không biết mình hay dùng từ gì để không bị hiểu nhầm là xóa/đóng luôn ah.
Chỉnh lại . . .Gửi bác @HieuCD, sau khi sử dụng Bin thấy là đối với dữ liệu có nhiều dòng, thì kết quả đang ưu tiên lấy kết quả cuối cùng nên có vài mã lại cần giá trị đầu tiên trong chuỗi. Vậy nên làm phiền bác có thể giúp Bin chỉnh lại được không?
Trong tệp mình sẽ bỏ đi c=5 và c=8, mình sẽ đặt giá trị đầu và giá trị sau tùy cột và theo nhu cầu cho các mã khác.
Cám ơn và làm phiền bác nhiều.
Sub ABC()
Dim sArr(), res$(), vc27$, vc30$, vc79$, vc$, sRow&, tmp$, N&, i&, j&
vc27 = "VCSC[27]": vc30 = "VCSC[30]": vc79 = "VCSC[79]"
With Sheets("HieuCD")
sArr = .Range("A3", .Range("A" & Rows.Count).End(xlUp)).Value
End With
sRow = UBound(sArr)
ReDim res(1 To sRow, 1 To 10)
For i = 1 To sRow
tmp = sArr(i, 1)
N = Len(tmp)
For j = 1 To N Step 36
vc = Mid(tmp, j, 8)
If vc = vc27 Then
If res(i, 1) = Empty Then
res(i, 1) = vc
res(i, 2) = Mid(tmp, j + 9, 5)
res(i, 3) = Mid(tmp, j + 15, 5)
res(i, 4) = Mid(tmp, j + 30, 4)
End If
ElseIf vc = vc30 Then
If res(i, 5) = Empty Then
res(i, 5) = vc
res(i, 6) = Mid(tmp, j + 9, 5)
res(i, 7) = Mid(tmp, j + 15, 5)
End If
ElseIf vc = vc79 Then
res(i, 8) = vc
res(i, 9) = Mid(tmp, j + 9, 5)
res(i, 10) = Mid(tmp, j + 15, 5)
End If
Next j
Next i
Sheets("HieuCD").Range("C3").Resize(sRow, 10) = res
End Sub
Tuyệt vời. Cám ơn bác @HieuCD đã hỗ trợ rất nhiều.Chỉnh lại . . .
Mã:Sub ABC() Dim sArr(), res$(), vc27$, vc30$, vc79$, vc$, sRow&, tmp$, N&, i&, j& vc27 = "VCSC[27]": vc30 = "VCSC[30]": vc79 = "VCSC[79]" With Sheets("HieuCD") sArr = .Range("A3", .Range("A" & Rows.Count).End(xlUp)).Value End With sRow = UBound(sArr) ReDim res(1 To sRow, 1 To 10) For i = 1 To sRow tmp = sArr(i, 1) N = Len(tmp) For j = 1 To N Step 36 vc = Mid(tmp, j, 8) If vc = vc27 Then If res(i, 1) = Empty Then res(i, 1) = vc res(i, 2) = Mid(tmp, j + 9, 5) res(i, 3) = Mid(tmp, j + 15, 5) res(i, 4) = Mid(tmp, j + 30, 4) End If ElseIf vc = vc30 Then If res(i, 5) = Empty Then res(i, 5) = vc res(i, 6) = Mid(tmp, j + 9, 5) res(i, 7) = Mid(tmp, j + 15, 5) End If ElseIf vc = vc79 Then res(i, 8) = vc res(i, 9) = Mid(tmp, j + 9, 5) res(i, 10) = Mid(tmp, j + 15, 5) End If Next j Next i Sheets("HieuCD").Range("C3").Resize(sRow, 10) = res End Sub