Yêu cầu của nếu nói rõ ra là: So sánh dử liệu ở 2 listMong các anh, em trên GPE xem và hướng dẩn giúp, tìm số lượng tăng giảm công nhân hàng tháng.
Cụ thể trong file đính kèm
Option Explicit
Sub SoTangGiam()
Dim tRng As Range, sRng As Range, Clls As Range, Rng0 As Range, xRng As Range
Dim jJ As Byte
Set sRng = Range([c4], [c65500].End(xlUp))
Set tRng = Range([b4], [b65500].End(xlUp))
For jJ = 1 To 2
Set xRng = Choose(jJ, [D4], [e4])
Range(xRng, xRng.End(xlDown)).ClearContents
For Each Clls In Choose(jJ, sRng, tRng)
Set Rng0 = Choose(jJ, tRng, sRng).Find(Clls.Value, , xlFormulas, xlWhole)
If Rng0 Is Nothing Then _
Choose(jJ, [D65500], [e65500]).End(xlUp).Offset(1).Value = Clls.Value
Next Clls
Next jJ
End Sub
-----------PHP:Option Explicit Sub SoTangGiam() Dim tRng As Range, sRng As Range, Clls As Range, Rng0 As Range, xRng As Range Dim jJ As Byte Set sRng = Range([c4], [c65500].End(xlUp)) Set tRng = Range([b4], [b65500].End(xlUp)) For jJ = 1 To 2 Set xRng = Choose(jJ, [D4], [e4]) Range(xRng, xRng.End(xlDown)).ClearContents For Each Clls In Choose(jJ, sRng, tRng) Set Rng0 = Choose(jJ, tRng, sRng).Find(Clls.Value, , xlFormulas, xlWhole) If Rng0 Is Nothing Then _ Choose(jJ, [D65500], [e65500]).End(xlUp).Offset(1).Value = Clls.Value Next Clls Next jJ End Sub
Thử code này xem:-----------
Nếu được thì nhờ anh xem và sửa giúp 1 lần nửa.
Đính kèm file
Sub Compare2List()
Dim List1 As Range, List2 As Range, Cll1 As Range, Cll2 As Range
Dim Dic1, Dic2, Dic3
Set Dic1 = CreateObject("Scripting.Dictionary")
Set Dic2 = CreateObject("Scripting.Dictionary")
Set Dic3 = CreateObject("Scripting.Dictionary")
Set List1 = Range([B4], [B65536].End(xlUp))
Set List2 = Range([C4], [C65536].End(xlUp))
Range("D4:F60000").ClearContents
With Application.WorksheetFunction
For Each Cll1 In List1
If .CountIf(List2, Cll1) Then
Dic1.Add Cll1, Cll1
Else
Dic3.Add Cll1, Cll1
End If
Next Cll1
For Each Cll2 In List2
If .CountIf(List1, Cll2) = 0 Then
Dic2.Add Cll2, Cll2
End If
Next Cll2
Range("D4").Resize(Dic1.Count) = .Transpose(Dic1.Keys)
Range("E4").Resize(Dic2.Count) = .Transpose(Dic2.Keys)
Range("F4").Resize(Dic3.Count) = .Transpose(Dic3.Keys)
End With
End Sub
Vì bài trước bạn yêu cầu khác: Từ 2 list lọc ra 2 list nên sư phụ dùng hàm CHOOSE để gôm lại (cho gọn)To : NDU
Rất cám ơn sự nhiệt tình của bạn. Ý tôi là như thế này:
Code của anh ChanhTQ tôi đọc còn hiểu lờ mờ chút đỉnh, của NDU thì....mù tịt.
Bạn giúp tôi ( xin phép anh ChanhTQ trước ) thêm, sửa trên đoạn code của anh ChanhTQ để tôi: trước mắt xử dụng cho công việc, sau đó ( so sánh trước và sau ) để học, để có thể áp dụng vào việc khác ( không lẽ mỗi chút mỗi hỏi ).
Mong tin bạn.
Sub SoTangGiam()
Dim tRng As Range, sRng As Range, Clls As Range
Set tRng = Range([B4], [B65500].End(xlUp))
Set sRng = Range([C4], [C65500].End(xlUp))
Range("D4:F65000").ClearContents
For Each Clls In sRng
If tRng.Find(Clls.Value, , xlFormulas, xlWhole) Is Nothing Then
[E65500].End(xlUp).Offset(1).Value = Clls.Value
Else
[D65500].End(xlUp).Offset(1).Value = Clls.Value
End If
Next Clls
For Each Clls In tRng
If sRng.Find(Clls.Value, , xlFormulas, xlWhole) Is Nothing Then
[F65500].End(xlUp).Offset(1).Value = Clls.Value
End If
Next Clls
End Sub
Option Explicit
Sub SoTangGiam()
Dim tRng As Range, sRng As Range, Clls As Range, Rng0 As Range, xRng As Range
Dim jJ As Long
Set sRng = Range([c4], [c65500].End(xlUp))
Set tRng = Range([b4], [b65500].End(xlUp))
jJ = sRng.Rows.Count + tRng.Rows.Count
[D4].Resize(jJ, 3).ClearContents
For jJ = 1 To 2
Set xRng = Choose(jJ, [E4], [F4])
For Each Clls In Choose(jJ, sRng, tRng)
Set Rng0 = Choose(jJ, tRng, sRng).Find(Clls.Value, , xlFormulas, xlWhole)
If Rng0 Is Nothing Then
Choose(jJ, [e65500], [F65500]).End(xlUp).Offset(1).Value = Clls.Value
Else
If jJ = 1 Then _
[D65500].End(xlUp).Offset(1).Value = Clls.Value
End If
Next Clls
Next jJ
End Sub
Thật ra thuật toán của tôi và sư phụ là giống nhau, chỉ khác về chi tiết:
- Dùng Find / COUNTIF
- Khi tìm được, sư cho nó vào cell luôn (tức tìm đến đâu ra kết quả đến nấy)... Còn tôi thì cho giá trị tìm được vào Dictionary Object (như thêm từ điển vậy)... Đến cuối quá trình mới cho toàn bộ vào bảng tính
Em chắc ăn 100% vì đã thử nghiệm rồi:Chưa thực nghiệm có quyền chưa tin 'Ai nhanh hơn ai!"
Tôi vừa phát hiện ra 1 cách cực kỳ đơn giàn, dùng Advanced Filter... Bạn làm như sau:Mong các anh, em trên GPE xem và hướng dẩn giúp, tìm số lượng tăng giảm công nhân hàng tháng.
Cụ thể trong file đính kèm
=COUNTIF($C$4:$C$18,$B4)>0
=COUNTIF($B$4:$B$16,$C4)=0
=COUNTIF($C$4:$C$18,$B4)=0
Sub Compare2List()
Dim List1 As Range, List2 As Range
Dim Dk1 As Range, Dk2 As Range, Dk3 As Range
Set List1 = Range([B3], [B65536].End(xlUp))
Set List2 = Range([C3], [C65536].End(xlUp))
Set Dk1 = Range("H3:H4")
Set Dk2 = Range("I3:I4")
Set Dk3 = Range("J3:J4")
List1.AdvancedFilter 2, Dk1, [D3]
List2.AdvancedFilter 2, Dk2, [E3]
List1.AdvancedFilter 2, Dk3, [F3]
End Sub
Giải thuật dựa trên cơ sơ dử liệu thật mà ra... Vì vậy, để có được cách tính toán chính xác tôi cần dử liệu nhập của bạn, cụ thể phải có những trường hợp đặc biệt như bạn vừa nói trong file ---> Từ đó nghiên cứu và tìm giải thuật chính xác!Trích NDU:
Tôi vừa phát hiện ra 1 cách cực kỳ đơn giàn, dùng Advanced Filter...
Rất trân trọng ý kiến của bạn .
Còn tôi cũng vừa phát hiện ra 1 lỗi cũng cực kỳ đơn giản:
- Trong trường hợp số thẻ (ST) vừa tăng, xong rồi lại giảm trong cùng 1 kỳ. Cụ thể là ST vào ngày 2, nghĩ vào ngày 20 chẳng hạn thì làm gì có trong bảng lương tháng ?
- Ghi chú:
* Lương nghỉ việc thanh toán 1 tháng 2 lần vào các ngày 15 và 2
* Lương bình thường vào ngày 5 của tháng sau
* ST : được đánh liên tục từ thấp đến cao.
Bạn có cao kiến gì không ? ( mời bạn uống cafe nhé )
--------Giải thuật dựa trên cơ sơ dử liệu thật mà ra... Vì vậy, để có được cách tính toán chính xác tôi cần dử liệu nhập của bạn, cụ thể phải có những trường hợp đặc biệt như bạn vừa nói trong file ---> Từ đó nghiên cứu và tìm giải thuật chính xác!
Theo như những gì bạn trình bày trong file thì:--------
Đã soát, xét lại quá trình nhập liệu.Nhờ các anh em GPE xem giúp ( lại phiền đến NDU)
Đính kèm file ( lần thứ 3 )
Sub Compare2List()
Dim List1 As Range, List2 As Range, List3 As Range
Dim Cll1 As Range, Cll2 As Range, Dic1, Dic2
On Error Resume Next
Set Dic1 = CreateObject("Scripting.Dictionary")
Set Dic2 = CreateObject("Scripting.Dictionary")
Set List1 = Range([B4], [B65536].End(xlUp))
Set List2 = Range([C4], [C65536].End(xlUp))
Set List3 = Range([D4], [D65536].End(xlUp))
Range("E4:G60000").ClearContents
With Application
For Each Cll1 In List1.SpecialCells(2)
If .CountIf(List2, Cll1) Then Dic1.Add Cll1, Cll1
Next Cll1
For Each Cll2 In List2.SpecialCells(2)
If .CountIf(List1, Cll2) = 0 Then Dic2.Add Cll2, Cll2
Next Cll2
Range("E4").Resize(Dic1.Count) = .Transpose(Dic1.Keys)
Range("F4").Resize(Dic2.Count) = .Transpose(Dic2.Keys)
List3.SpecialCells(2).Copy: Range("G4").PasteSpecial 3
.CutCopyMode = False
End With
End Sub
Vâng! Không có gì đâu bạn à, vì trước đây tôi cũng vậy thôi: Chỉ áp dụng cái nào ta hiểu được, cái gì không hiểu sẽ không áp dụng... Ẹc... Ẹc...To: NDU
Có gì không phải thì RẤT MONG bạn bỏ qua.
Tôi xin nói thẳng : tôi là dân học kế toán, học excel cùa các trung tâm ( Biên Hòa ) được 1 tháng, Code trước của bạn dùng 2 vòng lặp thì tôi hiểu được ít nhiều ( rất quý ), bạn tuần tự thì tôi theo được ( dù rằng code có chậm nhưng tôi vẫn thích, tôi chấp nhận tôi dốt, nhưng tôi hiểu vấn đề), bạn cao quá thì tôi thua (đọc không nổi ), bạn viết tầm tầm thôi để tôi còn thở, bạn có thể xử dụng hàm find để giải quyết vấn đề này được không ?
Trích:
- Ta chỉ cần tìm những số thể ổn định và số thẻ tăng => chính xác
- Số thẻ giảm chính là cột D (số thể nghỉ việc) => Chính xác, nhưng có thể sắp xếp cùng 1 Số thẻ thì cùng 1 dòng được không bạn nhỉ ( như trong file đính kèm, vì việc này liên quan đến phân tích dữ liệu : lý do tại sao vừa nhận việc lại nghĩ..., từ số thẻ còn liên quan đến các tổ, mức độ ổn định của các tổ sản xuất ....)
Tôi thật sự rất trân trọng sự nhiệt tình của bạn và anh ChanhTQ@, không phải diển đàn nào cũng có được những thành viên như thế.
Có gì không phải thì RẤT MONG bạn bỏ qua.
Nếu vậy thật sự quá đơn giản nếu ta dùng công thức:nhưng có thể sắp xếp cùng 1 Số thẻ thì cùng 1 dòng được không bạn nhỉ
E4 =IF(COUNTA(B4:C4)=2,B4,"")
F4 =IF(AND(B4="",C4<>""),C4,"")
G4 =IF(D4="","",D4)
Vậy chắc nhà bạn ở Biên Hòa?Tôi xin nói thẳng : tôi là dân học kế toán, học excel cùa các trung tâm ( Biên Hòa )
Tôi đã hiểu ý bạn rồi ---> Mấu chốt nằm ở chổ các số thẻ giống nhau nằm trên 1 hàng, vì thế mà tôi đưa ra công thứcVậy chắc nhà bạn ở Biên Hòa?
Đúng vậy, tôi dân BH,ở BH, không biết NDU ở đâu ?
Tôi đã kiểm tra code của NDU, chắc có lẻ do tôi trình bày trong file không được rỏ ràng nên code NDU viết kết quả không được như mong muốn. Các số thẻ vừa tăng, vừa giảm chỉ ra được kết quả giảm mà không có tăng ( khi có kết quả thì có thể sắp xếp những trường hợp này cùng 1 dòng được không ?)
Đính kèm file
Sub Test()
With Range([C4], [C65536].End(xlUp))
.Offset(, 2).Value = "=IF(COUNTA(RC[-3]:RC[-2])=2,RC[-3],"""")"
.Offset(, 3).Value = "=IF(AND(RC[-4]="""",RC[-3]<>""""),RC[-3],IF(AND(RC[-4]="""",RC[-2]<>""""),RC[-2],""""))"
.Offset(, 4).Value = "=IF(RC[-3]="""","""",RC[-3])"
With .Offset(, 2).Resize(, 3)
.Value = .Value
End With
End With
End Sub
NDU ở phường nào ? Sao lại có thể uống cafe ? , bình thường thôi(Tôi cũng ở Biên Hòa luôn ---> Có thể uống cafe được đấy... ẹc... ẹc...)