Cần hỗ trợ về tách các phần tử trong chuỗi

  • Thread starter Thread starter HDDP
  • Ngày gửi Ngày gửi
Liên hệ QC

HDDP

Thành viên chính thức
Tham gia
25/2/22
Bài viết
51
Được thích
27
Em chào các cô, chú, anh, chị trong diễn đàn.

Em có một chuỗi cần tách kí tự như file đính kèm: Từ cột A em cần tách ra 3 cột: màu/Size/Inseam tương ứng với cột B/C và D. Hiện tại em đang sử dụng hàm để tách nhưng nó quá nhiều cái không tối ưu như:
- Cột B tách màu: công thức khá là dài và mỗi khi có màu mới, em cũng cần thêm vào lại công thức nên rất bất tiện, nhờ anh chị rút gọn công thức hoặc hướng dẫn em phương pháp thuận lợi hơn.
- Cột C và D tách size và inseam: hai cột này hiện tại em sử dụng khá nhiều công thức để tách vì không có điểm chung giữa tất cả các nhóm. Nên em cần tìm các nhóm có điểm/quy luật chung để viết công thức ( ví dụ: Tall/Petite/In I/In Inwaist/In Inseam/ Right lấy kí tự cuối...). Nhờ anh chị giúp đỡ công thức nào để xử lý một lần luôn ah.

Kết quả mong muốn và công thức em sử dụng có trong file đính kèm, nhờ mọi người xem giúp, em cảm ơn.

P/s: Em đã tách bằng Flash Fill nhưng kết quả khá là lộn xộn nên em không tính phương án này.
 

File đính kèm

Thay vì kể nể cái đã làm thì mình nên trình bày thật chi tiết, cụ thể quy luật cần tách là gì.
Như em đề cập phía trên, hiện tại em không tìm thấy quy luật cần tách thống nhất cho tất cả các hàng trong file, nên em đã điền kết quả mong muốn và nhờ mọi người, anh giúp hộ em.
 
Không ai yêu cầu cái thống nhất đó. Nó rời rạc thì sao bắt nó dính với nhau được. Hãy mô tả toàn bộ, đầy đủ là được.
Em diễn tả chi tiết theo cột như bên dưới, anh xem giúp em:
- Cột B: tên màu: được viết hoa toàn bộ kí tự, là tên màu có ý nghĩa như BLACK/ARMY COT GREEN/BLUE NIGHTS....
một số lưu ý có ví dụ như: chuỗi Savanna Trails Pant - P BLACK 6 Petite => tên màu là BLACK, chứ không phải là P BLACK
chuỗi Act ASPHALT 42 IN Waist x 30 IN Inseam => Tên màu là ASPHALT, chứ không phải là ASPHALT IN IN

- Cột C: size có các nhóm size số và size chữ, size vừa số vừa chữ: nó nằm ở các nhóm:
* Trước chữ IN Waist/Petite/Tall
* Nằm cuối cùng bên phải
* Nhóm trong chuỗi có "Kids"
* Một số khác như chuỗi: Trailmade Pant CASTLEROCK 2 T -< size 2 T

- Cột D: Inseam: có các nhóm
* Tall/Petite/In I/In Inseam
 
- Cột B: tên màu: được viết hoa toàn bộ kí tự, là tên màu có ý nghĩa như BLACK/ARMY COT GREEN/BLUE NIGHTS....
một số lưu ý có ví dụ như: chuỗi Savanna Trails Pant - P BLACK 6 Petite => tên màu là BLACK, chứ không phải là P BLACK
chuỗi Act ASPHALT 42 IN Waist x 30 IN Inseam => Tên màu là ASPHALT, chứ không phải là ASPHALT IN IN

Phần màu bạn hãy liệt kê toàn bộ màu ra một cột.

- Cột C: size có các nhóm size số và size chữ, size vừa số vừa chữ: nó nằm ở các nhóm:
* Trước chữ IN Waist/Petite/Tall
* Nằm cuối cùng bên phải
* Nhóm trong chuỗi có "Kids"
* Một số khác như chuỗi: Trailmade Pant CASTLEROCK 2 T -< size 2 T

Giữa size là số và chữ cái khác nhau là gì? Tức là quy tắc lấy phần ký tự là size ra khỏi chuỗi như thế nào, bởi trong chuỗi có thể vừa có chữ số, vừa có ký tự size là chữ cái. Nếu có thể thì cũng liệt kê các size ra một cột luôn.

Bạn giải quyết được các thông tin điều kiện đầu vào thì cũng gần như giải quyết xong bài toán.
Đừng hấp tấp tìm cách giải, cứ nêu hết mọi dữ kiện ban đầu thì tự nhiên thấy đơn giản hơn rât nhiều.
 
Phần màu bạn hãy liệt kê toàn bộ màu ra một cột.
Em liệt kê ở cột G, anh xem nhé.
Giữa size là số và chữ cái khác nhau là gì? Tức là quy tắc lấy phần ký tự là size ra khỏi chuỗi như thế nào, bởi trong chuỗi có thể vừa có chữ số, vừa có ký tự size là chữ cái. Nếu có thể thì cũng liệt kê các size ra một cột luôn.
Bởi vì không có nguyên tắc lấy kí tự nên em đưa ra một số ví dụ bên dưới để rõ ràng hơn điểm này nhé:
- Chuỗi New Sahara Cargo S ASPHALT 34 IN Waist: chuỗi này quy tắc của nó là size 34 trước " IN Waist" chứ không phải là Size S.
- Chuỗi Sahara Amphib S BIO TEXTURE LARKSPUR L: size L, chứ không phải size S
- Chuỗi Sahara Guide ROCKWALL L x 32 IN Inseam : size L, (32 là Inseam lấy theo nguyên tắc IN Inseam)
- Chuỗi 650 Down Jacket 2.0 Plus INDIGO 2X : size 2X
Em liệt kê size ở cột H trong file ( đầy đủ các trường hợp size), và inseam ở cột I luôn.
 

File đính kèm

Vì các danh sách màu-size-inseam của bạn có cập nhật nên phải lưu danh sách ra sheet riêng để phục vụ việc tìm kiếm
Mình để danh sách trong sheet "List"
Vì có sự trùng lắp ký tự trong cùng nhóm, VD: XL và L là 2 size khác nhau. Do đó trong sheet List mình sắp xếp theo thứ tự giảm dần theo số ký tự. VD:
XL
L
Và 1 số trường hợp đặc biệt khác như ưu tiên L xếp trước 10

Nhấn vào nút RUN để thực hiện việc tách. Phía bên phải là cột so sánh với kết quả của bạn.

PHP:
Option Explicit
Sub Tach()
Dim i&, j&, m&, k&, lr&, lrC&, lrS&, lrI&, pos1&, pos2&, arr()
Dim Colo, Size, Inseam, rng, str
With Worksheets("List")
    lrC = .Cells(Rows.Count, "A").End(xlUp).Row
    lrS = .Cells(Rows.Count, "B").End(xlUp).Row
    lrI = .Cells(Rows.Count, "C").End(xlUp).Row
    Colo = .Range("A2:A" & lrC).Value
    Size = .Range("B2:B" & lrS).Value
    Inseam = .Range("C2:C" & lrI + 1).Value
End With
Worksheets("Data").Activate
lr = Cells(Rows.Count, "A").End(xlUp).Row
rng = Range("A2:A" & lr).Value
ReDim arr(1 To lr - 1, 1 To 3)
    For Each str In rng
        k = k + 1
        For i = 1 To lrC - 1
            If InStr(1, UCase(str), " " & UCase(Colo(i, 1)) & " ") > 0 Then
                pos1 = InStr(1, UCase(str) & " ", " " & UCase(Colo(i, 1)) & " ") + Len(Colo(i, 1)) + 1
                arr(k, 1) = Colo(i, 1)
                For j = 1 To lrS - 1
                    If InStr(pos1, UCase(str) & " ", " " & Size(j, 1) & " ") > 0 And InStr(pos1, UCase(str), Size(j, 1)) - pos1 < 7 Then
                        pos2 = InStr(pos1, UCase(str) & " ", " " & Size(j, 1) & " ") + Len(Size(j, 1)) + 1
                        arr(k, 2) = Size(j, 1)
                        For m = 1 To lrI - 1
                            If InStr(pos2, UCase(str) & " ", " " & UCase(Inseam(m, 1) & " "), vbTextCompare) > 0 Then
                                arr(k, 3) = UCase(Inseam(m, 1))
                            End If
                        Next
                        GoTo z
                    End If
                Next
            End If
        Next
z:
    Next
Range("B2").Resize(lr - 1, 3).Value = arr
End Sub
 

File đính kèm

Vì các danh sách màu-size-inseam của bạn có cập nhật nên phải lưu danh sách ra sheet riêng để phục vụ việc tìm kiếm
Mình để danh sách trong sheet "List"
Vì có sự trùng lắp ký tự trong cùng nhóm, VD: XL và L là 2 size khác nhau. Do đó trong sheet List mình sắp xếp theo thứ tự giảm dần theo số ký tự. VD:
XL
L
Và 1 số trường hợp đặc biệt khác như ưu tiên L xếp trước 10

Nhấn vào nút RUN để thực hiện việc tách. Phía bên phải là cột so sánh với kết quả của bạn.

PHP:
Option Explicit
Sub Tach()
Dim i&, j&, m&, k&, lr&, lrC&, lrS&, lrI&, pos1&, pos2&, arr()
Dim Colo, Size, Inseam, rng, str
With Worksheets("List")
    lrC = .Cells(Rows.Count, "A").End(xlUp).Row
    lrS = .Cells(Rows.Count, "B").End(xlUp).Row
    lrI = .Cells(Rows.Count, "C").End(xlUp).Row
    Colo = .Range("A2:A" & lrC).Value
    Size = .Range("B2:B" & lrS).Value
    Inseam = .Range("C2:C" & lrI + 1).Value
End With
Worksheets("Data").Activate
lr = Cells(Rows.Count, "A").End(xlUp).Row
rng = Range("A2:A" & lr).Value
ReDim arr(1 To lr - 1, 1 To 3)
    For Each str In rng
        k = k + 1
        For i = 1 To lrC - 1
            If InStr(1, UCase(str), " " & UCase(Colo(i, 1)) & " ") > 0 Then
                pos1 = InStr(1, UCase(str) & " ", " " & UCase(Colo(i, 1)) & " ") + Len(Colo(i, 1)) + 1
                arr(k, 1) = Colo(i, 1)
                For j = 1 To lrS - 1
                    If InStr(pos1, UCase(str) & " ", " " & Size(j, 1) & " ") > 0 And InStr(pos1, UCase(str), Size(j, 1)) - pos1 < 7 Then
                        pos2 = InStr(pos1, UCase(str) & " ", " " & Size(j, 1) & " ") + Len(Size(j, 1)) + 1
                        arr(k, 2) = Size(j, 1)
                        For m = 1 To lrI - 1
                            If InStr(pos2, UCase(str) & " ", " " & UCase(Inseam(m, 1) & " "), vbTextCompare) > 0 Then
                                arr(k, 3) = UCase(Inseam(m, 1))
                            End If
                        Next
                        GoTo z
                    End If
                Next
            End If
        Next
z:
    Next
Range("B2").Resize(lr - 1, 3).Value = arr
End Sub
Cảm ơn anh. Em làm theo anh và được rồi ah.
Cho em hỏi thêm nếu sử dụng hàm thì có thể sử dụng một công thức để có kết quả cho cả cột không anh? ba cột ba công thức ạ.
 
Web KT

Bài viết mới nhất

Back
Top Bottom