Tìm kiếm và so sánh 2 cột dữ liệu theo điều kiện

Liên hệ QC

Excel-newbie

Thành viên mới
Tham gia
24/5/21
Bài viết
3
Được thích
1
Xin chào mọi người,

Mình có một file excel như sau: cột ngày sản xuất, cột mã khách hàng, cột số thứ tự cont theo mã khách hàng. Yêu cầu kiểm tra số thứ tự cont theo một khách hàng nào đó với điều kiện cont sau phải có ngày sản xuất lớn hơn ngày sản xuất của cont trước. VD: ngày sản xuất của cont số 9 của khách hàng HAC phải sau ngày sản xuất của cont số 8 của khách hàng HAC đó. (Lưu ý giúp trường hợp có số cont của một khách hàng giống nhau nhưng khác ngày sản xuất vẫn cần phải kiểm tra để chắc chắn số thứ tự cont của khách hàng đó phù hợp với ngày sản xuất. Nghĩa là cont có số thứ tự nhỏ hơn phải được sản xuất trước.)

Nhờ mọi người giúp đỡ.
Xin cảm ơn
 

File đính kèm

  • Kiểm tra số cont.xlsx
    14.9 KB · Đọc: 18
Dùng countif kiểm tra, đếm các dòng có cùng mã KH:
+ Ngày lớn hơn nhưng mã nhỏ hơn hoặc bằng
+ Ngày nhỏ hơn nhưng mã lớn hơn hoặc bằng
Công thức tại ô G6 kéo xuống:
=IF(C6="","",COUNTIFS($D$6:$D$199,D6,$C$6:$C$199,">"&C6,$E$6:$E$199,"<="&E6)+COUNTIFS($D$6:$D$199,D6,$C$6:$C$199,"<"&C6,$E$6:$E$199,">="&E6))
Filter cột G để lọc
 

File đính kèm

  • Kiểm tra số cont.xlsx
    16.9 KB · Đọc: 5
Xin chào mọi người,

Mình có một file excel như sau: cột ngày sản xuất, cột mã khách hàng, cột số thứ tự cont theo mã khách hàng. Yêu cầu kiểm tra số thứ tự cont theo một khách hàng nào đó với điều kiện cont sau phải có ngày sản xuất lớn hơn ngày sản xuất của cont trước. VD: ngày sản xuất của cont số 9 của khách hàng HAC phải sau ngày sản xuất của cont số 8 của khách hàng HAC đó. (Lưu ý giúp trường hợp có số cont của một khách hàng giống nhau nhưng khác ngày sản xuất vẫn cần phải kiểm tra để chắc chắn số thứ tự cont của khách hàng đó phù hợp với ngày sản xuất. Nghĩa là cont có số thứ tự nhỏ hơn phải được sản xuất trước.)

Nhờ mọi người giúp đỡ.
Xin cảm ơn
Thử cách này xem sao.
Code tự thấy cũng chưa được chuẩn cho lắm. mong anh chị em trên diễn đàn cho nhiều góp ý để hoàn thiện tốt hơn.
Hãy Sort dữ liệu (cột C) trươc khi chạy code nhé.
 

File đính kèm

  • Kiểm tra số cont.xlsm
    27.1 KB · Đọc: 4
Nên bình tĩnh, tránh trường hợp người được giúp ngộ nhận VBA khi nào cũng là ưu việt.
Cảm ơn anh đã nhắc nhở. tôi có suy nghĩ rằng: mình cứ giúp đỡ cho người khác bằng cái mình có thể làm được, cùng nhiều cách khác của các bạn trên diễn đàn để cho người được giúp có nhiều lựa chon thôi mà. Hơn nữa cũng là đang muốn học hỏi thêm về VBA. như tôi đã nói: " Code tự thấy cũng chưa được chuẩn cho lắm. Mong anh chị em trên diễn đàn cho nhiều góp ý để hoàn thiện tốt hơn." kia mà.
Tôi thuộc dạng gà mờ về VBA Excel nên cũng không có nhiều kiến thức về VBA để tranh luận về sức mạnh của VBA. nhưng tôi nghĩ là đối vói nhũng bài mà dữ liệu lớn (nhiều dòng nhiều cột) thì giải quyết bàng VBa sẽ nhẹ nhàng hơn dùng công thức
 
Thử cách này xem sao.
Code tự thấy cũng chưa được chuẩn cho lắm. mong anh chị em trên diễn đàn cho nhiều góp ý để hoàn thiện tốt hơn.
Hãy Sort dữ liệu (cột C) trươc khi chạy code nhé.
Gởi bạn 3 code với số lần chạy vòng for khác nhau
Mã:
Option Explicit
Sub XYZ2()
  Dim sArr(), S, Res(), tmp$, sRow&, i&, r&, k&
 
  With Sheet1
    sArr = .Range("C6", .Cells(Rows.Count, "D").End(xlUp)).Value
  End With
  sRow = UBound(sArr)
  ReDim Res(1 To sRow, 1 To 1)
  For i = 1 To sRow
    tmp = sArr(i, 2)
    If tmp <> Empty Then
      For r = 1 To sRow
        If sArr(r, 2) = tmp Then
          If r <= i Then
            If sArr(i, 1) >= sArr(r, 1) Then Res(i, 1) = Res(i, 1) + 1
          Else
            If sArr(i, 1) > sArr(r, 1) Then Res(i, 1) = Res(i, 1) + 1
          End If
        End If
        k = k + 1 'Dem so lan vòng lap
      Next r
    End If
  Next i
  For i = 1 To sRow
    If Res(i, 1) <> Empty Then Res(i, 1) = Format(Res(i, 1), "000") & sArr(i, 2)
  Next i
  Sheet1.Range("H6").Resize(sRow).Value = Res
  MsgBox "So Lan: " & k
End Sub

Sub XYZ3()
  Dim sArr(), S, Res(), tmp$, sRow&, i&, r&, k&
 
  With Sheet1
    sArr = .Range("C6", .Cells(Rows.Count, "D").End(xlUp)).Value
  End With
  sRow = UBound(sArr)
  ReDim Res(1 To sRow, 1 To 1)
  For i = 1 To sRow - 1
    tmp = sArr(i, 2)
    If tmp <> Empty Then
      Res(i, 1) = Res(i, 1) + 1
      For r = i + 1 To sRow
        If sArr(r, 2) = tmp Then
          If sArr(i, 1) > sArr(r, 1) Then
            Res(i, 1) = Res(i, 1) + 1
          Else
            Res(r, 1) = Res(r, 1) + 1
          End If
        End If
        k = k + 1 'Dem so lan vòng lap
      Next r
    End If
  Next i
  Res(sRow, 1) = Res(sRow, 1) + 1
  For i = 1 To sRow
    If Res(i, 1) <> Empty Then Res(i, 1) = Format(Res(i, 1), "000") & sArr(i, 2)
  Next i
  Sheet1.Range("I6").Resize(sRow).Value = Res
  MsgBox "So Lan: " & k
End Sub

Sub XYZ()
  Dim dic As Object, sArr(), S, Res(), tmp, sRow&, i&, j&, k&
 
  Set dic = CreateObject("scripting.dictionary")
  With Sheet1
    sArr = .Range("C6", .Cells(Rows.Count, "D").End(xlUp)).Value
  End With
  sRow = UBound(sArr)
  ReDim Res(1 To sRow, 1 To 1)
  For i = 1 To sRow
    If sArr(i, 2) <> Empty Then
      Res(i, 1) = 1
      dic.Item(sArr(i, 2)) = dic.Item(sArr(i, 2)) & "," & i
      k = k + 1 'Dem so lan vòng lap
    End If
  Next i
  For Each tmp In dic.items
    S = Split(tmp, ",")
    For j = 1 To UBound(S) - 1
      For i = j + 1 To UBound(S)
        If sArr(S(j), 1) > sArr(S(i), 1) Then
          Res(S(j), 1) = Res(S(j), 1) + 1
        Else
          Res(S(i), 1) = Res(S(i), 1) + 1
        End If
        k = k + 1 'Dem so lan vòng lap
      Next i
    Next j
  Next tmp
  For i = 1 To sRow
    If Res(i, 1) <> Empty Then Res(i, 1) = Format(Res(i, 1), "000") & sArr(i, 2)
  Next i
  Sheet1.Range("G6").Resize(sRow).Value = Res
  MsgBox "So Lan: " & k
End Sub
 
Dùng countif kiểm tra, đếm các dòng có cùng mã KH:
+ Ngày lớn hơn nhưng mã nhỏ hơn hoặc bằng
+ Ngày nhỏ hơn nhưng mã lớn hơn hoặc bằng
Công thức tại ô G6 kéo xuống:
=IF(C6="","",COUNTIFS($D$6:$D$199,D6,$C$6:$C$199,">"&C6,$E$6:$E$199,"<="&E6)+COUNTIFS($D$6:$D$199,D6,$C$6:$C$199,"<"&C6,$E$6:$E$199,">="&E6))
Filter cột G để lọc
Xin cám ơn bác bebo02199 đã hỗ trợ, tuy nhiên có thể do mình đặt yêu cầu chưa rõ ràng nên câu trả lời chưa sát với yêu cầu. Mình sẽ lấy luôn ví dụ từ trong file đính kèm để giải thích cho cụ thể hơn.
Theo file đính kèm số thứ tự của cont gần đây nhất của khách hàng HAC là 69 có ngày sản xuất là 22/05/2021. Giả sử mình nhập thêm dữ liệu cho khách hàng HAC này với số cont là 70 và một ngày sản xuất mới. Điều mình cần phải làm là kiểm tra xem ngày sản xuất của cont thứ 70 này có lớn hơn ngày sản xuất của cont 69 không? (nếu lớn hơn là phù hợp vì quy định là ngày sản xuất của cont thứ n+1 phải lớn hơn ngày sản xuất của cont thứ n)-Cái này có thể làm thủ công bằng cách lọc mã HAC ra để kiểm tra. Tuy nhiên mình muốn mọi người giúp cho một công thức hay đoạn code VBE để khi nhập dữ liệu vào thì excel sẽ kiểm tra và thông báo luôn.
Cám ơn mọi người.
 
Vậy tự động gán số cont luôn đi được không?
VD: Khi nhập ngày SX và mã KH xong, dùng công thức cộng thêm 1 và STT?
 
Xin chào mọi người,

Mình có một file excel như sau: cột ngày sản xuất, cột mã khách hàng, cột số thứ tự cont theo mã khách hàng. Yêu cầu kiểm tra số thứ tự cont theo một khách hàng nào đó với điều kiện cont sau phải có ngày sản xuất lớn hơn ngày sản xuất của cont trước. VD: ngày sản xuất của cont số 9 của khách hàng HAC phải sau ngày sản xuất của cont số 8 của khách hàng HAC đó. (Lưu ý giúp trường hợp có số cont của một khách hàng giống nhau nhưng khác ngày sản xuất vẫn cần phải kiểm tra để chắc chắn số thứ tự cont của khách hàng đó phù hợp với ngày sản xuất. Nghĩa là cont có số thứ tự nhỏ hơn phải được sản xuất trước.)

Nhờ mọi người giúp đỡ.
Xin cảm ơn
Cứ đơn giản thêm cột phụ để tìm mã cont liền trước, ngày sản xuất của mã cont liền trước rồi so sánh thôi
 

File đính kèm

  • Kiểm tra số cont.xlsx
    21.1 KB · Đọc: 8
Vậy tự động gán số cont luôn đi được không?
VD: Khi nhập ngày SX và mã KH xong, dùng công thức cộng thêm 1 và STT?
Cám ơn bác nhưng mình chỉ nhận một mã bao gồm số cont, mã khách hàng và ngày sản xuất. Nhiệm vụ của mình là nhập số đó và kiểm tra xem số cont có phù hợp với ngày sản xuất hay không mà thôi. Có lẽ làm như pta289 là đã đáp ứng được yêu cầu. Thực ra khi làm mình cũng có ý tưởng như Pta289 nhưng do không tìm ngày theo cột G nên làm không ra.
 
Gởi bạn 3 code với số lần chạy vòng for khác nhau
Cảm ơn anh đã chỉ giáo. Trân trọng những kiến thức mà anh đã chia sẻ.
Code của tôi khi chạy thử tôi cũng không kiểm tra kỹ và có cảm giác vẫn chưa đúng thế nên mới nói là :" Code tự thấy cũng chưa được chuẩn cho lắm. Mong anh chị em trên diễn đàn cho nhiều góp ý để hoàn thiện tốt hơn."
Cái đoạn
For Each tmp In dic.items
S = Split(tmp, ",")
For j = 1 To UBound(S) - 1
For i = j + 1 To UBound(S)
If sArr(S(j), 1) > sArr(S(i), 1) Then
của anh tôi thực sự không hiểu lắm. Nếu có thể anh chú dẫn cho tôi hiểu được không?
Trân trọng
 
Lần chỉnh sửa cuối:
Cảm ơn anh đã chỉ giáo. Trân trọng những kiến thức mà anh đã chia sẻ.
Code của tôi khi chạy thử tôi cũng không kiểm tra kỹ và có cảm giác vẫn chưa đúng thế nên mới nói là :" Code tự thấy cũng chưa được chuẩn cho lắm. Mong anh chị em trên diễn đàn cho nhiều góp ý để hoàn thiện tốt hơn."
Cái đoạn
For Each tmp In dic.items
S = Split(tmp, ",")
For j = 1 To UBound(S) - 1
For i = j + 1 To UBound(S)
If sArr(S(j), 1) > sArr(S(i), 1) Then
của anh tôi thực sự không hiểu lắm. Nếu có thể anh chú dẫn cho tôi hiểu được không?
Trân trọng
dic.Item(sArr(i, 2)) = dic.Item(sArr(i, 2)) & "," & i : iTem cua dic là các thứ tự dòng ngăn cách bằng "," của từng mã khách hàng
For Each tmp In dic.items 'tmp: Lấy từng iTem của dic
S = Split(tmp, ",") ' mảng các thứ tự dòng của từng mã khách hàng

các lệnh còn lại giống như code XYZ3
Mã:
  For i = 1 To sRow - 1
    tmp = sArr(i, 2)
    If tmp <> Empty Then
      Res(i, 1) = Res(i, 1) + 1
      For r = i + 1 To sRow
        If sArr(r, 2) = tmp Then
          If sArr(i, 1) > sArr(r, 1) Then
            Res(i, 1) = Res(i, 1) + 1
          Else
            Res(r, 1) = Res(r, 1) + 1
          End If
        End If
        k = k + 1 'Dem so lan vòng lap
      Next r
    End If
  Next i
 
dic.Item(sArr(i, 2)) = dic.Item(sArr(i, 2)) & "," & i : iTem cua dic là các thứ tự dòng ngăn cách bằng "," của từng mã khách hàng
For Each tmp In dic.items 'tmp: Lấy từng iTem của dic
S = Split(tmp, ",") ' mảng các thứ tự dòng của từng mã khách hàng
Đã giải tỏa được phần nào. Có gì sẽ tìm hiểu sau, nếu còn có thắc mặc gì cũng mong anh tận tình giúp đỡ.
Cảm ơn anh. chúc anh khỏe & vui.
 
Web KT
Back
Top Bottom