Hỗ trợ hàm UDF tách chữ tô màu

Liên hệ QC

Tình nghĩa giang hồ

Thanh sơn bất cải, lục thủy trường lưu
Tham gia
29/9/20
Bài viết
330
Được thích
429
Chào anh em GPE, mình có bài tập tách chữ tô màu nhờ anh em hỗ trợ giúp.
Nội dung chỉ đơn giản chỗ nào có màu đỏ thì mình tách sang cột mới.
Nhờ anh em hỗ trợ gúp, cảm ơn anh em GPE.
 

File đính kèm

  • tách chữ tô màu đỏ.jpg
    tách chữ tô màu đỏ.jpg
    74.3 KB · Đọc: 45
  • tách chữ màu đỏ.xlsb
    8.4 KB · Đọc: 20
Upvote 0
Bài tập này do thầy Sếp giao đúng không bạn?
Bài tập của bạn bè cafe thôi bạn, một nhạc sĩ...........một câu hỏi vu vơ, nhưng là bạn bè thì mình tìm hiểu và giúp bạn đó.
(Chỉ cần gọi nhau là anh em thì khó khăn cỡ nào cũng giúp cơ mà.......)
 
Upvote 0
UDF không thể tạo nên cái gì trên bảng tính cả. Đó là luật bảo vệ bảng tính của Microsoft.
Cách gần như duy nhất để đi vòng qua luật này là tạm thời dùng một công cụ khác giật lại điều khiển (controls) từ UDF. Công cụ ấy là Class Module.

Code làm việc này khá rắc rối.

Trước khi bắt đâu viết cái code Class Module thì phải hiểu rõ tại sao Microsoft ra cái luật "bảo vệ" này:
1. Hàm không thể lấn ngoài phạm vi ô chứa nó. Lấn tùm lum hư hết dữ liệu những nơi khác.
2. Khi tham số hàm thay đổi, nó phải gỡ những gì mà nó tạo ra trước đó? Điều này gần như không thể thực hiện. Bởi vì nếu nhiều hàm tạo tùm lum thì nó biết gỡ phần của nó ra sao?
 
Upvote 0
Chào anh em GPE, mình có bài tập tách chữ tô màu nhờ anh em hỗ trợ giúp.
Nội dung chỉ đơn giản chỗ nào có màu đỏ thì mình tách sang cột mới.
Nhờ anh em hỗ trợ gúp, cảm ơn anh em GPE.
Dùng hàm tự tạo
Mã:
Function KyTuDo(ByVal rng As Range)
  Dim txt$, tmp$, N&, j&, fj&
  txt = rng.Value
  N = Len(txt)
  For j = 1 To N
    If rng.Characters(j, 1).Font.ColorIndex = 3 Then
      If fj = 0 Then fj = j
    End If
    If fj > 0 Then
      If rng.Characters(j, 1).Font.ColorIndex <> 3 Or j = N Then
        If j = N Then j = N + 1
        tmp = tmp & "; " & Mid(txt, fj, j - fj)
        fj = 0
      End If
    End If
  Next j
  KyTuDo = Mid(tmp, 3)
End Function
Công thứ trong sheet
Mã:
B2 =KyTuDo(A2)
Copy xuống
 
Upvote 0
Dùng hàm tự tạo
Mã:
Function KyTuDo(ByVal rng As Range)
  Dim txt$, tmp$, N&, j&, fj&
  txt = rng.Value
  N = Len(txt)
  For j = 1 To N
    If rng.Characters(j, 1).Font.ColorIndex = 3 Then
      If fj = 0 Then fj = j
    End If
    If fj > 0 Then
      If rng.Characters(j, 1).Font.ColorIndex <> 3 Or j = N Then
        If j = N Then j = N + 1
        tmp = tmp & "; " & Mid(txt, fj, j - fj)
        fj = 0
      End If
    End If
  Next j
  KyTuDo = Mid(tmp, 3)
End Function
Công thứ trong sheet
Mã:
B2 =KyTuDo(A2)
Copy xuống
Hàm này sử dụng ngon lành cành đào. Xin đa tạ người anh em Hieu CD nhé.
 
Upvote 0
Dùng hàm tự tạo
Mã:
Function KyTuDo(ByVal rng As Range)
  Dim txt$, tmp$, N&, j&, fj&
  txt = rng.Value
  N = Len(txt)
  For j = 1 To N
    If rng.Characters(j, 1).Font.ColorIndex = 3 Then
      If fj = 0 Then fj = j
    End If
    If fj > 0 Then
      If rng.Characters(j, 1).Font.ColorIndex <> 3 Or j = N Then
        If j = N Then j = N + 1
        tmp = tmp & "; " & Mid(txt, fj, j - fj)
        fj = 0
      End If
    End If
  Next j
  KyTuDo = Mid(tmp, 3)
End Function
Công thứ trong sheet
Mã:
B2 =KyTuDo(A2)
Copy xuống
Đối với bài này tách chữ màu đỏ thì code này quá ok. Nhưng cho mình hỏi thêm bác HieuCD. Giả sử trong đoạn văn của mình không chỉ một màu đỏ, mà là * đỏ, cam, vàng, lục, lam, chàm, tím* thì mình sửa code lại như thế nào bác Hieu CD. Nói nôm na: là màu đen là màu trung tâm, khác với màu đen thì mình lấy ra cột mới. Cái này là mình hỏi thêm.
 
Upvote 0
Đối với bài này tách chữ màu đỏ thì code này quá ok. Nhưng cho mình hỏi thêm bác HieuCD. Giả sử trong đoạn văn của mình không chỉ một màu đỏ, mà là * đỏ, cam, vàng, lục, lam, chàm, tím* thì mình sửa code lại như thế nào bác Hieu CD. Nói nôm na: là màu đen là màu trung tâm, khác với màu đen thì mình lấy ra cột mới. Cái này là mình hỏi thêm.
Thử các tùy chọn theo hướng dẫn trong hàm "KyTuMau"
Mã:
Function KyTuMau(ByVal rng As Range, Optional ByVal ColorID As Long = -1)
  Dim absID&, jColor&, bPos As Boolean, txt$, tmp$, N&, j&, fj&
' Lay cac ky tu co Ma Mau "ColorID" cua chuoi gia tri "rng"
' "- ColorID" Lay cac ky tu co Ma Mau "Khác" "ColorID"
' "ColorID" mac dinh = -1: lay cac ký tu khong phai Mau "Den" hoac "Automatic"
' KyTuMau(A2,3) lay cac ky tu co Ma Mau = 3 cua chuoi gia tri o "A2"
' KyTuMau(A2) lay cac ky tu co Mau khac mau "Den"
  Application.Volatile
  absID = Abs(ColorID)
  bPos = (ColorID > 0)
  txt = rng.Value
  N = Len(txt)
  For j = 1 To N
    jColor = rng.Characters(j, 1).Font.ColorInDex
    If jColor = -4105 Then jColor = 1
    If (jColor = absID) = bPos Then
      If fj = 0 Then fj = j
    End If
    If fj > 0 Then
      If (jColor <> absID) = bPos Or j = N Then
        If j = N Then j = N + 1
        tmp = tmp & "; " & Mid(txt, fj, j - fj)
        fj = 0
      End If
    End If
  Next j
  KyTuMau = Mid(tmp, 3)
End Function
Khuyến mãi thêm hàm "ColorID" xác định "Mã màu"
Mã:
Function ColorID(ByVal rng As Range, Optional ByVal Order_Number As Long = 1) As Long
' Lay Ma Màu ky tu thu "Order_Number" cua chuoi gia tri "rng"
' =ColorID(A2,4) lay Ma Màu ky tu thu "4" cua chuoi gia tri o "A2"
' "Order_Number" mac dinh = 1
' =ColorID(A2) lay Ma Màu ky tu thu "1" cua o "A2"
  Application.Volatile
  ColorID = rng.Characters(Order_Number, 1).Font.ColorInDex
End Function
Có thể có vài trường hợp đặc biệt hơi lạ do giới hạn của ".Font.ColorInDex"
 
Upvote 0
Thử các tùy chọn theo hướng dẫn trong hàm "KyTuMau"
Mã:
Function KyTuMau(ByVal rng As Range, Optional ByVal ColorID As Long = -1)
  Dim absID&, jColor&, bPos As Boolean, txt$, tmp$, N&, j&, fj&
' Lay cac ky tu co Ma Mau "ColorID" cua chuoi gia tri "rng"
' "- ColorID" Lay cac ky tu co Ma Mau "Khác" "ColorID"
' "ColorID" mac dinh = -1: lay cac ký tu khong phai Mau "Den" hoac "Automatic"
' KyTuMau(A2,3) lay cac ky tu co Ma Mau = 3 cua chuoi gia tri o "A2"
' KyTuMau(A2) lay cac ky tu co Mau khac mau "Den"
  Application.Volatile
  absID = Abs(ColorID)
  bPos = (ColorID > 0)
  txt = rng.Value
  N = Len(txt)
  For j = 1 To N
    jColor = rng.Characters(j, 1).Font.ColorInDex
    If jColor = -4105 Then jColor = 1
    If (jColor = absID) = bPos Then
      If fj = 0 Then fj = j
    End If
    If fj > 0 Then
      If (jColor <> absID) = bPos Or j = N Then
        If j = N Then j = N + 1
        tmp = tmp & "; " & Mid(txt, fj, j - fj)
        fj = 0
      End If
    End If
  Next j
  KyTuMau = Mid(tmp, 3)
End Function
Khuyến mãi thêm hàm "ColorID" xác định "Mã màu"
Mã:
Function ColorID(ByVal rng As Range, Optional ByVal Order_Number As Long = 1) As Long
' Lay Ma Màu ky tu thu "Order_Number" cua chuoi gia tri "rng"
' =ColorID(A2,4) lay Ma Màu ky tu thu "4" cua chuoi gia tri o "A2"
' "Order_Number" mac dinh = 1
' =ColorID(A2) lay Ma Màu ky tu thu "1" cua o "A2"
  Application.Volatile
  ColorID = rng.Characters(Order_Number, 1).Font.ColorInDex
End Function
Có thể có vài trường hợp đặc biệt hơi lạ do giới hạn của ".Font.ColorInDex"
Cảm ơn bác HieuCD nhé. Bác thật có Tâm.
 
Upvote 0
Bạn thử xem thế này ổn không bạn:

JavaScript:
Function getValueDrew(ByVal target As Range, Optional DiffColor = 0) As String
  Dim i&, ss, s$, l&
  ss = VBA.Split(target(1, 1).Value(11), "html:Color=""#", , 1)
  For i = 1 To UBound(ss)
    l = CLng("&H" & VBA.Left(ss(i), 6))
    If l <> DiffColor Then
      s = s & IIf(s <> vbNullString, "; ", vbNullString) & VBA.Split(VBA.Mid(ss(i), 9), "</Font>", , 1)(0)
    End If
  Next
  getValueDrew = s
End Function
 
Lần chỉnh sửa cuối:
Upvote 0
Bạn copy lại bản này cho chính xác yêu cầu:
JavaScript:
Function getValueDrew(ByVal target As Range, Optional DiffColor = 0) As String
  Dim i&, ss, s$
  ss = VBA.Split(target(1, 1).Value(11), "html:Color=""#", , 1)
  For i = 1 To UBound(ss)
    If CLng("&H" & VBA.Left(ss(i), 6)) <> DiffColor Then
      s = s & IIf(s <> vbNullString, "; ", vbNullString) & VBA.Split(VBA.Mid(ss(i), 9), "</Font>", , 1)(0)
    End If
  Next
  getValueDrew = s
End Function
 
Upvote 0
Bạn copy lại bản này cho chính xác yêu cầu:
JavaScript:
Function getValueDrew(ByVal target As Range, Optional DiffColor = 0) As String
  Dim i&, ss, s$
  ss = VBA.Split(target(1, 1).Value(11), "html:Color=""#", , 1)
  For i = 1 To UBound(ss)
    If CLng("&H" & VBA.Left(ss(i), 6)) <> DiffColor Then
      s = s & IIf(s <> vbNullString, "; ", vbNullString) & VBA.Split(VBA.Mid(ss(i), 9), "</Font>", , 1)(0)
    End If
  Next
  getValueDrew = s
End Function
Kết quả nè bác, có vài chỗ chưa ổn lắm. Dù sao cũng cám ơn bác nhiều.
 

File đính kèm

  • tách chữ màu đỏ.xlsb
    18.6 KB · Đọc: 5
  • CODE MỚI.jpg
    CODE MỚI.jpg
    82.2 KB · Đọc: 25
Upvote 0
Kết quả nè bác, có vài chỗ chưa ổn lắm. Dù sao cũng cám ơn bác nhiều.

Bạn sửa một chút:

JavaScript:
Function getValueDrew(ByVal target As Range, Optional DiffColor = 0) As String
  Dim i&, ss, s$, a$
  ss = VBA.Split(target(1, 1).Value(11), "html:Color=""#", , 1)
  If UBound(ss) > 0 Then
    For i = 1 To UBound(ss)
      If CLng("&H" & VBA.Left(ss(i), 6)) <> DiffColor Then
        a = VBA.Split(VBA.Mid(ss(i), 9), "</Font>", , 1)(0)
        Select Case a
        Case " ", vbNewLine, vbTab, vbCr, vbLf
        Case Else: s = s & IIf(s <> vbNullString, "; ", vbNullString) & a
        End Select
      End If
    Next
  Else
    If target(1, 1).Font.Color <> DiffColor Then
      s = target(1, 1).Value
    End If
  End If
  getValueDrew = s
End Function
 
Upvote 0

Bạn sửa một chút:

JavaScript:
Function getValueDrew(ByVal target As Range, Optional DiffColor = 0) As String
  Dim i&, ss, s$, a$
  ss = VBA.Split(target(1, 1).Value(11), "html:Color=""#", , 1)
  If UBound(ss) > 0 Then
    For i = 1 To UBound(ss)
      If CLng("&H" & VBA.Left(ss(i), 6)) <> DiffColor Then
        a = VBA.Split(VBA.Mid(ss(i), 9), "</Font>", , 1)(0)
        Select Case a
        Case " ", vbNewLine, vbTab, vbCr, vbLf
        Case Else: s = s & IIf(s <> vbNullString, "; ", vbNullString) & a
        End Select
      End If
    Next
  Else
    If target(1, 1).Font.Color <> DiffColor Then
      s = target(1, 1).Value
    End If
  End If
  getValueDrew = s
End Function
Code mới đã ngon lành cành đào rồi bác HeSanbi
Bài đã được tự động gộp:


Bạn sửa một chút:

JavaScript:
Function getValueDrew(ByVal target As Range, Optional DiffColor = 0) As String
  Dim i&, ss, s$, a$
  ss = VBA.Split(target(1, 1).Value(11), "html:Color=""#", , 1)
  If UBound(ss) > 0 Then
    For i = 1 To UBound(ss)
      If CLng("&H" & VBA.Left(ss(i), 6)) <> DiffColor Then
        a = VBA.Split(VBA.Mid(ss(i), 9), "</Font>", , 1)(0)
        Select Case a
        Case " ", vbNewLine, vbTab, vbCr, vbLf
        Case Else: s = s & IIf(s <> vbNullString, "; ", vbNullString) & a
        End Select
      End If
    Next
  Else
    If target(1, 1).Font.Color <> DiffColor Then
      s = target(1, 1).Value
    End If
  End If
  getValueDrew = s
End Function
Bác là tác giả TÌM KIẾM VÀ TÔ MÀU CHUỖI TÌM ĐƯỢC phải không? Bài viết đó khá hay, khá nhiều ứng dụng cho công việc. Nay hân hạnh được gặp gỡ, đúng là đáng vui đáng mừng.
 

File đính kèm

  • code mới 2.jpg
    code mới 2.jpg
    97.9 KB · Đọc: 15
Lần chỉnh sửa cuối:
Upvote 0
Code mới đã ngon lành cành đào rồi bác HeSanbi
Bài đã được tự động gộp:


Bác là tác giả TÌM KIẾM VÀ TÔ MÀU CHUỖI TÌM ĐƯỢC phải không? Bài viết đó khá hay, khá nhiều ứng dụng cho công việc. Nay hân hạnh được gặp gỡ, đúng là đáng vui đáng mừng.
Phiên bản Pro dành cho bạn:
Bạn có thể chọn tùy chọn RevDiff là True/False
Tức là đặt màu đen, thì tìm tất cả khác màu đen / hoặc chính màu đen
 

File đính kèm

  • tách chữ màu đỏ.xlsb
    26.7 KB · Đọc: 22
Lần chỉnh sửa cuối:
Upvote 0
Có trường hơp ngược lại được không anh @HeSanbi , tức là =HAM(Range,TXT,optional Color) thì trong Range sẽ tìm ra đoạn TXT và tô Color(mặc định đỏ).
 
Upvote 0
Có trường hơp ngược lại được không anh @HeSanbi , tức là =HAM(Range,TXT,optional Color) thì trong Range sẽ tìm ra đoạn TXT và tô Color(mặc định đỏ).
Bài viết nằm ở đây sẽ giúp bạn đạt được mong muốn
 
Upvote 0
Web KT

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

Back
Top Bottom