huonglien1901
GPE là ngôi nhà thứ 2 của tôi!!!
- Tham gia
- 17/4/16
- Bài viết
- 2,702
- Được thích
- 2,434
- Giới tính
- Nam
- Nghề nghiệp
- Nhân viên kỹ thuật in ấn
Muốn tách ít ra phải có một quy luật nào chứ kiểu này kêu tôi mò và lựa bằng mắt bình thường cũng không biết đâu mà tách.Chào mọi người!
Em có vấn đề nhờ mọi người hỗ trợ.
Em muốn tách chuỗi lấy tên Nhà cung cấp.
Em cảm ơn mọi người nhiều!
Quy luật tách là:Muốn tách ít ra phải có một quy luật nào chứ kiểu này kêu tôi mò và lựa bằng mắt bình thường cũng không biết đâu mà tách.
Bạn xem FileChào mọi người!
Em có vấn đề nhờ mọi người hỗ trợ.
Em muốn tách chuỗi lấy tên Nhà cung cấp.
Em cảm ơn mọi người nhiều!
Làm sao biết được tên sản phẩm đến đâu sẽ hết mà lấy. Còn nếu tên nhà cung cấp ở giữa làm sao biết tên có mấy từ mà tách. Nói chung khó hình dung và biết được tên như thế nào, hoặc ít nhất cũng phải có danh sách như #4.Quy luật tách là:
TH1: ở sau tên sản phẩm đó là tên nhà cung cấp đó Anh.
Th2: Tên nhà cung cấp nằm giữa tên sản phẩm và dung tich của nó.
tên sản phẩm bắt đầu sau dòng Tillcode(dòng này gồm có 12, 13 số )Làm sao biết được tên sản phẩm đến đâu sẽ hết mà lấy. Còn nếu tên nhà cung cấp ở giữa làm sao biết tên có mấy từ mà tách. Nói chung khó hình dung và biết được tên như thế nào, hoặc ít nhất cũng phải có danh sách như #4.
Thật tình tôi chưa tìm ra được quy luật để viết hàm hay code, mà #4 đã đáp ứng được yêu cầu của bạn chưa? Nếu chưa thì đợi thành viên khác hiểu mà giúp cho bạn nhé.tên sản phẩm bắt đầu sau dòng Tillcode(dòng này gồm có 12, 13 số )
Tên sản phẩm sẽ kéo dài chỗ dung tích của sản phẩm,
Tillcode/tên sản phẩm(có dung tich sản phẩm)/tên nhà cung cấp.
Nhờ Anh hỗ trợ giúp em.
Hình như là vầy thì phảiThật tình tôi chưa tìm ra được quy luật để viết hàm hay code, mà #4 đã đáp ứng được yêu cầu của bạn chưa? Nếu chưa thì đợi thành viên khác hiểu mà giúp cho bạn nhé.
Giải thích sao vòng vo tam quốc quá đi, anh chừa thêm 2 dòng để còn sử dụng cho nội dung và tiêu đề (có khi cần đến).tên sản phẩm bắt đầu sau dòng Tillcode(dòng này gồm có 12, 13 số )
Tên sản phẩm sẽ kéo dài chỗ dung tích của sản phẩm,
Tillcode/tên sản phẩm(có dung tich sản phẩm)/tên nhà cung cấp.
Nhờ Anh hỗ trợ giúp em.
Có thể còn sót một số dòngChào mọi người!
Em có vấn đề nhờ mọi người hỗ trợ.
Em muốn tách chuỗi lấy tên Nhà cung cấp.
Em cảm ơn mọi người nhiều!
Sub Tach_NB()
Dim sArr(), Res(), S As Variant, dArr As Variant, Dic As Object
Dim i As Long, j As Long, sR As Long, n As Long
Dim tmp As String
sArr = Range("A1", Range("A65500").End(xlUp)).Value
ReDim Res(1 To UBound(sArr), 1 To 1)
Set Dic = CreateObject("scripting.dictionary")
For i = 1 To UBound(sArr)
S = Split(Application.Trim(sArr(i, 1)), " ")
sR = UBound(S)
For j = 1 To sR
If isNum(S(j)) And j < sR Then
tmp = ""
For n = j + 1 To sR
If Not isNum(S(n)) Then tmp = tmp & " " & S(n) Else Exit For
Next n
If Len(tmp) Then
tmp = Mid(tmp, 2, Len(tmp) - 1)
If Not Dic.exists(tmp) Then Dic.Add (tmp), ""
Res(i, 1) = tmp
End If
Exit For
End If
Next j
Next i
dArr = Dic.keys
For i = 1 To UBound(sArr)
If Res(i, 1) = "" Then
tmp = Application.Trim(sArr(i, 1))
For j = 0 To UBound(dArr)
If InStr(tmp, dArr(j)) Then Res(i, 1) = dArr(j): Exit For
Next j
End If
Next i
Range("B1").Resize(UBound(sArr)) = Res
End Sub
Private Function isNum(ByVal tmp As String) As Boolean
Dim i As Byte
Const So = "(0123456789"
For i = 1 To Len(tmp)
If InStr(So, Mid(tmp, i, 1)) Then isNum = True: Exit Function
Next i
End Function
Ái dà, phức tạp ghê, bác HieuCD ơi!Có thể còn sót một số dòng
Mã:Sub Tach_NB() Dim sArr(), Res(), S As Variant, dArr As Variant, Dic As Object Dim i As Long, j As Long, sR As Long, n As Long Dim tmp As String sArr = Range("A1", Range("A65500").End(xlUp)).Value ReDim Res(1 To UBound(sArr), 1 To 1) Set Dic = CreateObject("scripting.dictionary") For i = 1 To UBound(sArr) S = Split(Application.Trim(sArr(i, 1)), " ") sR = UBound(S) For j = 1 To sR If isNum(S(j)) And j < sR Then tmp = "" For n = j + 1 To sR If Not isNum(S(n)) Then tmp = tmp & " " & S(n) Else Exit For Next n If Len(tmp) Then tmp = Mid(tmp, 2, Len(tmp) - 1) If Not Dic.exists(tmp) Then Dic.Add (tmp), "" Res(i, 1) = tmp End If Exit For End If Next j Next i dArr = Dic.keys For i = 1 To UBound(sArr) If Res(i, 1) = "" Then tmp = Application.Trim(sArr(i, 1)) For j = 0 To UBound(dArr) If InStr(tmp, dArr(j)) Then Res(i, 1) = dArr(j): Exit For Next j End If Next i Range("B1").Resize(UBound(sArr)) = Res End Sub Private Function isNum(ByVal tmp As String) As Boolean Dim i As Byte Const So = "(0123456789" For i = 1 To Len(tmp) If InStr(So, Mid(tmp, i, 1)) Then isNum = True: Exit Function Next i End Function
Do dữ liệu lung tung, code phải nhảy tưng tưng theoÁi dà, phức tạp ghê, bác HieuCD ơi!
Nếu có danh mục nhà cung cấp thì tra cũng không dễ dàng gì đâu. Chủ yêu là do lúc nhập liệu không chuẩn: Lúc có dấu chấm, lúc có dấu phẩy, lúc thì liền, lúc có 1 khoảng trắng, lúc có 2 khoảng trắng.Do dữ liệu lung tung, code phải nhảy tưng tưng theo
Nếu có danh sách nhà cung cấp thì dùng công thức hay code đều dể![]()
Góp thêm cách dùng code:Chào mọi người!
Em có vấn đề nhờ mọi người hỗ trợ.
Em muốn tách chuỗi lấy tên Nhà cung cấp.
Em cảm ơn mọi người nhiều!
Function tach(rng As Range)
Dim cell As Range
With CreateObject("vbscript.regexp")
.Pattern = "^.*[\d\.]+(ml|l|g|mg)([^\d\(]+).*$": .ignorecase = True ''[\d\.]+?
If .test(rng) Then
tach = .Replace(rng, "$2")
Else
For Each cell In Range(Cells(1, ActiveCell.Column), Cells(rng.Row - 1, ActiveCell.Column))
If InStr(1, rng, cell) Then tach = cell: Exit Function
Next
End If
End With
End Function
Tôi rất ngưỡng mộ bạn với thể loại vbscript.regexp, với cách đặt điều kiện .PatternGóp thêm cách dùng code:
PHP:Function tach(rng As Range) Dim cell As Range With CreateObject("vbscript.regexp") .Pattern = "^.*[\d\.]+(ml|l|g|mg)([^\d\(]+).*$": .ignorecase = True ''[\d\.]+? If .test(rng) Then tach = .Replace(rng, "$2") Else For Each cell In Range(Cells(1, ActiveCell.Column), Cells(rng.Row - 1, ActiveCell.Column)) If InStr(1, rng, cell) Then tach = cell: Exit Function Next End If End With End Function
Regex (VBA) và công thức mảng (WS) dựa vào một vài khái niệm căn bản và từ đó suy ra nhiều thiên biến vạn hoá, rất thích hợp cho những người có sử thích thử thách toán học.Tôi rất ngưỡng mộ bạn với thể loại vbscript.regexp, với cách đặt điều kiện .Pattern
Trước đây tôi thấy có bạn doatmenhhon rất giỏi món này.
Dùng vbscript.regexp quá đỉnh, nhìn code không biết gì luônGóp thêm cách dùng code:
PHP:Function tach(rng As Range) Dim cell As Range With CreateObject("vbscript.regexp") .Pattern = "^.*[\d\.]+(ml|l|g|mg)([^\d\(]+).*$": .ignorecase = True ''[\d\.]+? If .test(rng) Then tach = .Replace(rng, "$2") Else For Each cell In Range(Cells(1, ActiveCell.Column), Cells(rng.Row - 1, ActiveCell.Column)) If InStr(1, rng, cell) Then tach = cell: Exit Function Next End If End With End Function
Tôi viết lại:Dùng vbscript.regexp quá đỉnh, nhìn code không biết gì luôn
Còn 1 khả năng bạn xử luôn cho đẹp![]()
Sub tach()
Dim cell As Range, cell1 As Range, rng As Range, arr, result, darr
arr = Range([a1], Cells(Rows.Count, 1).End(xlUp))
ReDim result(1 To UBound(arr), 1 To 1)
With CreateObject("vbscript.regexp")
.Pattern = "^.*[\d\.]+(ml|l|g|mg)([^\d\(]+).*$": .ignorecase = True
For i = 1 To UBound(arr)
If .test(arr(i, 1)) Then result(i, 1) = .Replace(arr(i, 1), "$2")
Next
[B1].Resize(UBound(result), 1) = result
Set rng = Range([B1], Cells(Rows.Count, 1).End(xlUp).Offset(, 1))
For Each cell In rng
If cell = "" Then
For Each cell1 In rng
If cell1 <> "" And InStr(1, cell.End(xlToLeft), cell1) Then cell = cell1: Exit For
Next
End If
Next
End With
End Sub
Cho em muốn hỏi anh là có thể tạo 1 Function Tổng quát dùng vớiDùng vbscript.regexp quá đỉnh, nhìn code không biết gì luôn
Còn 1 khả năng bạn xử luôn cho đẹp![]()
Bạn hỏi nhầm người rồi, vbscript.regexp có các tham số quá nhức đầu nên mình không bao giờ đụng tớiCho em muốn hỏi anh là có thể tạo 1 Function Tổng quát dùng với
vbscript.regexp
Để lấy được những dữ liệu theo ý muốn Dạng kiểu Hàm lấy ký tự sau những kí tự đặc biệt như #, ? , * đại diện cho 1 hay nhiều kí tự: Ví dụ như Hàng hóa theo số #45786 của ngày 01/2017 > kết quả muốn lấy là 45786 hay kết quả ra là 01/2017 ....Giống kiểu crtl+h của excel kèm theo excel được không anh !
@excel_lv1.5 có thể hướng dẫn cách em tạo ra function dạng này được không ạ ! Em cảm ơn anh ẠBạn hỏi nhầm người rồi, vbscript.regexp có các tham số quá nhức đầu nên mình không bao giờ đụng tới
Bạn nên nhờ @excel_lv1.5 là chuyên gia về regexp
Không biết làm được không nhưng bạn đưa file ví dụ lên đi bạn , tất cả trường hợp tổng quát luôn nhe!!@excel_lv1.5 có thể hướng dẫn cách em tạo ra function dạng này được không ạ ! Em cảm ơn anh Ạ
Em gửi anh 1 số trường hợp tổng quát như thế này và kết quả mong muốn ! Mong sự giúp đỡ của anh !Không biết làm được không nhưng bạn đưa file ví dụ lên đi bạn , tất cả trường hợp tổng quát luôn nhe!!
Bạn dùng code này thử xem:Em gửi anh 1 số trường hợp tổng quát như thế này và kết quả mong muốn ! Mong sự giúp đỡ của anh !
Trong chỗ này thêm cả chuỗi ký tự : Ngày 01/01/2017; 01/02/2017 hạch toán nhà hàng nguyễn văn A: Chuỗi cần kết quả chính xác là 01/01/2017; 01/02/2017
Function tach(str As String, n As Long)
With CreateObject("vbscript.regexp")
.Pattern = "([^\#\&\\\s]+)[\#\&\\]+([^\#\&\\\s]+).*,(.*)"
If .test(str) Then
Select Case n
Case 1
tach = .Execute(str)(0).submatches(1)
Case 2
tach = .Execute(str)(0).submatches(0)
Case 3
tach = .Execute(str)(0).submatches(2)
End Select
Else
.Pattern = "\b(\d[\d\s\,]+)\b\D+\b((\d{1,2}/)?\d{1,2}\/\d{4})\b"
Select Case n
Case 1
tach = .Execute(str)(0).submatches(0)
Case 2
tach = .Execute(str)(0).submatches(1)
End Select
End If
End With
End Function
Dạ vâng em cảm ơn anh ạ ! Hàm này có thể làm thành kiểu Tach(A1,"&") ra kết quả như trường hợp 1 hay đối với trường hợp giữa 2 kí tự đặc biệt .. được không Anh giống kiểu Ctrl + H ạ. Ngoài ra em muốn hỏi anh cách thức phân tích 1 chuỗi dạng này để em có thể vận dụng ở các bài sau ạ. EM cảm ơn anh ạ !Bạn dùng code này thử xem:
PHP:Function tach(str As String, n As Long) With CreateObject("vbscript.regexp") .Pattern = "([^\#\&\\\s]+)[\#\&\\]+([^\#\&\\\s]+).*,(.*)" If .test(str) Then Select Case n Case 1 tach = .Execute(str)(0).submatches(1) Case 2 tach = .Execute(str)(0).submatches(0) Case 3 tach = .Execute(str)(0).submatches(2) End Select Else .Pattern = "\b(\d[\d\s\,]+)\b\D+\b((\d{1,2}/)?\d{1,2}\/\d{4})\b" Select Case n Case 1 tach = .Execute(str)(0).submatches(0) Case 2 tach = .Execute(str)(0).submatches(1) End Select End If End With End Function
Bạn sữa code lại như vầy :Dạ vâng em cảm ơn anh ạ ! Hàm này có thể làm thành kiểu Tach(A1,"&") ra kết quả như trường hợp 1 hay đối với trường hợp giữa 2 kí tự đặc biệt .. được không Anh giống kiểu Ctrl + H ạ. Ngoài ra em muốn hỏi anh cách thức phân tích 1 chuỗi dạng này để em có thể vận dụng ở các bài sau ạ. EM cảm ơn anh ạ !
Function tach(str As String, n As Long, Optional demi As String = "")
With CreateObject("vbscript.regexp")
.Pattern = "([^" & demi & "\s]+)[" & demi & "]+([^" & demi & "\s]+).*,(.*)"
If .test(str) Then
Select Case n
Case 1
tach = .Execute(str)(0).submatches(1)
Case 2
tach = .Execute(str)(0).submatches(0)
Case 3
tach = .Execute(str)(0).submatches(2)
End Select
Else
.Pattern = "\b(\d[\d\s\,]+)\b\D+\b((\d{1,2}/)?\d{1,2}\/\d{4})\b"
Select Case n
Case 1
tach = .Execute(str)(0).submatches(0)
Case 2
tach = .Execute(str)(0).submatches(1)
End Select
End If
End With
End Function
Em thử với chuỗi "Nguyễn văn A #AFF-UV Hơn" thì ra được kết quả là Value anh ạ. Ngoài ra cái chuỗi này em muốn dạng * đại điện cho 1 chuỗi kí tự và ? đại diện 1 ký tự anh ạBạn sữa code lại như vầy :
Công thức là: =tach($A3,COLUMN(A1),"&#|")PHP:Function tach(str As String, n As Long, Optional demi As String = "") With CreateObject("vbscript.regexp") .Pattern = "([^" & demi & "\s]+)[" & demi & "]+([^" & demi & "\s]+).*,(.*)" If .test(str) Then Select Case n Case 1 tach = .Execute(str)(0).submatches(1) Case 2 tach = .Execute(str)(0).submatches(0) Case 3 tach = .Execute(str)(0).submatches(2) End Select Else .Pattern = "\b(\d[\d\s\,]+)\b\D+\b((\d{1,2}/)?\d{1,2}\/\d{4})\b" Select Case n Case 1 tach = .Execute(str)(0).submatches(0) Case 2 tach = .Execute(str)(0).submatches(1) End Select End If End With End Function
Các dấu khác thì bình thường riêng dấu "\" thì bạn phải gõ là "\\"
.Bạn sữa code lại như vầy :
Công thức là: =tach($A3,COLUMN(A1),"&#|")PHP:Function tach(str As String, n As Long, Optional demi As String = "") With CreateObject("vbscript.regexp") .Pattern = "([^" & demi & "\s]+)[" & demi & "]+([^" & demi & "\s]+).*,(.*)" If .test(str) Then Select Case n Case 1 tach = .Execute(str)(0).submatches(1) Case 2 tach = .Execute(str)(0).submatches(0) Case 3 tach = .Execute(str)(0).submatches(2) End Select Else .Pattern = "\b(\d[\d\s\,]+)\b\D+\b((\d{1,2}/)?\d{1,2}\/\d{4})\b" Select Case n Case 1 tach = .Execute(str)(0).submatches(0) Case 2 tach = .Execute(str)(0).submatches(1) End Select End If End With End Function
Các dấu khác thì bình thường riêng dấu "\" thì bạn phải gõ là "\\"
Trường hợp này của bạn dựa vào đâu vào lấy, nó không cùng chung quy luật với chuỗi trên sao?Em thử với chuỗi "Nguyễn văn A #AFF-UV Hơn" thì ra được kết quả là Value anh ạ. Ngoài ra cái chuỗi này em muốn dạng * đại điện cho 1 chuỗi kí tự và ? đại diện 1 ký tự anh ạ
Trường hợp này nó chỉ lấy sau dấu # không kèm trường hợp " " Hơn anh ạTrường hợp này của bạn dựa vào đâu vào lấy, nó không cùng chung quy luật với chuỗi trên sao?
Bạn chỉnh code như vầy:Trường hợp này nó chỉ lấy sau dấu # không kèm trường hợp " " Hơn anh ạ
Function tach(str As String, n As Long, Optional demi As String = "")
str = str & ","
With CreateObject("vbscript.regexp")
.Pattern = "([^" & demi & "\s]+)(\s*)[" & demi & "]+(\s*)([^" & demi & "\s]+)"
If .test(str) Then
Select Case n
Case 1
If Len(.Execute(str)(0).submatches(2)) = 0 Then tach = .Execute(str)(0).submatches(3)
Case 2
If Len(.Execute(str)(0).submatches(1)) = 0 Then tach = .Execute(str)(0).submatches(0)
Case 3
.Pattern = ".*,([^,]+)"
If .test(str) Then tach = .Execute(str)(0).submatches(0)
End Select
Else
.Pattern = "\b(\d[\d\s\,]+)\b\D+\b((\d{1,2}/)?\d{1,2}\/\d{4})\b"
If .test(str) Then
Select Case n
Case 1
tach = .Execute(str)(0).submatches(0)
Case 2
tach = .Execute(str)(0).submatches(1)
End Select
End If
End If
End With
End Function
Ngoài ra anh cho em hỏi với Cách thức để phân tích chuỗi này để các trường hợp sau em nghiên cứu và thực hiện với ! Mỗi lần dùng công thức này em lại phải xác định được chuỗi pattern nhưng chưa biết phân tách kiểu gì cho ổn cho nên ví vụ công thức này mà em muốn lấy số trong chuỗi thì em để ở ngoài là :LayTextDk(E6,"[^0-9]","",FALSE). Anh có thể giúp em phần này được không ạ !Bạn chỉnh code như vầy:
PHP:Function tach(str As String, n As Long, Optional demi As String = "") str = str & "," With CreateObject("vbscript.regexp") .Pattern = "([^" & demi & "\s]+)(\s*)[" & demi & "]+(\s*)([^" & demi & "\s]+)" If .test(str) Then Select Case n Case 1 If Len(.Execute(str)(0).submatches(2)) = 0 Then tach = .Execute(str)(0).submatches(3) Case 2 If Len(.Execute(str)(0).submatches(1)) = 0 Then tach = .Execute(str)(0).submatches(0) Case 3 .Pattern = ".*,([^,]+)" If .test(str) Then tach = .Execute(str)(0).submatches(0) End Select Else .Pattern = "\b(\d[\d\s\,]+)\b\D+\b((\d{1,2}/)?\d{1,2}\/\d{4})\b" If .test(str) Then Select Case n Case 1 tach = .Execute(str)(0).submatches(0) Case 2 tach = .Execute(str)(0).submatches(1) End Select End If End If End With End Function
Bạn đọc mấy bài này thử xem:Ngoài ra anh cho em hỏi với Cách thức để phân tích chuỗi này để các trường hợp sau em nghiên cứu và thực hiện với ! Mỗi lần dùng công thức này em lại phải xác định được chuỗi pattern nhưng chưa biết phân tách kiểu gì cho ổn cho nên ví vụ công thức này mà em muốn lấy số trong chuỗi thì em để ở ngoài là :LayTextDk(E6,"[^0-9]","",FALSE). Anh có thể giúp em phần này được không ạ !
Function LayTextDk(Chuoi As String, MaChuoi As String, CanThayThe, DieuKienTrueFalse As Boolean) As String
Dim objRegExp As Object
Set objRegExp = CreateObject("vbscript.regexp")
With objRegExp
.pattern = MaChuoi
.IgnoreCase = DieuKienTrueFalse
.Global = True
End With
LayTextDk = objRegExp.Replace(Chuoi, CanThayThe)
Set objRegExp = Nothing
End Function
Bạn đọc mấy bài này thử xem:
https://www.giaiphapexcel.com/diendan/threads/vbscript-regexp.76017/
https://www.giaiphapexcel.com/diendan/threads/thử-nghiệm-vbscript-regexp.69985/#post430042
Regex thì hơi khó hơn các object khác, thuộc tính thì nó có vài cái, tham số trong pattern cũng không nhiều , nhưng cái quan trọng là kết hợp các tham số để định dạng chuỗi, một chuỗi có nhiều cách viết pattern khác nhau. Cái này chắc không ai giúp được bạn đâu tùy vào khả năng bạn hiểu tới đâu thôi.
Thank anh ạ ! Để em nghiên cứu thêm ạBạn đọc mấy bài này thử xem:
https://www.giaiphapexcel.com/diendan/threads/vbscript-regexp.76017/
https://www.giaiphapexcel.com/diendan/threads/thử-nghiệm-vbscript-regexp.69985/#post430042
Regex thì hơi khó hơn các object khác, thuộc tính thì nó có vài cái, tham số trong pattern cũng không nhiều , nhưng cái quan trọng là kết hợp các tham số để định dạng chuỗi, một chuỗi có nhiều cách viết pattern khác nhau. Cái này chắc không ai giúp được bạn đâu tùy vào khả năng bạn hiểu tới đâu thôi.
bạn dùng công cụ Flash fill ấy, lên google để xem cách sử dụngChào mọi người!
Em có vấn đề nhờ mọi người hỗ trợ.
Em muốn tách chuỗi lấy tên Nhà cung cấp.
Em cảm ơn mọi người nhiều!