Giúp code: Dựa vào bảng tra để viết tắt Tên!
Em chào Thầy cô & Anh chị!
Vui lòng viết giúp code cho em như sau:
Tại Sheet DS cột B, em có danh sách tên Cty, do tên này thường qúa dài nên khi em nối chuỗi thì nó dài quá!
Bây giờ em lập bảng tra tại cột I của Sheet MA, bảng này dùng để liệt kê các từ cần lọai bỏ, khi chuyển 1 tên Cty bình thường sang viết tắt.
VD: bên bảng tra (cột I của Sheet MA) có chữ "TNHH" thì tại sheet DS cột F (cột kết quả chạy code) sẽ lấy tên cty tại cột B và bỏ chữ "TNHH"
Cty TNHH Hồng Vân thì kết qủa là Cty Hồng Vân
————-
Lưu ý: Bảng tra của em còn có thể thêm nhiều từ khác
Xin xem File đính kèm
Em cảm ơn!
Dùng UDF cho linh hoạt nhé.
Function TenTat(Str As String, Arr)
Dim Obj, Item
Set Obj = CreateObject("VBScript.RegExp")
For Each Item In Arr
Obj.Pattern = Obj.Pattern & "|" & Item
Next
Obj.Pattern = Replace(Obj.Pattern, "|", "", 1, 1)
Obj.Global = True
Obj.IgnoreCase = True
TenTat = WorksheetFunction.Trim(Obj.Replace(Str, ""))
Set Obj = Nothing
End Function
Tại F4 bạn nhập công thức
=TenTat(B4,MA!$I$3:$I$20)
www.giaiphapexcel.com/diendan/threads/gi%C3%BAp-code-d%E1%BB%B1a-v%C3%A0o-b%E1%BA%A3ng-tra-%C4%91%E1%BB%83-vi%E1%BA%BFt-t%E1%BA%AFt-t%C3%AAn.76285/#post468728
Bạn dùng thử UDF này. Tôi sort dữ liệu trong code luôn. Cú pháp vẫn như cũ.
Function TenTat(Str As String, Arr)
Dim Obj, Tmp As String, i As Long, j As Long
Set Obj = CreateObject("VBScript.RegExp")
Arr = Arr.Value
For i = 1 To UBound(Arr, 1)
For j = i + 1 To UBound(Arr, 1)
If Len(Arr(i, 1)) < Len(Arr(j, 1)) Then
Tmp = Arr(i, 1): Arr(i, 1) = Arr(j, 1): Arr(j, 1) = Tmp
End If
Next
Next
For i = 1 To UBound(Arr, 1)
Obj.Pattern = Obj.Pattern & "|" & Arr(i, 1)
Next
Obj.Pattern = Replace(Obj.Pattern, "|", "", 1, 1)
Obj.Global = True
Obj.IgnoreCase = True
TenTat = WorksheetFunction.Trim(Obj.Replace(Str, ""))
Set Obj = Nothing
End Function
Nếu dữ liệu đã được sort theo độ dài giảm dần thì bạn có thể dùng code cũ ở bài:
Dùng UDF cho linh hoạt nhé.
Function TenTat(Str As String, Arr)
Dim Obj, Item
Set Obj = CreateObject("VBScript.RegExp")
For Each Item In Arr
Obj.Pattern = Obj.Pattern & "|" & Item
Next
Obj.Pattern = Replace(Obj.Pattern, "|", "", 1, 1)
Obj.Global = True
Obj.IgnoreCase = True
TenTat = WorksheetFunction.Trim(Obj.Replace(Str, ""))
Set Obj = Nothing
End Function
Tại F4 bạn nhập công thức=TenTat(B4,MA!$I$3:$I$20)
Kỹ năng giải quyết vấn đề hiệu quả
Mô tả Nội dung Đánh giá Tài nguyên KỸ NĂNG GIẢI QUYẾT VẤN ĐỀ HIỆU QUẢHiểu đúng vấn đề là một nửa của giải...
Xem khóa học
Bạn thử code này xem:
Kết quả còn sai rất nhiều
Ví dụ:
Cty TNHH TM TBVT Vũ Lộc cho kết quả là Cty TBVT Vũ Lộc (mà lý ra phải là: Cty Vũ Lộc)
Cty TNHH TM & TTNT Trung Á Sài Gòn cho kết quả là Cty & Trung Á Sài Gòn (mà lý ra phải là: Cty Trung Á Sài Gòn)
vân vân
—————-
Tôi nghĩ điều đầu tiên tác giả cần làm là:
– Xem kỹ lại bảng tra (viết chính xác các từ cần thay thế)
– Nên sort lại bảng tra theo độ dài chuổi. Chuổi dài nhất nằm trên cùng và chuổi ngắn nhất nằm dưới cùng
Sort theo kiểu ABC cũng được, nhưng quan trọng là duyệt từ dưới lên.
Còn làm từ trên làm xuống thì theo cách NDU!
Kha, kha,. . . . SPAM 1 tí & nhờ MOD/SMOD xóa dùm!
To Nghĩa: Em nghĩ, với bài #3 em làm thử vừa rồi đã đáp ứng hoàn toàn với dữ liệu của tác giả, vậy có cần thiết sắp xếp hay không?
Sort khi không biết mảng là gì, chắc vậy . . . .
Bạn dùng thử UDF này. Tôi sort dữ liệu trong code luôn. Cú pháp vẫn như cũ.
Function TenTat(Str As String, Arr)
Dim Obj, Tmp As String, i As Long, j As Long
Set Obj = CreateObject("VBScript.RegExp")
Arr = Arr.Value
For i = 1 To UBound(Arr, 1)
For j = i + 1 To UBound(Arr, 1)
If Len(Arr(i, 1)) < Len(Arr(j, 1)) Then
Tmp = Arr(i, 1): Arr(i, 1) = Arr(j, 1): Arr(j, 1) = Tmp
End If
Next
Next
For i = 1 To UBound(Arr, 1)
Obj.Pattern = Obj.Pattern & "|" & Arr(i, 1)
Next
Obj.Pattern = Replace(Obj.Pattern, "|", "", 1, 1)
Obj.Global = True
Obj.IgnoreCase = True
TenTat = WorksheetFunction.Trim(Obj.Replace(Str, ""))
Set Obj = Nothing
End Function
Nếu dữ liệu đã được sort theo độ dài giảm dần thì bạn có thể dùng code cũ ở bài #2.
Thêm 1 thủ tục chẳng giống ai cho bạn tham khảo
Sub Ten_Tat()
Dim data(), i, j, Res(), temp1, temp2
With Sheet2
.Range(., ..End(3)).Offset(, -1) = [Row(a:a)]
.Range(., ..End(3)).Offset(, 1).FormulaR1C1 = "=LEN(RC)"
.Range(., ..End(3)).Resize(, 3).Sort ., 2
data = .Range(., ..End(3).Offset(1)).Value
.Range(., ..End(3)).Offset(, 2).ClearContents
.Range(., ..End(3)).Resize(, 3).Sort ., 1
End With
data(UBound(data), 1) = "&"
Res = Sheet1.Range(Sheet1., Sheet1..End(3)).Value
For i = 1 To UBound(Res)
For j = 1 To UBound(data)
Res(i, 1) = Application.Trim(Replace(Res(i, 1), data(j, 1), "", , , 1))
Next
Next
Sheet1..Resize(i – 1) = Res
End Sub
Vầy thì ngắn hơn chút. Nếu có thêm cột STT trước cột I thì sau khi xử lý sẽ trả cột I về trạng thái ban đầu.
Sub Ten_Tat2()
Dim data(), i, j, Res(), temp1, temp2
With Sheet2
.Range(., ..End(3)).Sort ., 2
data = .Range(., ..End(3).Offset(1)).Value
End With
data(UBound(data), 1) = "&"
Res = Sheet1.Range(Sheet1., Sheet1..End(3)).Value
For i = 1 To UBound(Res)
For j = UBound(data) To 1 Step -1
Res(i, 1) = Application.Trim(Replace(Res(i, 1), data(j, 1), "", , , 1))
Next
Next
Sheet1..Resize(i – 1) = Res
End Sub
To HuuThang:
Thuật toán của bạn rất hay, nhưng mình nghĩ nên dùng hàm Join để tạo ra chuỗi cho pattern
PTN = Join(Application.Transpose(Arr), "|")
To HongVan:
Mình nghĩ bạn nên thêm cái dấu "&" trong sheet MA thì tốt hơn. Hoặc là chuỗi PTN sẽ thế này
PTN = Join(Application.Transpose(Arr), "|") & "|&"
To dhn46:
Hình như bài này mà không sort dữ liệu thì không được đâu. Mình test code của bạn rồi và kết quả không đúng
Thật ra dù các bạn làm gì đi nữa thì cũng sẽ có ít nhiều sai sót do chuỗi trùng chuỗi, ví dụ Công trình, người ta viết tắt CT nếu chuỗi là CTY CT CẢNG (CÔNG TY CÔNG TRÌNH CẢNG) nếu loại bỏ chữ CT đi thì kết quả sẽ là Y CẢNG
Cho nên hàm chỉ hỗ trợ tương đối chứ không thể tuyệt đối trong trường hợp này.
Nếu dữ liệu lộn xộn thì xếp lại sẽ nhanh hơn; Bằng không thì ghi đâu đó & kiểm tra,
Nếu ngắn hơn thì bị ghi đè bằng cái hiện hành vô thay thế;