Giúp sửa code: Fương thức Find để nó không Paste lên dữ liệu cũ! (1 người xem)

Liên hệ QC

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

Hong.Van

Busy
Tham gia
7/5/12
Bài viết
2,328
Được thích
1,765
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 em
PHP:
Sub TimMaKH()
    Dim i As Long
    Dim arrRes, arrSrc
    Dim n1 As Range, rTmp As Range
    With ActiveSheet
        arrSrc = .Range(.[G9], .[G65536].End(3)).Resize(, 27).Value
    End With
    With Sheets("MA")
        Set n1 = .Range(.[BE10], .[BE1000].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 Sub
Em 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
 

File đính kèm

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 em
PHP:
Sub TimMaKH()
    Dim i As Long
    Dim arrRes, arrSrc
    Dim n1 As Range, rTmp As Range
    With ActiveSheet
        arrSrc = .Range(.[G9], .[G65536].End(3)).Resize(, 27).Value
    End With
    With Sheets("MA")
        Set n1 = .Range(.[BE10], .[BE1000].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 Sub
Em 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.
PHP:
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(.[BE10], .[BE65000].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(.[G9], .[G65000].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
 
Lần chỉnh sửa cuối:
Upvote 0
Đã trót viết rồi cũng mạo muội đưa lên dù chậm hơn bác Bate
Mã:
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
 
Upvote 0
Đã trót viết rồi cũng mạo muội đưa lên dù chậm hơn bác Bate
Mã:
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???
 
Upvote 0
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ê.
 
Upvote 0
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!
 
Upvote 0
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

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
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
PHP:
Sub TimMaKH2()
Dim i As Long, j As Long
Dim ArrDes(), arrSrc(), result()
ArrDes = Range([G9], [G65536].End(3)).Value
result = Range([AG9], [G65536].End(3)).Offset(, 26).Value
With Sheets("MA")
 arrSrc = .Range(.[BE10], .[BE10000].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ỉ?
PHP:
Sub TimMaKH3()
Dim I As Long, j As Long, Des(), Src(), Result()
Des = Range([G9], [G65536].End(3)).Value
Result = Range([AG9], [G65536].End(3)).Offset(, 26).Value
With Sheets("MA")
   Src = .Range(.[BE10], .[BE65536].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
 
Lần chỉnh sửa cuối:
Upvote 0
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
Mã:
Sub TimMaKH2()
Dim i As Long, j As Long
Dim ArrDes(), arrSrc(), result()
ArrDes = Range([G9], [G65536].End(3)).Value
[COLOR=#ff0000][B]result = Range([AG9], [G65536].End(3)).Offset(, 26).Value
[/B][/COLOR]With Sheets("MA")
 arrSrc = .Range(.[BE10], .[BE10000].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
Anh Hải cho em hỏi
result = Range([AG9], [G65536].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], [G65536].End(3)).Offset(, 26).Value
Mong anh giải thích , em cảm ơn
 
Upvote 0
Anh Hải cho em hỏi
result = Range([AG9], [G65536].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], [G65536].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([AG9], [G65536].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], [G65536].End(3)).Offset(, 26).Value
 
Lần chỉnh sửa cuối:
Upvote 0
PHP:
Sub TimMaKH3()
Dim I As Long, j As Long, Des(), Src(), Result()
Des = Range([G9], [G65536].End(3)).Value
Result = Range([AG9], [G65536].End(3)).Offset(, 26).Value
With Sheets("MA")
   Src = .Range(.[BE10], .[BE65536].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

cho em hỏi nếu không chỉ hiển thị 1 cột mã khách hàng mà hiển thị cả một range bao gồm cả cột mã, cột tên, cột phụ ... đằng sau nữa thì sửa code trên như thế nào ạ.
 
Upvote 0
PHP:
Sub TimMaKH3()
Dim I As Long, j As Long, Des(), Src(), Result()
Des = Range([G9], [G65536].End(3)).Value
Result = Range([AG9], [G65536].End(3)).Offset(, 26).Value
With Sheets("MA")
   Src = .Range(.[BE10], .[BE65536].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

cho em hỏi nếu không chỉ hiển thị 1 cột mã khách hàng mà hiển thị cả một range bao gồm cả cột mã, cột tên, cột phụ ... đằng sau nữa thì sửa code trên như thế nào ạ.
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á.
 
Upvote 0
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á.

àh file của em giống như file trên, em muốn khi nhấn tìm mã thì ngoài cột mã hiển thị tương ứng có thêm tên (gắn liền ngay sau cột mã khách hàng) ngay bên cạnh. Nói chung là tất cả những gì liên quan đến cột mã đều hiển thị luôn.
 

File đính kèm

Upvote 0
àh file của em giống như file trên, em muốn khi nhấn tìm mã thì ngoài cột mã hiển thị tương ứng có thêm tên (gắn liền ngay sau cột mã khách hàng) ngay bên cạnh. Nói chung là tất cả những gì liên quan đến cột mã đều hiển thị luôn.
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)
PHP:
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(.[BF9], .[IV9].End(xlToLeft)).Columns.Count
    Rng = .Range(.[BF10], .[BF65000].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(.[AG9], .[AG65000].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
    .[AG9].Resize(I - 1, Cot).Value = KQ
End With
Set Dic = Nothing
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
àh file của em giống như file trên, em muốn khi nhấn tìm mã thì ngoài cột mã hiển thị tương ứng có thêm tên (gắn liền ngay sau cột mã khách hàng) ngay bên cạnh. Nói chung là tất cả những gì liên quan đến cột mã đều hiển thị luôn.
Tôi dựa vào code cua Anh Hải làm thử cho bạn
Mã:
Sub TimMaKH3()
    Dim i As Long, j As Long
    Dim ArrDes(), arrSrc(), result()
    ArrDes = Range([G9], [G65536].End(3)).Value
    result = Range([G9], [G65536].End(3)).Offset(, 26).Resize(, 2).Value
    With Sheets("MA")
        arrSrc = .Range(.[BE10], .[BE10000].End(3)).Resize(, 3).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)
                        result(i, 2) = arrSrc(j, 3)
                        Exit For
                    End If
                End If
            End If
        Next j
    Next i
    ActiveSheet.Range("AG9").Resize(i - 1, 2).Value = result
End Sub
Cảnh báo nếu cột AG, có cái gì khác ngoài mã tìm được thì nó không xóa!!!
 
Upvote 0
Em cám ơn rất nhiều tuy nhiên:

code của bác Bate nếu xóa cột mã sẵn có thì không chạy (em muốn lấy cả mã khách hàng và các cột bên cạnh mã)
=============================

cột mã | cột tên | cột tháng

M013

=> code chạy chính xác

cột mã

bỏ trống

không có biểu hiện gì thay đổi
==========================================
code của bác Hong.Van thì chạy nhưng bị dính nội dung của các cột

cột mã | cột tên | cột tháng

M013 | nguyen van a1 | 17

code chạy thành

cột mã | cột tên | cột tháng

M013 | nguyen van a117 |
 
Lần chỉnh sửa cuối:
Upvote 0
Em cám ơn rất nhiều tuy nhiên:

code của bác Bate nếu xóa cột mã sẵn có thì không chạy (em muốn lấy cả mã khách hàng và các cột bên cạnh mã)
=============================
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:
PHP:
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(.[BF9], .[IV9].End(xlToLeft)).Columns.Count
    Rng = .Range(.[BE10], .[BE65000].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(.[G9], .[G65000].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
    .[AG9].Resize(I - 1, Cot).Value = KQ
End With
Set Dic = Nothing
End Sub
 
Upvote 0
Em cám ơn rất nhiều tuy nhiên:

==========================================
code của bác Hong.Van thì chạy nhưng bị dính nội dung của các cột

cột mã | cột tên | cột tháng

M013 | nguyen van a1 | 17

code chạy thành

cột mã | cột tên | cột tháng

M013 | nguyen van a117 |
Bạn xem kỹ chưa vậy M013 thì tên là nguyen van a117 thì đúng rồi !Còn muốn lấy thêm cột tháng bên Sh MA thì fải sửa code 1 chút
Mã:
Sub TimMaKH3()
    Dim i As Long, j As Long
    Dim ArrDes(), arrSrc(), result()
    ArrDes = Range([G9], [G65536].End(3)).Value
    result = Range([G9], [G65536].End(3)).Offset(, 26).Resize(, 3).Value
    With Sheets("MA")
        arrSrc = .Range(.[BE10], .[BE10000].End(3)).Resize(, 4).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)
                        result(i, 2) = arrSrc(j, 3)
                        result(i, 3) = arrSrc(j, 4)
                        Exit For
                    End If
                End If
            End If
        Next j
    Next i
    ActiveSheet.Range("AG9").Resize(i - 1, 3).Value = result
End Sub
 
Upvote 0
Không còn gì thắc mắc nữa, rất cám ơn hai bác
 
Upvote 0

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

Back
Top Bottom