Dựa vào VBA xác định các số trùng lặp trong bảng

Liên hệ QC

1986QV

Thành viên hoạt động
Tham gia
15/5/12
Bài viết
114
Được thích
6
Nghề nghiệp
Kỹ sư
Bài toán của mình có 2 phần. phần 1 tìm theo chiều thuận, phần 2 tìm theo thuận đảo của số. Tất cả đều sử dụng VBA tìm, nhầm tránh nhầm lẫn các số tìm được phải tô màu cụ thể. Rất mong các bạn giúp đỡ mình để mình làm công việc hiệu quả hơn.
Cảm ơn các bạn quan tâm giúp đỡ!
 

File đính kèm

  • Dua vao VBA xac dinh cac so trung lap.xlsx
    9.7 KB · Đọc: 50
Lần chỉnh sửa cuối:
Bài toán của mình có 2 phần. phần 1 tìm theo chiều thuận, phần 2 tìm theo thuận đảo của số. Tất cả đều sử dụng VBA tìm, nhầm tránh nhầm lẫn các số tìm được phải tô màu cụ thể. Rất mong các bạn giúp đỡ mình để mình làm công việc hiệu quả hơn.
Cảm ơn các bạn quan tâm giúp đỡ!

Trong file đính kèm, tôi viết 2 macro tách rời (thật ra có thể chỉ cần viết 1 sub sau đó tùy tình huống mà truyền tham số để so sánh) cho 2 sheet. Ban load về chạy thử nhé.
Macro1: so sánh bằng tuyệt đối:
PHP:
Sub CommandButton1_Click()
Dim r As Range, a(), i As Long, j As Long, iR As Long, iC As Long, _
    xI As Long, yI As Long, xJ As Long, yJ As Long
Dim co As Integer, hasDoub As Boolean
    Set r = ActiveSheet.Range("a5").CurrentRegion
    iR = r.Rows.Count
    iC = r.Columns.Count
    r.Cells.Interior.ColorIndex = 0
    ReDim a(1 To iR, 1 To iC)
    a = r
    co = 1
    For i = 1 To iR * iC - 1
        hasDoub = True
        xI = WorksheetFunction.RoundUp(i / iC, 0)
        yI = IIf(i Mod iC = 0, iC, i Mod iC)
        If a(xI, yI) <> "" Then
       
        For j = i + 1 To iR * iC
            xJ = WorksheetFunction.RoundUp(j / iC, 0)
            yJ = IIf(j Mod iC = 0, iC, j Mod iC)
            If a(xJ, yJ) <> "" Then
            If a(xI, yI) = a(xJ, yJ) Then 'Hai thủ tục chỉ khác nhau ở phép so sánh này'
                If hasDoub Then
                    co = co + 1
                    r.Cells(xI, yI).Interior.ColorIndex = co
                End If
                r.Cells(xJ, yJ).Interior.ColorIndex = co
                hasDoub = False
                a(xJ, yJ) = ""
            End If
            End If
        Next
        End If
    Next
    Set r = Nothing
    Erase a
End Sub

Macro 2: so sánh bằng nhau và đảo nhau

PHP:
Sub CommandButton2_Click()
Dim r As Range, a(), i As Long, j As Long, iR As Long, iC As Long, _
    xI As Long, yI As Long, xJ As Long, yJ As Long
Dim co As Integer, hasDoub As Boolean
    Set r = ActiveSheet.Range("a5").CurrentRegion
    iR = r.Rows.Count
    iC = r.Columns.Count
    r.Cells.Interior.ColorIndex = 0
    ReDim a(1 To iR, 1 To iC)
    a = r
    co = 5
    For i = 1 To iR * iC - 1
        hasDoub = True
        xI = WorksheetFunction.RoundUp(i / iC, 0)
        yI = IIf(i Mod iC = 0, iC, i Mod iC)
        If a(xI, yI) <> "" Then
       
        For j = i + 1 To iR * iC
            xJ = WorksheetFunction.RoundUp(j / iC, 0)
            yJ = IIf(j Mod iC = 0, iC, j Mod iC)
            If a(xJ, yJ) <> "" Then
            If a(xI, yI) = a(xJ, yJ) Or CStr(a(xI, yI)) = StrReverse(CStr(a(xJ, yJ))) Then
                If hasDoub Then
                    co = co + 1
                    r.Cells(xI, yI).Interior.ColorIndex = co
                End If
                r.Cells(xJ, yJ).Interior.ColorIndex = co
                hasDoub = False
                a(xJ, yJ) = ""
            End If
            End If
        Next
        End If
    Next
    Set r = Nothing
    Erase a
End Sub
 

File đính kèm

  • Dua vao VBA xac dinh cac so trung lap_2.rar
    19.7 KB · Đọc: 50
Lần chỉnh sửa cuối:
Upvote 0
Bài toán của mình có 2 phần. phần 1 tìm theo chiều thuận, phần 2 tìm theo thuận đảo của số. Tất cả đều sử dụng VBA tìm, nhầm tránh nhầm lẫn các số tìm được phải tô màu cụ thể. Rất mong các bạn giúp đỡ mình để mình làm công việc hiệu quả hơn.
Cảm ơn các bạn quan tâm giúp đỡ!
Thử bài này xem
Nếu hơn 50 màu thì "tèo" à nha, phải làm cách khác
Híc
 

File đính kèm

  • Dua vao VBA xac dinh cac so trung lap.rar
    25.4 KB · Đọc: 94
Upvote 0
Ôi... Mạng ba trợn rồi
Post 2 bài cùng lúc ---> Mod xóa giùm nhé
Code bài dưới mới là "chuẩn" nha
 
Lần chỉnh sửa cuối:
Upvote 0
Thử bài này xem
Nếu hơn 50 màu thì "tèo" à nha, phải làm cách khác
Híc

Em nghĩ 1 vòng lập cũng có thể được đấy
Đại khái chắc thế này:
PHP:
Sub Thuan()
  Dim Rng As Range, Clls As Range, Dic As Object, OldRng As String
  Dim n As Long, tmp As String
  'On Error Resume Next
  Set Rng = Range("A1").CurrentRegion
  Rng.Interior.ColorIndex = xlNone
  Set Dic = CreateObject("Scripting.Dictionary")
  n = 2
  For Each Clls In Rng
    If Clls.Text <> "" Then
      If Not Dic.Exists(Clls.Text) Then
        Dic.Add Clls.Text, Clls.Address
      Else
        If Range(Dic.Item(Clls.Text)).Interior.ColorIndex = xlNone Then
          n = n + 1
          Range(Dic.Item(Clls.Text)).Interior.ColorIndex = n
        End If
        OldRng = Dic.Item(Clls.Text)
        tmp = Dic.Item(Clls.Text) & ", " & Clls.Address
        Dic.Item(Clls.Text) = tmp
        Range(tmp).Interior.ColorIndex = Range(OldRng).Interior.ColorIndex
      End If
    End If
  Next
End Sub
Chỉ có 1 nguy hiểm: n vượt quá 56 thì... Ẹc... Ẹc...
 
Lần chỉnh sửa cuối:
Upvote 0
Có thể thay ColorIndex bằng Color và dùng hàm RGB để xác định màu (tránh trường hợp n vượt quá 56).
 
Upvote 0
Có thể thay ColorIndex bằng Color và dùng hàm RGB để xác định màu (tránh trường hợp n vượt quá 56).
Dùng RGB có thể xác định 16.7 triệu màu, tuy nhiên Excel chỉ thể hiện 56 màu mà thôi. Tức thời có thể thấy màu RGB, nhưng sau khi save, đóng lại, mở lên chỉ còn 56 màu.
 
Upvote 0
Em nghĩ 1 vòng lập cũng có thể được đấy
Đại khái chắc thế này:
PHP:
Sub Thuan()
  Dim Rng As Range, Clls As Range, Dic As Object, OldRng As String
  Dim n As Long, tmp As String
  'On Error Resume Next
  Set Rng = Range("A1").CurrentRegion
  Rng.Interior.ColorIndex = xlNone
  Set Dic = CreateObject("Scripting.Dictionary")
  n = 2
  For Each Clls In Rng
    If Clls.Text <> "" Then
      If Not Dic.Exists(Clls.Text) Then
        Dic.Add Clls.Text, Clls.Address
      Else
        If Range(Dic.Item(Clls.Text)).Interior.ColorIndex = xlNone Then
          n = n + 1
          Range(Dic.Item(Clls.Text)).Interior.ColorIndex = n
        End If
        OldRng = Dic.Item(Clls.Text)
        tmp = Dic.Item(Clls.Text) & ", " & Clls.Address
        Dic.Item(Clls.Text) = tmp
        Range(tmp).Interior.ColorIndex = Range(OldRng).Interior.ColorIndex
      End If
    End If
  Next
End Sub
Chỉ có 1 nguy hiểm: n vượt quá 56 thì... Ẹc... Ẹc...

Ndu cho mình hỏi: trong code trên thay Clls.Text = Clls.Value có được không ? vì tôi thường viết là Clls.Value (không phân biệt giá trị là Text hay Number)
 
Upvote 0
Ndu cho mình hỏi: trong code trên thay Clls.Text = Clls.Value có được không ? vì tôi thường viết là Clls.Value (không phân biệt giá trị là Text hay Number)

.Text là cái anh nhìn thấy, còn .Value là giá trị thật
Ví dụ anh format số 123456 thành dạng #,##0 thì cái anh nhìn thấy là 123,456 còn giá trị thật đương nhiên vẫn là 123456
Ỏ trong file của tác giá, các giá trị đều là dạng số và có vài cell có số 0 đằng trước (như 04 chẳng hạn)... Em muốn chắc ăn code phải lấy được số 04 chứ không phải giá trị 4 nên dùng .Text cho an toàn thôi anh à ----> Ai biết được có cell nào đó do format mà ta thấy là 04 nhưng thực chất nó chỉ là số 4 thì sao?
Ẹc... Ẹc...
 
Lần chỉnh sửa cuối:
Upvote 0
Code ở bài #6 có đoạn:
Mã:
tmp = Dic.Item(Clls.Text) & ", " & Clls.Address
Tức dùng phép nối chuổi để "thu gom" các địa chỉ cell thỏa điều kiện
Vậy xin đố mọi người 1 câu: Nếu không dùng phép nối chuổi mà dùng phương thức Union thì ta sẽ sửa code lại thế nào?
Ẹc... Ẹc...
 
Upvote 0
Nhờ bác ndu96081631 viết cho trường hợp 2 đối số ( Ví dụ như 18,81 hoặc 23,32... cùng 1 màu) Xác định được 1 cặp là đối số cho cùng 1 màu. Bài Của bác Luân và Concogia khi chạy thi bị nhầm màu chưa thoải mãn được điều kiện của bài.
Cảm ơn mọi người quan tâm và giúp đỡ !
 
Upvote 0
Bài toán của mình có 2 phần. phần 1 tìm theo chiều thuận, phần 2 tìm theo thuận đảo của số. Tất cả đều sử dụng VBA tìm, nhầm tránh nhầm lẫn các số tìm được phải tô màu cụ thể. Rất mong các bạn giúp đỡ mình để mình làm công việc hiệu quả hơn.
Cảm ơn các bạn quan tâm giúp đỡ!
Đề bài của bạn và cả trong file đính kèm đều xác định các số sau: 12, 12 và 21 đều thỏa mãn tính THUẬN-ĐẢO (nghĩa là ban đầu bạn MONG MUỐN các số THUẬN và ĐẢO đều tô màu, bây giờ bạn lại cho rằng Code của chúng tôi CHƯA THỎA MÃN!!!!!
 
Upvote 0
Nhờ bác ndu96081631 viết cho trường hợp 2 đối số ( Ví dụ như 18,81 hoặc 23,32... cùng 1 màu) Xác định được 1 cặp là đối số cho cùng 1 màu. Bài Của bác Luân và Concogia khi chạy thi bị nhầm màu chưa thoải mãn được điều kiện của bài.
Cảm ơn mọi người quan tâm và giúp đỡ !
ĐẢO cũng tương tự thôi mà (lý ra bạn có thể dựa vào code THUAN để biến đổi)
PHP:
Sub Dao()
  Dim Rng As Range, Clls As Range, Dic As Object, OldRng As String
  Dim n As Long, tmp As String
  On Error Resume Next
  Set Rng = Range("A1").CurrentRegion
  Rng.Interior.ColorIndex = xlNone
  Set Dic = CreateObject("Scripting.Dictionary")
  n = 2
  For Each Clls In Rng
    If Clls.Text <> "" Then
      If (Not Dic.Exists(Clls.Text)) And (Not Dic.Exists(StrReverse(Clls.Text))) Then
        Dic.Add Clls.Text, Clls.Address
      Else
        If Dic.Exists(Clls.Text) Then
          OldRng = Dic.Item(Clls.Text)
        Else
          OldRng = Dic.Item(StrReverse(Clls.Text))
        End If
        If Range(OldRng).Interior.ColorIndex = xlNone Then
          n = n + 1
          Range(OldRng).Interior.ColorIndex = n
        End If
        tmp = OldRng & ", " & Clls.Address
        If Dic.Exists(Clls.Text) Then
          Dic.Item(Clls.Text) = tmp
        Else
          Dic.Item(StrReverse(Clls.Text)) = tmp
        End If
        Range(tmp).Interior.ColorIndex = Range(OldRng).Interior.ColorIndex
      End If
    End If
  Next
End Sub
 
Upvote 0
Xin lỗi bác Hoangvuluan không phải lỗi ở đó. Nghĩa số thuận và đảo của số đó cùng 1 màu. Nhưng em chạy code đó đều chạy màu nhưng không cùng 1 màu bác ah (Bác chạy lại dùm em xem có sai sót gì không). Chứ đâu phải những số đảo của nó chạy màu đâu. Thật thất kính với các bác lão làng quá. Thật xin lỗi các bác!
Cảm ơn các bác và forum đã giúp đỡ!
 
Lần chỉnh sửa cuối:
Upvote 0
Xin lỗi bác Hoangvuluan không phải lỗi ở đó. Nghĩa số thuận và đảo của số đó cùng 1 màu. Nhưng em chạy code đó đều chạy màu nhưng không cùng 1 màu bác ah (Bác chạy lại dùm em xem có sai sót gì không). Chứ đâu phải những số đảo của nó chạy màu đâu. Thật thất kính với các bác lão làng quá. Thật xin lỗi các bác!
Cảm ơn các bác và forum đã giúp đỡ!

Lạ nhỉ, không hiểu! Trên máy tính của tôi chạy thì vẫn cùng màu là sao nhỉ????
Không biết sai chỗ nào???
 
Upvote 0
Em có hỏi các bác xem 56 màu đó tương ứng 56 bộ số khác nhau hay cùng nhau bị loại vậy( ví dụ như 18 với 18 thành 1 màu thì bộ đếm cho 2 màu hay 1 ) vì khi em làm ít ok. Nhưng khi vào nhiều số cùng đều lỗi. Các bác coi giúp em.
Cảm ơn các bác quan tâm!
 
Upvote 0
Xác định sự trùng lặp trong bảng tính bằng VBA

Để giải quyết bài toán tô màu với số lượng lớn mà màu giới không quá 56 thì thật khó. Em đã nghĩ phải cho ra dạng số cho phù hợp. Các bác xem đếm số lần trùng lặp trong bảng và cho ra kết quả bên cạnh cho cả 2 trường hợp nêu trên.
Cảm ơn bạn quan tâm và giúp đỡ!
 

File đính kèm

  • Dua vao VBA xac dinh cac so trung lap.xlsx
    9.8 KB · Đọc: 9
Upvote 0
Bạn xem cách bình dân này coi thế nào, nếu dãy số có 3 chữ số thì bài này không xài được, vì trong file của bạn chỉ có 2 số
Nếu dữ liệu nhiều chắc phải thêm dòng Application.ScreenUpdating = False để code chạy nhanh tí

Và nếu ô nào trúng màu trắng thì bị trùng màu với những ô không được tô màu, nghĩ mãi mà không có phương án nào hết
 

File đính kèm

  • VBA.rar
    13.6 KB · Đọc: 22
Lần chỉnh sửa cuối:
Upvote 0
Web KT
Back
Top Bottom