So sánh giữa hai cột bằng VBA (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

thao nguyen01

Thành viên thường trực
Tham gia
8/12/19
Bài viết
252
Được thích
33
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

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

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

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

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

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
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 ạ.
Vì dữ liệu "lệch dòng", tức là không thể đoan chắc khi nào 1 phần tử bên mảng kia khớp với 1 phần tử bên mảng này nên phải dò đến khi nào KHÔNG KHỚP mới thôi. Đó là do tôi nghĩ vậy nên giải thuật có thể gây tốn thời gian. Chủ thớt cũng nên cân nhắc đánh giá.

P/S: tôi không dám nói gì nhưng với yêu cầu của chủ thớt, cả 2 cột dữ liệu đều có khả năng lạc mã và phải dò tìm, thì kết quả của bài #19 thế này, thớt xem thử;
1610790982624.png
 
Lần chỉnh sửa cuối:
Upvote 0
Vì dữ liệu "lệch dòng", tức là không thể đoan chắc khi nào 1 phần tử bên mảng kia khớp với 1 phần tử bên mảng này nên phải dò đến khi nào KHÔNG KHỚP mới thôi. Đó là do tôi nghĩ vậy nên giải thuật có thể gây tốn thời gian. Chủ thớt cũng nên cân nhắc đánh giá.
Dạ. Em cảm ơn nhiều ạ.
 
Upvote 0
Nếu tốc độ là điều cần thiết thì:

1. viết vòng lặp như thế nào để nếu có thể thì chấm dứt sớm, trước khi biến đếm vượt giới hạn cận trên (chấm dứt tự nhiên).

2. so chuỗi bằng hàm Instr thay cho toán tử Like

Riêng bài này thì nên Sort là tót nhất.
 
Upvote 0
Vì dữ liệu "lệch dòng", tức là không thể đoan chắc khi nào 1 phần tử bên mảng kia khớp với 1 phần tử bên mảng này nên phải dò đến khi nào KHÔNG KHỚP mới thôi. Đó là do tôi nghĩ vậy nên giải thuật có thể gây tốn thời gian. Chủ thớt cũng nên cân nhắc đánh giá.

P/S: tôi không dám nói gì nhưng với yêu cầu của chủ thớt, cả 2 cột dữ liệu đều có khả năng lạc mã và phải dò tìm, thì kết quả của bài #19 thế này, thớt xem thử;
View attachment 253093
Dạ, em mới xem kết quả lại nếu dùng code của anh thì không có kết quả của "Z9L3875644" và "Z9L3875644Z" vì thực tế giống nhau. Khi em kiểm tra dữ liệu của anh, em mới thấy ạ. Vì dữ liệu của em đưa ra là dạng *ABC nên em không thấy trường hợp này khi em xem code bài #19. Code của anh là dạng *ABC* ạ.
 
Upvote 0
Đính chính cho bài #23: sort là giải thuật không đúng !
Ở bài #23, tôi nói "bài này nên sort" là hơi hấp tấp. Sau khi phân tích lại, tôi nhận ra nếu so sánh *abc = abc thì sort chả có công dụng gì cả.
 
Upvote 0
Dạ, dữ liệu thật khoảng 10000 dòng ạ.
Code với vài trăm nghìn dòng
Mã:
Sub XYZ()
  Dim Arr(), Arr2(), Res() As String, t
  Dim i&, i2&, k&, k2&, sR&, sR2&, sRow&, ma$, ma2$
    
  t = Timer
  With Sheet1
    Arr = .Range("B3", .Range("B" & Rows.Count).End(xlUp)).Value
    Arr2 = .Range("D3", .Range("D" & Rows.Count).End(xlUp)).Value
  End With
  Call SortArrayList(Arr, Arr)
  Call SortArrayList(Arr2, Arr2)
  sR = UBound(Arr): sR2 = UBound(Arr2)
  If sR > sR2 Then sRow = sR Else sRow = sR2
  ReDim Res(1 To sRow, 1 To 2)
 
  i = 1: i2 = 1
  ma = Arr(i, 1): ma2 = Arr2(i2, 1)
  Do
    If ma Like ma2 & "*" Or ma2 Like ma & "*" Then
      Arr(i, 1) = Empty: Arr2(i2, 1) = Empty
      If i = sR Or i2 = sR2 Then Exit Do
      i = i + 1: i2 = i2 + 1
      ma = Arr(i, 1): ma2 = Arr2(i2, 1)
    Else
      If ma > ma2 Then
        If i2 = sR2 Then Exit Do
        i2 = i2 + 1: ma2 = Arr2(i2, 1)
      Else
        If i = sR Then Exit Do
        i = i + 1: ma = Arr(i, 1)
      End If
    End If
  Loop
 
  For i = 1 To sR
    If Arr(i, 1) <> Empty Then
      k = k + 1
      Res(k, 1) = StrReverse(Arr(i, 1))
    End If
  Next i
  For i2 = 1 To sR2
    If Arr2(i2, 1) <> Empty Then
      k2 = k2 + 1
      Res(k2, 2) = StrReverse(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("F3").Resize(k, 2).Value = Res
  End With
  MsgBox ("Thoi gian chay code:  " & Timer - t & "giay")
 End Sub
 
 Private Sub SortArrayList(ByRef ResSort As Variant, ByVal sArrSort As Variant)
  Dim oArrList As Object, iKey$, i&, k&, fRow&, eRow&

  Set oArrList = CreateObject("System.Collections.ArrayList")
  fRow = LBound(sArrSort, 1): eRow = UBound(sArrSort, 1)
  ReDim ResSort(1 To eRow - fRow + 1, 1 To 1)
  For i = fRow To eRow
    iKey = sArrSort(i, 1)
    'If iKey <> Empty Then oArrList.Add iKey
    If iKey <> Empty Then oArrList.Add StrReverse(iKey)
  Next i
  oArrList.Sort
  eRow = oArrList.Count - 1
  For i = 0 To eRow
    k = k + 1
    ResSort(k, 1) = oArrList.Item(i)
  Next i
  Set oArrList = Nothing
End Sub
 
Upvote 0
Code với vài trăm nghìn dòng
Mã:
Sub XYZ()
  Dim Arr(), Arr2(), Res() As String, t
  Dim i&, i2&, k&, k2&, sR&, sR2&, sRow&, ma$, ma2$
   
  t = Timer
  With Sheet1
    Arr = .Range("B3", .Range("B" & Rows.Count).End(xlUp)).Value
    Arr2 = .Range("D3", .Range("D" & Rows.Count).End(xlUp)).Value
  End With
  Call SortArrayList(Arr, Arr)
  Call SortArrayList(Arr2, Arr2)
  sR = UBound(Arr): sR2 = UBound(Arr2)
  If sR > sR2 Then sRow = sR Else sRow = sR2
  ReDim Res(1 To sRow, 1 To 2)

  i = 1: i2 = 1
  ma = Arr(i, 1): ma2 = Arr2(i2, 1)
  Do
    If ma Like ma2 & "*" Or ma2 Like ma & "*" Then
      Arr(i, 1) = Empty: Arr2(i2, 1) = Empty
      If i = sR Or i2 = sR2 Then Exit Do
      i = i + 1: i2 = i2 + 1
      ma = Arr(i, 1): ma2 = Arr2(i2, 1)
    Else
      If ma > ma2 Then
        If i2 = sR2 Then Exit Do
        i2 = i2 + 1: ma2 = Arr2(i2, 1)
      Else
        If i = sR Then Exit Do
        i = i + 1: ma = Arr(i, 1)
      End If
    End If
  Loop

  For i = 1 To sR
    If Arr(i, 1) <> Empty Then
      k = k + 1
      Res(k, 1) = StrReverse(Arr(i, 1))
    End If
  Next i
  For i2 = 1 To sR2
    If Arr2(i2, 1) <> Empty Then
      k2 = k2 + 1
      Res(k2, 2) = StrReverse(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("F3").Resize(k, 2).Value = Res
  End With
  MsgBox ("Thoi gian chay code:  " & Timer - t & "giay")
End Sub

Private Sub SortArrayList(ByRef ResSort As Variant, ByVal sArrSort As Variant)
  Dim oArrList As Object, iKey$, i&, k&, fRow&, eRow&

  Set oArrList = CreateObject("System.Collections.ArrayList")
  fRow = LBound(sArrSort, 1): eRow = UBound(sArrSort, 1)
  ReDim ResSort(1 To eRow - fRow + 1, 1 To 1)
  For i = fRow To eRow
    iKey = sArrSort(i, 1)
    'If iKey <> Empty Then oArrList.Add iKey
    If iKey <> Empty Then oArrList.Add StrReverse(iKey)
  Next i
  oArrList.Sort
  eRow = oArrList.Count - 1
  For i = 0 To eRow
    k = k + 1
    ResSort(k, 1) = oArrList.Item(i)
  Next i
  Set oArrList = Nothing
End Sub
Dạ, em cảm ơn Thầy nhiều ạ
 
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)
Bạn thử code này xem coi thế nào. Đã thử chạy với dữ liệu 100 000 dòng, tốc độ khoảng 3 giây trên máy của mình
Lưu ý: theo mô tả của bạn thì dữ liệu có dạng *1234567, nên nếu cần thiết thì hãy thay NumOfStr=7 thành 8, hay 9 ... cho phù hợp thực tế
Code này không có xóa kết quả trước đó, hãy xóa thủ công trước khi chạy code
Nếu code không phù hợp yêu cầucủa bạn, hãy coi như tham khảo thuật toán nhé

Mã:
Sub So_Sanh()
Dim sArr1(), sArr2(), i As Long, tmp As String, k As Long, kk As Long
Dim sh As Worksheet, Res1(), Res2(), NumOfStr As Long
Dim Dic1 As Object, Dic2 As Object
Set Dic1 = CreateObject("scripting.dictionary")
Set Dic2 = CreateObject("scripting.dictionary")
Set sh = Sheets("Sheet1")
NumOfStr = 7
sArr1 = sh.Range("B3", sh.Range("B" & Rows.Count).End(3)).Value
sArr2 = sh.Range("D3", sh.Range("D" & Rows.Count).End(3)).Value
ReDim Res1(1 To UBound(sArr2), 1 To 1)
ReDim Res2(1 To UBound(sArr1), 1 To 1)
For i = 1 To UBound(sArr1)
   tmp = Right(UCase(sArr1(i, 1)), NumOfStr)
   Dic1(tmp) = Empty
Next
For i = 1 To UBound(sArr2)
   tmp = Right(UCase(sArr2(i, 1)), NumOfStr)
   Dic2(tmp) = Empty
Next
For i = 1 To UBound(sArr1)
   tmp = Right(UCase(sArr1(i, 1)), NumOfStr)
   If Not Dic2.exists(tmp) Then
      k = k + 1
      Res1(k, 1) = sArr1(i, 1)
   End If
Next
For i = 1 To UBound(sArr2)
   tmp = Right(UCase(sArr2(i, 1)), NumOfStr)
   If Not Dic1.exists(tmp) Then
      kk = kk + 1
      Res2(kk, 1) = sArr2(i, 1)
   End If
Next
If k Then sh.[G3].Resize(k) = Res1
If kk Then sh.[H3].Resize(kk) = Res2
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Bạn thử code này xem coi thế nào. Đã thử chạy với dữ liệu 100 000 dòng, tốc độ khoảng 3 giây trên máy của mình
Lưu ý: theo mô tả của bạn thì dữ liệu có dạng *1234567, nên nếu cần thiết thì hãy thay NumOfStr=7 thành 8, hay 9 ... cho phù hợp thực tế
Code này không có xóa kết quả trước đó, hãy xóa thủ công trước khi chạy code
Nếu code không phù hợp yêu cầucủa bạn, hãy coi như tham khảo thuật toán nhé

Mã:
Sub So_Sanh()
Dim sArr1(), sArr2(), i As Long, tmp As String, k As Long, kk As Long
Dim sh As Worksheet, Res1(), Res2(), NumOfStr As Long
Dim Dic1 As Object, Dic2 As Object
Set Dic1 = CreateObject("scripting.dictionary")
Set Dic2 = CreateObject("scripting.dictionary")
Set sh = Sheets("Sheet1")
NumOfStr = 7
sArr1 = sh.Range("B3", sh.Range("B" & Rows.Count).End(3)).Value
sArr2 = sh.Range("D3", sh.Range("D" & Rows.Count).End(3)).Value
ReDim Res1(1 To UBound(sArr2), 1 To 1)
ReDim Res2(1 To UBound(sArr1), 1 To 1)
For i = 1 To UBound(sArr1)
   tmp = Right(UCase(sArr1(i, 1)), NumOfStr)
   Dic1(tmp) = Empty
Next
For i = 1 To UBound(sArr2)
   tmp = Right(UCase(sArr2(i, 1)), NumOfStr)
   Dic2(tmp) = Empty
Next
For i = 1 To UBound(sArr1)
   tmp = Right(UCase(sArr1(i, 1)), NumOfStr)
   If Not Dic2.exists(tmp) Then
      k = k + 1
      Res1(k, 1) = sArr1(i, 1)
   End If
Next
For i = 1 To UBound(sArr2)
   tmp = Right(UCase(sArr2(i, 1)), NumOfStr)
   If Not Dic1.exists(tmp) Then
      kk = kk + 1
      Res2(kk, 1) = sArr2(i, 1)
   End If
Next
If k Then sh.[G3].Resize(k) = Res1
If kk Then sh.[H3].Resize(kk) = Res2
End Sub
Dạ, kết quả ra đúng ạ. Em cảm ơn anh nhiều ạ.
 
Upvote 0

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

Back
Top Bottom