So sánh giữa hai cột bằng VBA

Liên hệ QC

thao nguyen01

Thành viên thường trực
Tham gia
8/12/19
Bài viết
214
Được thích
25
Kính gửi anh/chị trên diễn đàn,

Em muốn so sánh giữa hai cột và tìm ra những mã khác nhau giữa hai cột. Nhưng em vướng vấn đề sau ạ:
-Số lượng ký tự giữa hai mã có thể khác nhau:
Ví dụ: mã 2 có số ký tự ít hơn nhưng vẫn đúng so với mã 1 (ký tự thiếu chỉ nằm bên trái, em ví dụ có dạng: *ABC) =>thì kết quả là không khác nhau (chỉ liệt kê những mã khác nhau hoặc không có ạ)

Anh/chị xem giúp em ạ. Em cảm ơn ạ.
 

File đính kèm

  • do tim.xlsb
    12.2 KB · Đọc: 25
Lần chỉnh sửa cuối:
Kính gửi anh/chị trên diễn đàn,

Em muốn so sánh giữa hai cột và tìm ra những mã khác nhau giữa hai cột. Nhưng em vướng vấn đề sau ạ:
-Số lượng ký tự giữa hai mã có thể khác nhau:
Ví dụ: mã 2 có số ký tự ít hơn nhưng vẫn đúng so với mã 1 (ký tự thiếu chỉ nằm bên trái, em ví dụ có dạng: *ABC) =>thì kết quả là không khác nhau (chỉ liệt kê những mã khác nhau hoặc không có ạ)

Anh/chị xem giúp em ạ. Em cảm ơn ạ.
Nếu giống nhau dạng ABC* hoặc *ABC* thì sao bạn?
 
Upvote 0
Nếu không có dấu * ở giữa thì tôi nghĩ thế này được rồi.

P/S: cột F là nơi ghi kết quả so sánh tương ứng giữa 2 cột B và D.
 

File đính kèm

  • do tim_thao nguyen01.xlsb
    14 KB · Đọc: 13
Lần chỉnh sửa cuối:
Upvote 0
Kính gửi anh/chị trên diễn đàn,

Em muốn so sánh giữa hai cột và tìm ra những mã khác nhau giữa hai cột. Nhưng em vướng vấn đề sau ạ:
-Số lượng ký tự giữa hai mã có thể khác nhau:
Ví dụ: mã 2 có số ký tự ít hơn nhưng vẫn đúng so với mã 1 (ký tự thiếu chỉ nằm bên trái, em ví dụ có dạng: *ABC) =>thì kết quả là không khác nhau (chỉ liệt kê những mã khác nhau hoặc không có ạ)

Anh/chị xem giúp em ạ. Em cảm ơn ạ.
Bạn mô tả chưa kỹ lưỡng.
Bạn viết
Ví dụ: mã 2 có số ký tự ít hơn nhưng vẫn đúng so với mã 1 thì kết quả là không khác nhau
Đỏ đỏ chỉ là ví dụ ngẫu nhiên hay đó là qui luật? Có phải là mã 2 luôn có số ký tự nhỏ hơn hoặc bằng số lý tự mã 1? Nếu là qui luật hay không thì cũng nên nói toẹt ra.

Luôn luôn so sánh cặp (mã 1, mã 2) cùng dòng?

Tôi thử phát biểu như sau:

"
1. Khái niệm.
Với mỗi dòng ta xét cặp (mã 1; mã 2). Nếu có mã 1 = *mã 2 thì cặp (mã 1; mã 2) gọi là cặp tốt, ngược lại là cặp xấu.

2. Yêu cầu.
Nếu dòng có cặp xấu thì trả về mã 1, ngược lại trả về chuỗi rỗng.
"

Nếu tôi phát biểu không đúng ý thì dừng đọc tại đây, ngược lại thì công thức cho G3
Mã:
=IF(OR(D3="",COUNTIF(B3,"*"&D3)=0),B3&"","")
 
Upvote 0
Em cảm ơn anh @Maika8008 , Thầy @HieuCD và Bác @batman1 đã xem bài của em ạ.

Dạ, lỗi này do em không mô tả kỹ ạ. Dữ liệu của em nằm lệch dòng và không phải lúc nào cũng ở dạng mã 2 ít hơn mã 1 ạ. Em thấy chỉ đúng với dạng *ABC thôi ạ. Vì do người nhập không thống nhất với nhau, mỗi người nhập lấy số ký tự không thống nhất, nên khi dò tìm khá cực và mất nhiều thời gian. Em đã thử làm thủ công nhưng mất nhiều thời gian mà em không thể kiểm soát là có sót không. Trong thời gian tới em nghĩ sẽ điều chỉnh lại nhưng vì hiện tại cần xử lý những dữ liệu quá khứ nên em mong các Thầy, anh/chị trên diễn đàn xem giúp em ạ. Em cảm ơn nhiều ạ

Em xin mô tả lại:
Em muốn tìm những mã khác nhau giữa hai cột (Những mã có ở cột B nhưng không có ở cột D và ngược lại). Dữ liệu lệch dòng.

Nếu số lượng ký tự giữa hai mã khác nhau:

Ví dụ: mã 2 có số ký tự ít hơn nhưng vẫn đúng so với mã 1 thì kết quả là không khác nhau hay ngược lại (số lượng ký tự mã 2 >số lượng ký tự mã 1 và ngược lại)
 

File đính kèm

  • do tim-16.01.2021.xlsb
    12.9 KB · Đọc: 17
Upvote 0
Em cảm ơn anh @Maika8008 , Thầy @HieuCD và Bác @batman1 đã xem bài của em ạ.

Dạ, lỗi này do em không mô tả kỹ ạ. Dữ liệu của em nằm lệch dòng và không phải lúc nào cũng ở dạng mã 2 ít hơn mã 1 ạ. Em thấy chỉ đúng với dạng *ABC thôi ạ. Vì do người nhập không thống nhất với nhau, mỗi người nhập lấy số ký tự không thống nhất, nên khi dò tìm khá cực và mất nhiều thời gian. Em đã thử làm thủ công nhưng mất nhiều thời gian mà em không thể kiểm soát là có sót không. Trong thời gian tới em nghĩ sẽ điều chỉnh lại nhưng vì hiện tại cần xử lý những dữ liệu quá khứ nên em mong các Thầy, anh/chị trên diễn đàn xem giúp em ạ. Em cảm ơn nhiều ạ

Em xin mô tả lại:
Em muốn tìm những mã khác nhau giữa hai cột (Những mã có ở cột B nhưng không có ở cột D và ngược lại). Dữ liệu lệch dòng.

Nếu số lượng ký tự giữa hai mã khác nhau:

Ví dụ: mã 2 có số ký tự ít hơn nhưng vẫn đúng so với mã 1 thì kết quả là không khác nhau hay ngược lại (số lượng ký tự mã 2 >số lượng ký tự mã 1 và ngược lại)
Nếu lệch dòng và không phải lúc nào cũng ở dạng mã 2 ít hơn mã 1 thì mọi việc trở nên phức tạp
 
Upvote 0
Nếu lệch dòng và không phải lúc nào cũng ở dạng mã 2 ít hơn mã 1 thì mọi việc trở nên phức tạp
Dạ, dữ liệu hiện tại của em khoảng 10000 dòng. Nên em chưa biết chính xác là cột mã 2 có số ký tự hoàn toàn nhỏ hơn cột mã 1 không. Nhưng để vấn đề bớt phức tạp, em nghĩ nên để cột mã 1 chuẩn và để cột mã 2 nhỏ hơn cột mã 1 ạ (xem như quy luật ạ, chỉ còn lệch dòng). Em nghĩ xử lý được phần đó cũng đã bớt mất thời gian hơn nhiều rồi ạ.
 
Upvote 0
Dạ, dữ liệu hiện tại của em khoảng 10000 dòng. Nên em chưa biết chính xác là cột mã 2 có số ký tự hoàn toàn nhỏ hơn cột mã 1 không. Nhưng để vấn đề bớt phức tạp, em nghĩ nên để cột mã 1 chuẩn và để cột mã 2 nhỏ hơn cột mã 1 ạ (xem như quy luật ạ, chỉ còn lệch dòng). Em nghĩ xử lý được phần đó cũng đã bớt mất thời gian hơn nhiều rồi ạ.
Nói vậy nhưng không sao. Bạn thử file xem nhé. Những mã có trong Mã 1 nhưng không có trong Mã 2 được ghi ở F3. Mã có trong Mã 2 nhưng không có trong Mã 1 ghi ở G3.
 

File đính kèm

  • do tim_thao nguyen01.xlsb
    15.5 KB · Đọc: 13
Upvote 0
Nói vậy nhưng không sao. Bạn thử file xem nhé. Những mã có trong Mã 1 nhưng không có trong Mã 2 được ghi ở F3. Mã có trong Mã 2 nhưng không có trong Mã 1 ghi ở G3.
Dạ, kết quả ra sai ở ô B11 và D12 ạ. Em nghĩ do anh chọn dòng cuối hai cột giống nhau. Em có thử chỉnh lại code. Em cảm ơn anh nhiều ạ.
Mã:
Option Explicit

Sub DoTim()
Dim arrF, arrCF, arrRsl, arrRsl2
Dim i As Long, j As Long, k As Long, endR As Long, endR02 As Long
Dim chk As Boolean

endR = Range("D" & Rows.Count).End(xlUp).Row
endR02 = Range("B" & Rows.Count).End(xlUp).Row
arrF = Range("D3:D" & endR).Value
arrCF = Range("B3:B" & endR02).Value
ReDim arrRsl(1 To UBound(arrCF), 1 To 1)
ReDim arrRsl2(1 To UBound(arrF), 1 To 1)
For i = 1 To UBound(arrCF)
    For j = 1 To UBound(arrF)
        If Len(arrCF(i, 1)) > Len(arrF(j, 1)) Then
            If arrCF(i, 1) Like "*" & arrF(j, 1) & "*" Then
                chk = True
                Exit For
            End If
        Else
            If arrF(j, 1) Like "*" & arrCF(i, 1) & "*" Then
                chk = True
                Exit For
            End If
        End If
    Next
    If chk = False Then
        k = k + 1
        arrRsl(k, 1) = arrCF(i, 1)
    Else
        chk = False
    End If
Next
Range("F3").Resize(UBound(arrCF), 1).ClearContents
Range("F3").Resize(k, 1).Value = arrRsl
k = 0
For i = 1 To UBound(arrF)
    For j = 1 To UBound(arrCF)
        If Len(arrF(i, 1)) > Len(arrCF(j, 1)) Then
            If arrF(i, 1) Like "*" & arrCF(j, 1) & "*" Then
                chk = True
                Exit For
            End If
        Else
            If arrCF(j, 1) Like "*" & arrF(i, 1) & "*" Then
                chk = True
                Exit For
            End If
        End If
    Next
    If chk = False Then
        k = k + 1
        arrRsl2(k, 1) = arrF(i, 1)
    Else
        chk = False
    End If
Next
Range("G3").Resize(UBound(arrF), 1).ClearContents
Range("G3").Resize(k, 1).Value = arrRsl2
End Sub
 

File đính kèm

  • do tim_thao nguyen01.xlsb
    16.6 KB · Đọc: 18
Lần chỉnh sửa cuối:
Upvote 0
Nói vậy nhưng không sao. Bạn thử file xem nhé. Những mã có trong Mã 1 nhưng không có trong Mã 2 được ghi ở F3. Mã có trong Mã 2 nhưng không có trong Mã 1 ghi ở G3.
Có cách nào chỉ cần 1 lần
For i = 1 To UBound(arrCF)
For j = 1 To UBound(arrF)
...
Next
Next
Là ra kết quả, tốc độ code sẽ nhanh hơn tí
 
Upvote 0
Có cách nào chỉ cần 1 lần
For i = 1 To UBound(arrCF)
For j = 1 To UBound(arrF)
...
Next
Next
Là ra kết quả, tốc độ code sẽ nhanh hơn tí
Dạ, em cũng chưa hiểu cách anh @Maika8008 chạy 2 lần với đoạn code

For i = 1 To UBound(arrCF)
For j = 1 To UBound(arrF)
...
Next
Next

Nhưng kết quả ra đúng ạ.
 
Upvote 0
Upvote 0
Dạ, dữ liệu thật khoảng 10000 dòng ạ.
Dùng tạm , nếu chạy quá chậm báo lại mình viết lại toàn bộ
Mã:
Option Explicit

Sub XYZ()
  Dim Arr1(), Arr2(), Res() As String, t
  Dim i&, i2&, k&, k2&, sR1&, sR2&, sRow&, w&, ma1$, ma2$
   
  t = Timer
  With Sheet1
    Arr1 = .Range("B3", .Range("B" & Rows.Count).End(xlUp)).Value
    Arr2 = .Range("D3", .Range("D" & Rows.Count).End(xlUp)).Value
    sR1 = UBound(Arr1): sR2 = UBound(Arr2)
  End With
  If sR1 > sR2 Then sRow = sR1 Else sRow = sR2
  ReDim Res(1 To sRow, 1 To 2)

  For i = 1 To sR1
    ma1 = Arr1(i, 1)
    w = Len(ma1)
    For i2 = 1 To sR2
      ma2 = Arr2(i2, 1)
      If ma2 <> Empty Then
        If w > Len(ma2) Then
          If ma1 Like "*" & ma2 Then
            Arr2(i2, 1) = Empty
            Exit For
          End If
        Else
          If ma2 Like "*" & ma1 Then
            Arr2(i2, 1) = Empty
            Exit For
          End If
        End If
      End If
    Next i2
    If i2 = sR2 + 1 Then
      k = k + 1
      Res(k, 1) = ma1
    End If
  Next i
  For i2 = 1 To sR2
    If Arr2(i2, 1) <> Empty Then
      k2 = k2 + 1
      Res(k2, 2) = Arr2(i2, 1)
    End If
  Next i2
  With Sheet1
    i = .Range("G" & Rows.Count).End(xlUp).Row
    i2 = .Range("H" & Rows.Count).End(xlUp).Row
    If i2 > i Then i = i2
    If i > 2 Then .Range("G3").Resize(i, 2).ClearContents
    If k2 > k Then k = k2
    If k > 0 Then .Range("G3").Resize(k, 2).Value = Res
  End With
  MsgBox ("Thoi gian chay code:  " & Timer - t & "giay")
End Sub
 
Upvote 0
Dùng tạm , nếu chạy quá chậm báo lại mình viết lại toàn bộ
Mã:
Option Explicit

Sub XYZ()
  Dim Arr1(), Arr2(), Res() As String, t
  Dim i&, i2&, k&, k2&, sR1&, sR2&, sRow&, w&, ma1$, ma2$
  
  t = Timer
  With Sheet1
    Arr1 = .Range("B3", .Range("B" & Rows.Count).End(xlUp)).Value
    Arr2 = .Range("D3", .Range("D" & Rows.Count).End(xlUp)).Value
    sR1 = UBound(Arr1): sR2 = UBound(Arr2)
  End With
  If sR1 > sR2 Then sRow = sR1 Else sRow = sR2
  ReDim Res(1 To sRow, 1 To 2)

  For i = 1 To sR1
    ma1 = Arr1(i, 1)
    w = Len(ma1)
    For i2 = 1 To sR2
      ma2 = Arr2(i2, 1)
      If ma2 <> Empty Then
        If w > Len(ma2) Then
          If ma1 Like "*" & ma2 Then
            Arr2(i2, 1) = Empty
            Exit For
          End If
        Else
          If ma2 Like "*" & ma1 Then
            Arr2(i2, 1) = Empty
            Exit For
          End If
        End If
      End If
    Next i2
    If i2 = sR2 + 1 Then
      k = k + 1
      Res(k, 1) = ma1
    End If
  Next i
  For i2 = 1 To sR2
    If Arr2(i2, 1) <> Empty Then
      k2 = k2 + 1
      Res(k2, 2) = Arr2(i2, 1)
    End If
  Next i2
  With Sheet1
    i = .Range("G" & Rows.Count).End(xlUp).Row
    i2 = .Range("H" & Rows.Count).End(xlUp).Row
    If i2 > i Then i = i2
    If i > 2 Then .Range("G3").Resize(i, 2).ClearContents
    If k2 > k Then k = k2
    If k > 0 Then .Range("G3").Resize(k, 2).Value = Res
  End With
  MsgBox ("Thoi gian chay code:  " & Timer - t & "giay")
End Sub
Dạ, em cảm ơn Thầy nhiều ạ
 
Upvote 0
Web KT
Back
Top Bottom