Giúp sửa code: Fương thức Find để nó không Paste lên dữ liệu cũ!
Em chào Thầy cô & anh chị!
Em viết code như sau:
Tại Sheet TH, lấy tên khách hàng ở cột G, Tìm tại Cột BE của Sheet MA, nếu tìm được thì lấy qua một cột (Cột BF) và gán nó vào Cột AG của Sheet TH tại dòng tương ứng.Ví dụ: Tại dòng thứ 9 của Sheet TH, Cell G9 không có Tên khách hàng, Cell AG9 đã có sẵn Mã KH, khi chạy code nó làm mất Mã KH tại cell AG9!!!. Em muốn sửa code, nếu KHÔNG CÓ TÊN KHÁCH HÀNG TẠI CỘT G THÌ KHÔNG ĐƯỢC XÓA MÃ KH ĐÃ CÓ TẠI CỘT AG
Xin xem chi tiết trong File
Code của emSub TimMaKH()
Dim i As Long
Dim arrRes, arrSrc
Dim n1 As Range, rTmp As Range
With ActiveSheet
arrSrc = .Range(., ..End(3)).Resize(, 27).Value
End With
With Sheets("MA")
Set n1 = .Range(., ..End(3))
End With
ReDim arrRes(1 To UBound(arrSrc, 1), 1 To 1)
For i = 1 To UBound(arrSrc, 1)
Set rTmp = n1.Find(arrSrc(i, 1), , xlValues, xlWhole)
If Not rTmp Is Nothing Then
'If arrSrc(i, 1) <> "" Then
arrRes(i, 1) = rTmp.Offset(, 1)
'End If
End If
Next i
ActiveSheet.Range("AG9").Resize(UBound(arrRes, 1)).Value = arrRes
End SubEm xin cảm ơn!
———–
Em thấy code trên, nếu Sheet TH dữ liệu nhiều thì chạy chậm, Có thể giúp em cải tiến code
Thử với code này xem, hổng biết dữ liệu nhiều nó chạy bao lâu.
Public Sub GPE()
Dim Rng As Range, Cll As Range, Arr(), Dic As Object, I As Long
Set Dic = CreateObject("Scripting.Dictionary")
With Sheets("Ma")
Arr = .Range(., ..End(xlUp)).Resize(, 2).Value
End With
For I = 1 To UBound(Arr, 1)
If Not Dic.Exists(Arr(I, 1)) Then Dic.Add Arr(I, 1), Arr(I, 2)
Next I
With Sheets("TH")
Set Rng = .Range(., ..End(xlUp))
For Each Cll In Rng
If Cll <> "" Then
If Dic.Exists(Cll.Value) Then
Cll.Offset(, 26).Value = Dic.Item(Cll.Value)
End If
End If
Next
End With
Set Dic = Nothing
Set Rng = Nothing
End Sub
www.giaiphapexcel.com/diendan/threads/gi%C3%BAp-s%E1%BB%ADa-code-f%C6%B0%C6%A1ng-th%E1%BB%A9c-find-%C4%91%E1%BB%83-n%C3%B3-kh%C3%B4ng-paste-l%C3%AAn-d%E1%BB%AF-li%E1%BB%87u-c%C5%A9.76186/
Đã trót viết rồi cũng mạo muội đưa lên dù chậm hơn bác Bate
Sub gpe() Dim i As Long, Arr, ArrKH ArrKH = Sheets("Ma").Range("BE11:BF" & Sheets("ma").Range("BE65536").End(3).Row) Arr = Sheets("TH").Range("G9:AG" & Sheets("th").Range("G65536").End(3).Row) With CreateObject("scripting.dictionary") For i = 1 To UBound(ArrKH, 1) If Not .exists(ArrKH(i, 1)) Then .Add ArrKH(i, 1), ArrKH(i, 2) End If Next '----------------------- For i = 1 To UBound(Arr, 1) If Arr(i, 1) <> "" And .exists(Arr(i, 1)) Then Arr(i, 27) = .Item(Arr(i, 1)) End If Next End With Sheets("TH").[G9].Resize(UBound(Arr, 1), UBound(Arr, 2)) = Arr End Sub
Code này nếu trong các cột H:AF có tính toán bằng công thức thì … hổng còn công thức nào???
Vâng đúng rồi ạ. Em nhìn cái Form này quen quen, bạn í lần trước cũng đã hỏi về tính xuất, nhập, tồn rồi vậy có thể không dùng công thức(hihi) mà có nhỡ dùng công thức thì đã có Code thấy Ba tê.
Hi, dùng code của anh đỡ fải Paste Value!
Em xin cảm ơn các Thầy & anh đã giúp em!
Xem code nông dân này rồi đem ra cày xem nhé.
Mặc dù cách này chạy chậm hơn dùng Dictionary nhưng sẽ giúp các bạn nắm được căn bản nhanh hơn
Mình nhân bản dữ liệu của bạn lên hơn 6000 dòng và chạy chưa đến 0.5 giây
Sub TimMaKH2()
Dim i As Long, j As Long
Dim ArrDes(), arrSrc(), result()
ArrDes = Range(, .End(3)).Value
result = Range(, .End(3)).Offset(, 26).Value
With Sheets("MA")
arrSrc = .Range(., ..End(3)).Resize(, 2).Value
End With
For i = 1 To UBound(ArrDes, 1)
For j = 1 To UBound(arrSrc)
If ArrDes(i, 1) <> "" Then
If result(i, 1) = "" Then
If ArrDes(i, 1) = arrSrc(j, 1) Then
result(i, 1) = arrSrc(j, 2)
Exit For
End If
End If
End If
Next j
Next i
ActiveSheet.Range("AG9").Resize(i – 1, 1).Value = result
End Sub
Nếu dùng Dic thì xài thêm 1 mảng kết quả nữa để tránh xử lý trên sheet luôn. Nếu lỡ như cột AG có công thức thì mình sẽ dùng .Formula, không dùng .Value nữa…
Chắc bạn nắm vững rồi nhỉ?
Sub TimMaKH3()
Dim I As Long, j As Long, Des(), Src(), Result()
Des = Range(, .End(3)).Value
Result = Range(, .End(3)).Offset(, 26).Value
With Sheets("MA")
Src = .Range(., ..End(3)).Resize(, 2).Value
End With
With CreateObject("scripting.dictionary")
For I = 1 To UBound(Src)
If Not .exists(Src(I, 1)) Then .Add Src(I, 1), Src(I, 2)
Next
For I = 1 To UBound(Des)
If Des(I, 1) <> "" Then
If Result(I, 1) = "" Then
If .exists(Des(I, 1)) Then Result(I, 1) = .Item(Des(I, 1))
End If
End If
Next
End With
ActiveSheet.Range("AG9").Resize(I – 1, 1).Value = Result
End Sub
www.giaiphapexcel.com/diendan/threads/gi%C3%BAp-s%E1%BB%ADa-code-f%C6%B0%C6%A1ng-th%E1%BB%A9c-find-%C4%91%E1%BB%83-n%C3%B3-kh%C3%B4ng-paste-l%C3%AAn-d%E1%BB%AF-li%E1%BB%87u-c%C5%A9.76186/post-468070
Anh Hải cho em hỏi
result = Range([AG9], .End(3)).Offset(, 26).Value
Tại sao câu trên như vậy, mà nó không fải như vầy
result = Range([G9], .End(3)).Offset(, 26).Value
Mong anh giải thích , em cảm ơn
Chắc mình viết code sai í mà. Lâu quá rồi nên không nhớ. Nhưng nhìn vào kỳ kỳ sao ấy
Chắc lúc đó ý mình là thế này vì mảng Result chỉ cần có 1 cột.
Result = Range(, .End(3).Offset(, 26)).Value
……………..
Nếu chỉnh lại như HV hỏi thì chắc là chính xác rồi
result = Range([G9], .End(3)).Offset(, 26).Value
www.giaiphapexcel.com/diendan/threads/gi%C3%BAp-s%E1%BB%ADa-code-f%C6%B0%C6%A1ng-th%E1%BB%A9c-find-%C4%91%E1%BB%83-n%C3%B3-kh%C3%B4ng-paste-l%C3%AAn-d%E1%BB%AF-li%E1%BB%87u-c%C5%A9.76186/post-472585
Khóa học Power PI – Ứng dung trong Nhân sự
TỔNG QUAN KHÓA HỌC: POWER BI CHO NGÀNH NHÂN SỰ Khóa học Power BI cho Nhân sự được thiết kế dành riêng cho các...
Xem khóa học
Mỗi code viết phục vụ cho một mục đích và một kiểu dữ liệu.
Nếu bạn muốn làm khác đi thì nên đưa file có dữ liệu ví dụ lên và nói rõ muốn làm gì với nó.
Bạn hỏi chung chung như vậy thì khó trả lời quá.
Vậy bạn dùng hàm Vlookup() là được rồi.
——————————————
Nếu muốn code làm thay cho Vlookup() hàng mấy chục cột phía sau thì thử code này.
Phía sau BF9 trong sheet Ma nếu có tiêu đề là lấy hết
(Nó chỉ sử dụng cho dữ liệu trong file của bạn)
Public Sub MyLook()
Dim Rng(), Arr(), KQ(), I As Long, J As Long, K As Long, Cot As Long, Dic As Object, Tem As String
Set Dic = CreateObject("Scripting.Dictionary")
With Sheets("Ma")
Cot = .Range(., ..End(xlToLeft)).Columns.Count
Rng = .Range(., ..End(xlUp)).Resize(, Cot).Value
End With
ReDim Arr(1 To UBound(Rng, 1), 1 To Cot)
For I = 1 To UBound(Rng, 1)
Tem = Rng(I, 1)
If Not Dic.Exists(Tem) Then
K = K + 1
Dic.Add Tem, K
For J = 1 To Cot
Arr(K, J) = Rng(I, J)
Next J
End If
Next I
With Sheets("TH")
Rng = .Range(., ..End(xlUp)).Resize(, Cot).Value
ReDim KQ(1 To UBound(Rng, 1), 1 To Cot)
For I = 1 To UBound(Rng, 1)
Tem = Rng(I, 1)
If Tem <> "" Then
If Dic.Exists(Tem) Then
For J = 1 To Cot
KQ(I, J) = Arr(Dic.Item(Tem), J)
Next J
End If
End If
Next I
..Resize(I – 1, Cot).Value = KQ
End With
Set Dic = Nothing
End Sub
Hóa ra là lookup từ cột G sheet TH. Lấy dữ liệu từ cột BF sheet Ma trở về sau?
Vậy kiểm tra lại code này xem:
Public Sub MyLook()
Dim Rng(), Arr(), KQ(), I As Long, J As Long, K As Long, Cot As Long, Dic As Object, Tem As String
Set Dic = CreateObject("Scripting.Dictionary")
With Sheets("Ma")
Cot = .Range(., ..End(xlToLeft)).Columns.Count
Rng = .Range(., ..End(xlUp)).Resize(, Cot + 1).Value
End With
ReDim Arr(1 To UBound(Rng, 1), 1 To Cot)
For I = 1 To UBound(Rng, 1)
Tem = Rng(I, 1)
If Not Dic.Exists(Tem) Then
K = K + 1
Dic.Add Tem, K
For J = 2 To Cot + 1
Arr(K, J – 1) = Rng(I, J)
Next J
End If
Next I
With Sheets("TH")
Rng = .Range(., ..End(xlUp)).Value
ReDim KQ(1 To UBound(Rng, 1), 1 To Cot)
For I = 1 To UBound(Rng, 1)
Tem = Rng(I, 1)
If Tem <> "" Then
If Dic.Exists(Tem) Then
For J = 1 To Cot
KQ(I, J) = Arr(Dic.Item(Tem), J)
Next J
End If
End If
Next I
..Resize(I – 1, Cot).Value = KQ
End With
Set Dic = Nothing
End Sub