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