Macro tách kí tự từ 1 cell ra nhiều cell

Liên hệ QC
Tôi tuân thủ nội quy khi đăng bài

KPL_1987

Thành viên mới
Tham gia
31/7/23
Bài viết
4
Được thích
0
Mình có file dữ liệu cần phân tách các giá trị cần thiết từ 1 cell (ở cột C) ra các cell độc lập (ở cột M đến cột P) Nhưng không biết xử lý bằng hàm excel hay code như thế nào để làm nhanh việc này, nếu làm tay thì nhiều quá ko làm nổi. Mọi người có hướng nào xử lý thay vì làm bằng tay như hiện tại giúp mình không.

File ví dụ mình có đính kèm để dễ hiểu hơn
 

File đính kèm

  • Ví dụ 1.xlsx
    108.1 KB · Đọc: 24
Công việc này là do bạn không biết làm hay muốn dùng VBA cho "nhanh".

Nếu tôi làm công việc này, tôi vẫn làm bằng tay nổi. Và tôi sẽ làm tay chứ lười viết code lắm.
Chủ yếu là dùng Text-to-columns, hoặc dùng kỹ thuật "tách họ và tên" mà diễn đàn này có cả đống bài. Chỉ vì dữ liệu ở đây không đồng bộ cho nên cái con số đầu tiên phải quyền biến một chút.
Nếu gặp phiên bản 365 thì càng khỏe vì hàm LET dùng trong kỹ thuật "tách họ và tên" rất hiệu quả.

Tuy nhiên trước khi tôi chỉ dẫn bạn cách làm, tôi cần biết thêm chi tiết, bởi vì dữ liệu ví dụ của bạn loạn như cào cào:
1. dấu * tương đương với X?
2. khoảng trắng giữ chuỗi có nghĩa là gì?
 
Lần chỉnh sửa cuối:
Upvote 0
Công việc này là do bạn không biết làm hay muốn dùng VBA cho "nhanh".

Nếu tôi làm công việc này, tôi vẫn làm bằng tay nổi.
Chủ yếu là dùng Text-to-columns, hoặc dùng kỹ thuật "tách họ và tên" mà diễn đàn này có cả đống bài. Chỉ vì dữ liệu ở đây không đồng bộ cho nên cái con số đầu tiên phải quyền biến một chút.
Nếu gặp phiên bản 365 thì càng khỏe vì hàm LET dùng trong kỹ thuật "tách họ và tên" rất hiệu quả.
Nếu dùng hàm thì sợ ko chuẩn vì giá trị số trước và sau X có thay đổi (nó có thể là 1 , 2, 3,... Kí tự số không phải là số nhất định 2 hay 3 kí tự) nên mình nghĩ macro mới giải quyết chính xác đc
 
Upvote 0
Công việc này là do bạn không biết làm hay muốn dùng VBA cho "nhanh".
Nếu tôi làm công việc này, tôi vẫn làm bằng tay nổi.
Chủ yếu là dùng Text-to-columns, hoặc dùng kỹ thuật "tách họ và tên" mà diễn đàn này có cả đống bài. Chỉ vì dữ liệu ở đây không đồng bộ cho nên cái con số đầu tiên phải quyền biến một chút.
Nếu gặp phiên bản 365 thì càng khỏe vì hàm LET dùng trong kỹ thuật "tách họ và tên" rất hiệu quả.
Em đã làm bài này rồi, nhưng vì bài này có từ viết tắt nên lại xóa đi cho đỡ nặng máy anh ạ.
 
Upvote 0
Nếu dùng hàm thì sợ ko chuẩn vì giá trị số trước và sau X có thay đổi (nó có thể là 1 , 2, 3,... Kí tự số không phải là số nhất định 2 hay 3 kí tự) nên mình nghĩ macro mới giải quyết chính xác đc
Bạn chưa tham khảo các thớt nói về "tách họ và tên" cho nên mới có thành kiến như vậy.

Tuy nhiên, tôi từ chối không tiếp chuyện với người hay vết tắt.
Nếu bạn không chữa thì tôi ngưng ở đây. Bạn chờ dân ghiền code làm giùm.
 
Upvote 0
Bạn chưa tham khảo các thớt nói về "tách họ và tên" cho nên mới có thành kiến như vậy.

Bài này không dùng Text-to-columns hay code tách họ tên được, vì kết quả mong muốn của họ là 1-3-2-4, không phải 1-2-3-4.

Theo tôi, một hàm tự tạo mãng là hợp lý.

.
 
Upvote 0
Bài này không dùng Text-to-columns hay code tách họ tên được, vì kết quả mong muốn của họ là 1-3-2-4, không phải 1-2-3-4.

Theo tôi, một hàm tự tạo mãng là hợp lý.

.
Tôi đã nói tôi lười viết code mà. :D
Đối với người thích code thì cứ thao tác vài lượt tay là coi như khó.
Đối với tôi thằng lính nào làm việc nhanh quá thì có lẽ do ban đầu mình định độ khó công việc sai lầm. Sếp của nó cần giao thêm công việc cho nó.

LET sẽ như vầy:
LET(num, 50, x_1, Rept(" ", num)&, y_1, Substitute(Substitute($C6&"XX", "*", x_1), "X", x_1), yx_1, TRIM(LEFT(y_1, num)), choose({ 1, 3, 2, 4 }, Mid(yx_1, IF(N(Mid(yx_1, 2, 1), 2, 3)), Trim(phần thứ ), Trim(phần thứ 2), Trim(phần thứ 4)))
Hàm Choose điều khiển thứ tự phần tử trong mảng.

Nếu phiên bản thấp hơn thì nên dùng cột phụ để giảm tính toán của công thức khủng.

Tôi không dưng công thức cả mâm. Biết "tách họ và tên thì biết phần thứ 3, 2, 4 phải làm ra sao.

Chú thích: tôi rất đồng ý với bạn là bà này dùng UDF tốt hơn. Ở đây tôi chỉ chứng mình cho các bạn thấy việc ồhớt nói chỉ VBA mới làm được là chủ quan, thành kiến, và thiển cận.
 
Lần chỉnh sửa cuối:
Upvote 0
Tôi đã nói tôi lười viết code mà. :D
Đối với người thích code thì cứ thao tác vài lượt tay là coi như khó.
Đối với tôi thằng lính nào làm việc nhanh quá thì có lẽ do ban đầu mình định độ khó công việc sai lầm. Sếp của nó cần giao thêm công việc cho nó.
Em gửi nhầm file, mục đích của Em cần xử lý dữ liệu như file đã lược bỏ các dòng không cần xử lý rồi ạ

Ngoài ra:
1- nếu trong file xuất hiện dấu * thì nó được hiểu tương đương với X
Ví dụ: BH350X200X10X12 = BH350*200*10*12
2-Khoảng trắng (nếu có) là ký tự rác
 

File đính kèm

  • Ví dụ 2.xlsx
    69.8 KB · Đọc: 10
Lần chỉnh sửa cuối:
Upvote 0
Em gửi nhầm file, mục đích của Em cần xử lý dữ liệu như file đã lược bỏ các dòng không cần xử lý rồi ạ

Ngoài ra:
1- nếu trong file xuất hiện dấu * thì nó được hiểu tương đương với X
Ví dụ: BH350X200X10X12 = BH350*200*10*12
2-Khoảng trắng (nếu có) là ký tự rác
Chạy code:
Rich (BB code):
Sub TachSo()
Dim FChr&, i&, iSt&, iC&, iCl&
Dim aData, aRes, sSrc$
   
    aData = Range("C6", "C" & Range("C" & Rows.Count).End(xlUp).Row).Value
    ReDim aRes(1 To UBound(aData), 1 To 4)
    iSt = 1: iC = 1
    For i = 1 To UBound(aData)
        FChr = IIf(IsNumeric(Mid(Trim(aData(i, 1)), 2, 1)), 2, 3)
        sSrc = Trim(Right(Trim(aData(i, 1)), Len(Trim(aData(i, 1))) - FChr + 1))
        sSrc = Replace(sSrc, "*", "X")
        Do While InStr(iSt, sSrc, "X")
            iCl = IIf(iC = 2, 3, IIf(iC = 3, 2, iC))
            aRes(i, iCl) = Mid(sSrc, iSt, InStr(iSt, sSrc, "X") - iSt)
            iC = iC + 1: iSt = InStr(iSt, sSrc, "X") + 1
        Loop
        aRes(i, 4) = Mid(sSrc, iSt): iSt = 1: iC = 1
    Next
    Range("R6").Resize(UBound(aRes), 4).Value = aRes
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Em gửi nhầm file, mục đích của Em cần xử lý dữ liệu như file đã lược bỏ các dòng không cần xử lý rồi ạ

Ngoài ra:
1- nếu trong file xuất hiện dấu * thì nó được hiểu tương đương với X
Ví dụ: BH350X200X10X12 = BH350*200*10*12
2-Khoảng trắng (nếu có) là ký tự rác
Công thức tại M6, tự sửa thêm cho phù hợp với nhu cầu:
Mã:
=TRIM(MID(SUBSTITUTE(SUBSTITUTE(C6,"BH","X"),"X",REPT(" ",100)),100,100))
 
Upvote 0
Thử UDF

PHP:
Public Function Tach4So(s As String) As Variant
'Chi tach chuoi co 4 so
Dim i&, tmp$, arr As Variant
For i = 1 To Len(s)
        If IsNumeric(Mid(s, i, 1)) Then
            s = Mid(s, i)
            Exit For
        End If
Next i
arr = Split(Replace(UCase(s), "*", "X"), "X")
If UBound(arr) = 3 Then
    tmp = arr(1)
    arr(1) = arr(2)
    arr(2) = tmp
    Tach4So = arr
End If
End Function
Cách dùng:

Chọn 4 ô theo hàng ngang, nhập công thức trên thanh công thức:

=Tach4So(A1)

Kết thúc bằng Ctrl + Shift+Enter.

.
 
Upvote 0
Em gửi nhầm file, mục đích của Em cần xử lý dữ liệu như file đã lược bỏ các dòng không cần xử lý rồi ạ

Ngoài ra:
1- nếu trong file xuất hiện dấu * thì nó được hiểu tương đương với X
Ví dụ: BH350X200X10X12 = BH350*200*10*12
2-Khoảng trắng (nếu có) là ký tự rác
Em gửi nhầm file, mục đích của Em cần xử lý dữ liệu như file đã lược bỏ các dòng không cần xử lý rồi ạ

Ngoài ra:
1- nếu trong file xuất hiện dấu * thì nó được hiểu tương đương với X
Ví dụ: BH350X200X10X12 = BH350*200*10*12
2-Khoảng trắng (nếu có) là ký tự rác
Thêm 1 cách nữa cho bạn tham khảo.
Dùng hàm UDF của anh NDu
Mã:
Option Explicit

Function ExtractChar(text As Variant, iType As String)
  Dim Tmp 'As String
  Tmp = Switch(iType = "L", "[^a-zA-Z]", iType = "N", "[^0-9]", iType = "S", "[0-9a-zA-Z]")
  With CreateObject("VBScript.RegExp")
    .Global = True: .Pattern = Tmp
    ExtractChar = .Replace(text, "")
  End With
End Function
Và đoạn code sau:
Mã:
Option Explicit

Sub Tach()
Dim i&, j&, S, Tmp, Temp, Lr&
Dim Arr(), KQ()
Dim Sh As Worksheet
Set Sh = Sheet1
Lr = Sh.Cells(100000, "C").End(xlUp).Row
Arr = Sh.Range("C6:C" & Lr)
ReDim KQ(1 To UBound(Arr), 1 To 4)
For i = 1 To UBound(Arr)
Temp = Replace(Arr(i, 1), "X", " ")
S = Split(Temp, " ")

KQ(i, 1) = ExtractChar(S(0), "N")
KQ(i, 2) = ExtractChar(S(2), "N")
KQ(i, 3) = ExtractChar(S(1), "N")
KQ(i, 4) = ExtractChar(S(3), "N")
    'Sheet1.Cells(i + 1, (j * 2) + 18) = ExtractChar(Tmp, "N")
'Next j
Next i
Sheet1.Range("R6").Resize(i, 4) = KQ
End Sub
Kết quả đang để ở R6 trở xuống.
 

File đính kèm

  • Ví dụ 2.xlsm
    82.8 KB · Đọc: 3
Upvote 0
Bạn thử công thức này xem sao:
TRIM(CONCAT(IFERROR(MID(C6,ROW(INDIRECT("1:"&LEN(C6))),1)+0," ")))

Sau đó dùng Text to Columns
 
Upvote 0
Bạn thử công thức này xem sao:
TRIM(CONCAT(IFERROR(MID(C6,ROW(INDIRECT("1:"&LEN(C6))),1)+0," ")))

Sau đó dùng Text to Columns
Concat theo ghi chú của Microsoft là từ bản 2016, mà không biết là phiên bản nào. Mấy bản 2016 mình dùng đều không thấy có hàm này. Nếu 2019 thì hình như có hàm Sequence rồi.
 
Upvote 0
Tham khảo thêm hàm tự tạo
Mã:
Function TachSo(iStr As String, iD As Byte) As Double
    Dim S, Tmp$, j&
    S = Split(iStr, "X")
    If UBound(S) < iD Then ReDim Preserve S(0 To iD - 1)
    Tmp = S(iD - 1)
    For j = 1 To Len(S(iD - 1))
        If IsNumeric(Mid(Tmp, j)) = True Then
            TachSo = Val(Mid(Tmp, j)): Exit Function
        End If
    Next j
End Function
Cách dùng = Tachso(C6,1)
Đối số thứ 2 là vị trí số muốn tách
 
Upvote 0
Web KT

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

Back
Top Bottom