Thảo luận về phương thức tìm kiếm - METHOD FIND() (2 người xem)

  • Thread starter Thread starter cadafi
  • Ngày gửi Ngày gửi
Liên hệ QC

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

cadafi

Hành động từ trái tim
Administrator
Tham gia
27/5/07
Bài viết
4,297
Được thích
11,386
Donate (Paypal)
Donate
Giới tính
Nam
Nghề nghiệp
Business Man
Đây là phần lượt dịch từ file của HYen17 (phần I). Các anh chị xem và chỉnh sửa cho phù hợp giúp nhé!

Đây là toàn bộ phần lượt dịch trong tài liệu của HYEN17. Các anh chị xem và chỉnh sửa giúp!
 

File đính kèm

Vể nội dung phương thức thì đã có. Em sẽ viết 2 VD minh họa về phương thức này :

1 . Tìm kiếm các ô thỏa mãn điều kiện dò tìm trong một vùng và điền giá trị tìm được sang một vùng khác.
2. Tìm kiếm các ô thỏa mãn điều kiện trong vùng (1 cột) và trả về một vùng chứa đứng tất cả các ô thỏa mãn.

Còn các VD khác các Bác tiếp tục nha.
 
Mình xin gởi 1 file về Find(). Không biết Danh đã viết chưa. Các code này là copy của Bác Sa và xào nấu lại.
Tìm trong Sheet1 có Cell nào thỏa điều kiện Value=OldText và thay thế =newText
Lúc ấy mọi người sẽ hỏi sao không Ctr F và thay thế cho nhanh, cụ thể như:

PHP:
 .Replace What:=oldText, Replacement:=newText, LookAt:=xlPart, SearchOrder _
        :=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False

Nhưng vấn đề hay nhất của Find() là không những thay thế bằng value, mà còn thay thế font, màu... và gán vào 1 Array.
Trong code sau, bạn có thể thay các thông số sau: After, LookAt:=xlWhole hay LookAt:=xlPart, sẽ thấy nhiệm mầu của nó.
Cụ thể khi tìm số 3, nếu chọn LookAt:=xlPart thì sẽ chọn những cell có số 3 (*3*) nhưng khi chọn LookAt:=xlWhole. Cũng như bạn thay thông số After:=ActiveCell (After:=cells(5,5)) thì thấy thế nào.
Sau đây là 2 code
1/ Tìm và thay thế value, text...
2/ Tìm và đưa vào 1 MyArr() sau đó gán MyArr vào sheet khác.
PHP:
Option Explicit
Sub TimVaThayThe()
 Dim DiaChi As String 'Sa
 Dim MyRng As Range, Rng As Range
 Set MyRng = Range(Cells(1, 1), Cells(18, 4))
 Dim oldText As String, newText As String
 oldText = "3"
 newText = "test"
    With MyRng
        Set Rng = .Find(What:=oldText, LookIn:=xlValues, LookAt:=xlWhole)
      Set Rng = .Find(What:=oldText, After:=ActiveCell,LookIn:=xlValues, LookAt:=xlxlPart)
      If Not Rng Is Nothing Then
         DiaChi = Rng.Address
         Do
         With Rng.Offset(, 5)
         With Rng
            .Value = newText
            .Interior.ColorIndex = 36
            .Font.Bold = True
        End With
            Set Rng = .FindNext(Rng)
            If Rng Is Nothing Then Exit Sub
         Loop While Not Rng Is Nothing And Rng.Address <> DiaChi
      End If
   End With
End Sub
Sub TimVaGan()
 Dim DiaChi As String, i As Long
 Dim MyRng As Range, Rng As Range
 Set MyRng = Range(Cells(1, 1), Cells(18, 4))
 Dim oldText As String
 Dim MyArr()
 i = 1
 ReDim MyArr(1 To MyRng.Count)
 oldText = "3"
 With MyRng
        Set Rng = .Find(What:=oldText, LookIn:=xlValues, LookAt:=xlPart)
            If Not Rng Is Nothing Then
            DiaChi = Rng.Address
         Do
            MyArr(i) = Rng.Value
            i = i + 1
           Set Rng = .FindNext(Rng)
            If Rng Is Nothing Then GoTo bien
         Loop While Not Rng Is Nothing And Rng.Address <> DiaChi
      End If
End With
bien:
With Sheets("sheet2")
    .Cells.ClearContents
   For i = LBound(MyArr) To UBound(MyArr)
        .Cells(i, 1) = MyArr(i)
   Next
End With
End Sub


Bác Sa hiệu đính lại giúp. Cám ơn Bác. Hậu tạ.

Các bạn đừng chê nhé, mình cũng mới biết Find() qua bài dịch của Kiệt (Ca_dafi).
 

File đính kèm

Bác Sa hiệu đính lại giúp. Cám ơn Bác. Hậu tạ.
Các bạn cứ xem mình cũng mới biết Find() qua bài dịch của Kiệt (Ca_dafi).
ThuNghi nhờ thì hiệu đính thôi, chứ tuyệt nhiên không có ý định gây áp lực đâu HoangDanh nha
PHP:
Option Explicit
Sub TimVaThayThe()
 Dim DiaChi As String
 Dim MyRng As Range, Rng As Range
 Set MyRng = Range(Cells(1, 1), Cells(18, "D"))
' Dim newText As String'
 Const oldText As Long = 3
 With MyRng
   Set Rng = .Find(What:=oldText, LookIn:=xlValues, LookAt:=xlWhole)
   If Not Rng Is Nothing Then
      DiaChi = Rng.Address
      Do
         With Rng
            .Value = "test":           .Font.Bold = True
            .Interior.ColorIndex = 36
         End With
         Set Rng = .FindNext(Rng)
         If Rng Is Nothing Then Exit Sub
      Loop While Not Rng Is Nothing And Rng.Address <> DiaChi
   End If
 End With
End Sub
Nói thêm cho rõ: Mình đã bỏ không khai báo 1 biến; Lý do biến này chỉ xài trong 1 câu lệnh mà thôi; Điều này mình học được từ BAB!
Biến thứ 2 cũng vậy, nhưng mình chuyển sang khai báo Const kiểu Long; cũng có mục đích đưa thêm thông tin đến bạn đọc, rằng ta có thể thay 1 trị số bằng một chuỗi.
Chúc vui!
 
Em vẫn trung thành đặt thêm biến NewText hay là NewS. Dù nó chỉ 1 lần nhưng khi thay đổi Code thì tìm mau hơn.
Bỏ một bữa eat out nghiên cứu tìm thấy thêm 1 vấn đề. Có thể dùng Find để thay thế Vlookup, Index Match tiện hơn thay vì for i.
Tôi làm thử 1 ví dụ xem thử. Lấy thông số ở sh Index gán vào cột C, D của sh Data. Format (tô), insert comment theo điều kiện chọn.
PHP:
Option Explicit
Sub xIndex()
With Application
       .ScreenUpdating = False
End With
 Dim DiaChi As String, eRow As Long, iR As Long
 Dim MyRng As Range, Rng As Range, RngDM As Range
 Dim oldText As String
 Sheets("Data").Select
 With Sheets("Index")
    eRow = .[a1000].End(xlUp).Row - 1
    Set RngDM = .Range(.Cells(2, 1), .Cells(eRow, 3))
 End With
 Columns("B:B").ClearComments
 Columns("A:D").ClearFormats
 eRow = [a1000].End(xlUp).Row
 Range(Cells(2, 3), Cells(eRow, 4)).ClearContents
 Set MyRng = Range(Cells(2, 2), Cells(eRow, 2))
 For iR = 1 To eRow
    oldText = RngDM.Cells(iR)
    With MyRng
      Set Rng = .Find(What:=oldText, LookIn:=xlValues, LookAt:=xlWhole)
      If Not Rng Is Nothing Then
         DiaChi = Rng.Address
        Do
            With Rng
               If .Value = "A1" Then
                    With .Offset(0, -1).Resize(, 4).Font
                        .ColorIndex = 5
                        .Bold = True
                    End With
                    .AddComment
                    .Comment.Visible = False
                    .Comment.Text Text:="GPE:" & Chr(10) & "OK"
                End If
                .Offset(, 1).Value = RngDM.Cells(iR).Offset(, 1)
                With .Offset(, 2)
                    .Value = RngDM.Cells(iR).Offset(, 2)
                    .NumberFormat = "#,##0"
                End With
                
            End With
            Set Rng = .FindNext(Rng)
            If Rng Is Nothing Then Exit Sub
        Loop While Not Rng Is Nothing And Rng.Address <> DiaChi
      End If
   End With
Next
Set RngDM = Nothing
Set MyRng = Nothing
With Application
       .ScreenUpdating = True
End With
End Sub
Hóa ra vừa nghiên cứu thêm mà lại giữ sức khỏe.
Xin Bác Sa edit tiếp nhé. Cám ơn Bác.
 

File đính kèm

Em vẫn trung thành đặt thêm biến NewText hay là NewS. Dù nó chỉ 1 lần nhưng khi thay đổi Code thì tìm mau hơn.
Bỏ một bữa eat out nghiên cứu tìm thấy thêm 1 vấn đề. Có thể dùng Find để thay thế Vlookup, Index Match tiện hơn thay vì for i.
Tôi làm thử 1 ví dụ xem thử. Lấy thông số ở sh Index gán vào cột C, D của sh Data. Format (tô), insert comment theo điều kiện chọn.
Hóa ra vừa nghiên cứu thêm mà lại giữ sức khỏe. Xin Bác Sa edit tiếp nhé. Cám ơn Bác.
Theo ý mình nó như vầy; Nói nhỏ:"Ngoài cách giới thiệu phương thức FIND(), macro này là một điển hình về cách dùng
With . . .
. . . . .
End With


PHP:
Option Explicit
Sub xIndex()
Dim DiaChi As String, eRow As Long, jF As Long
Dim MyRng As Range, Rng As Range, RngDM As Range
Dim OldText As String

 Application .ScreenUpdating = False
 With Sheets("Index")
    eRow = .[a1000].End(xlUp).Row - 1
    Set RngDM = .Range(.Cells(2, 1), .Cells(eRow, "C"))
 End With
 Sheets("Data").Select
 Columns("B:B").ClearComments
 Columns("A:D").ClearFormats:          eRow = [a65000].End(xlUp).Row
 Range(Cells(2, 3), Cells(eRow, 4)).ClearContents
 Set MyRng = Range([B2], Cells(eRow, 2))
 For jF = 1 To eRow
    OldText = RngDM.Cells(jF)
    With MyRng
      Set Rng = .Find(What:=OldText, LookIn:=xlValues, LookAt:=xlWhole)
      If Not Rng Is Nothing Then
         DiaChi = Rng.Address
        Do
            With Rng
               If .Value = "A1" Then
                    With .Offset(0, -1).Resize(, 4).Font
                        .ColorIndex = 5:             .Bold = True
                    End With
                    .AddComment:             .Comment.Visible = False
                    .Comment.Text Text:="GPE:" & Chr(10) & "OK"
                End If
                .Offset(, 1).Value = RngDM.Cells(jF).Offset(, 1)
                With .Offset(, 2)
                    .Value = RngDM.Cells(jF).Offset(, 2)
                    .NumberFormat = "#,##0"
                End With
            End With
            Set Rng = .FindNext(Rng)
            If Rng Is Nothing Then Exit Sub
        Loop While Not Rng Is Nothing And Rng.Address <> DiaChi
      End If
   End With
Next
Set RngDM = Nothing:                   Set MyRng = Nothing
End Sub

To HoangDanh: Theo thiển ý, bài tới HoangDanh sẽ đưa ra ví dụ. Nếu được Danh phân tích ví dụ đầu kỹ hơn các ví dụ sau; Ý mình là dẫn giải người đọc đấy mà!
Kỹ nói ở đây là các câu lệnh liên quan đến FIND() sát sườn thôi; chứ việc khai báo biến, Application. . . , ngay đến With . . . End With, . . . . đã có sách PhanTuHuong lo rồi! Mình cho rằng những người đọc các bài này đã có sách của tác giả này!
Thân ái!
 
Xin tham gia đề tài một ví dụ về Find
Tôi lại không thích dùng:
Mã:
With MyRng 
  Set Rng = .Find(What:=OldText, LookIn:=xlValues, LookAt:=xlWhole) 
  If Not Rng Is Nothing Then 
  ...
End With

Mà dùng vòng lặp Do ... Loop
Code dưới đây tìm chuỗi sFind (nhập từ InputBox) trong cột A và ghi cột B nội dung ô tìm được.

Mã:
Sub MyFind()
Dim r As Long, rW As Long, rF1 As Long, rF2 As Long, S As Long
Dim sFind
On Error Resume Next
Columns("B").ClearContents
r = 1
sFind = InputBox("Nhap du lieu tim:")
rF1 = [COLOR=Red][B]Columns("A")[/B][/COLOR].Find(What:=sFind, After:=Cells(1, 1)).Row
If rF1 = 0 Then Exit Sub
rF2 = rF1
Do
  Cells(r, 2) = Cells(rF2, 1)
  r = r + 1
  rF2 = Columns("A").Find(What:=sFind, After:=Cells(rF2, 1)).Row
  If rF2 <= rF1 Then Exit Do
Loop
End Sub
Chưa so sánh xem 2 cách có khác nhau về tốc độ không nhưng viết gọn hơn
 
Lần chỉnh sửa cuối:
Em gởi Anh, Kiệt và Danh xem thử đọan dịch phần 2. Gởi tin nhắn thấy khó quá nên đưa file lên nhờ hiệu đính vậy. Tiếng A của em # level A.
[FONT=&quot]Excel Find Method in Excel VBA (Ozgrid.com)[/FONT]
 
Xin tham gia đề tài một ví dụ về Find
Tôi lại không thích dùng:
Mã:
With MyRng 
  Set Rng = .Find(What:=OldText, LookIn:=xlValues, LookAt:=xlWhole) 
  If Not Rng Is Nothing Then 
  ...
End With

Mà dùng vòng lặp Do ... Loop
Code dưới đây tìm chuỗi sFind (nhập từ InputBox) trong cột A và ghi cột B nội dung ô tìm được.. . .
Chưa so sánh xem 2 cách có khác nhau về tốc độ không nhưng viết gọn hơn
Cách của thầy Long cũng như cách khác, đều dùng vòng lặp Do . . . Loop cả mà!
Khác nhau ở chỗ Thầy dùng không phải là biến đối tượng Rng mà là chí ít hai biến kiểu Long
Để thay chỗ;
Theo tôi, tốc độ ở đây, quyết định bỡi chiếm ít hay nhiều bộ nhớ mà thôi.
Thật tình, mình cũng chưa rõ là dùng câu lệnh .FIND() & FindNext() sẽ khác nhau như thế nào về tốc độ tìm.
Rất mong bạn nào có tài liệu về vấn đề này, chia sẻ cho với!
 
Tôi cụ thể bài dịch của Find Method theo Ozgrid.com bằng code sau:
Tôi xin thay Cat=Sun vì tôi ghét Cat
PHP:
Sub Find_Sun()
Dim lCount As Long '(Ozgrid.com)
Dim rFoundCell As Range
    Set rFoundCell = Range("A1")
        For lCount = 1 To WorksheetFunction.CountIf(Columns(1), "Sun")
            Set rFoundCell = Columns(1).Find(What:="Sun", After:=rFoundCell, _
                LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, _
                SearchDirection:=xlNext, MatchCase:=False)
             With rFoundCell.Offset(, 2)
                .Value = rFoundCell
                .ClearComments
                .AddComment Text:="Ozgrid.com"
             End With
        Next lCount
End Sub
Code này tìm trong côt 1 những chữ "Sun" thì AddComment Text:="Ozgrid.com" vào cell bên cạnh. Để ý Next lCount rất hay.
Code này sẽ khác phục vòng lặp Do...Loop vì nó chỉ
số lần findNext =WorksheetFunction.CountIf(Columns(1), "Sun")
Còn nhanh , chậm thì em chưa biết.
To: Thầy Long
Code của Thầy còn thiếu
range(....).select
Còn nếu column(1).select
rF1 = column(1).Find(What:=sFind, After:=Cells(1, 1)).Row
thì dòng lệnh này dư After:=Cells(1, 1), bởi chắc rằng ta đang tìm trên côt 1.

Thú thật cái After:=ActiveCells này có cần thiết với find không thì em chưa biết, bởi vì khi ta select thì ta chắc rằng find tìm hết selection.
 

File đính kèm

Tôi cụ thể bài dịch của Find Method theo Ozgrid.com bằng code sau:
Tôi xin thay Cat=Sun vì tôi ghét Cat
PHP:
Sub Find_Sun()
Dim lCount As Long '(Ozgrid.com)
Dim rFoundCell As Range
    Set rFoundCell = Range("A1")
        For lCount = 1 To WorksheetFunction.CountIf(Columns(1), "Sun")
            Set rFoundCell = Columns(1).Find(What:="Sun", After:=rFoundCell, _
                LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, _
                SearchDirection:=xlNext, MatchCase:=False)
             With rFoundCell.Offset(, 2)
                .Value = rFoundCell
                .ClearComments
                .AddComment Text:="Ozgrid.com"
             End With
        Next lCount
End Sub
Code này tìm trong côt 1 những chữ "Sun" thì AddComment Text:="Ozgrid.com" vào cell bên cạnh. Để ý Next lCount rất hay.
Code này sẽ khác phục vòng lặp Do...Loop vì nó chỉ
số lần findNext =WorksheetFunction.CountIf(Columns(1), "Sun")
Còn nhanh , chậm thì em chưa biết.
To: Thầy Long
Code của Thầy còn thiếu
range(....).select
Còn nếu column(1).select
rF1 = column(1).Find(What:=sFind, After:=Cells(1, 1)).Row
thì dòng lệnh này dư After:=Cells(1, 1), bởi chắc rằng ta đang tìm trên côt 1.

Thú thật cái After:=ActiveCells này có cần thiết với find không thì em chưa biết, bởi vì khi ta select thì ta chắc rằng find tìm hết selection.

Đây cũng là một ý tưởng hay về giải thuật theo Find : For Next

Tuy nhiên nhanh hơn hay chậm hơn thì không biết do :

Nếu ở TH1 : Cứ mỗi một lần tìm thì lại phải xét hai điều kiện

PHP:
Loop While Not Rng Is Nothing And Rng.Address <> DiaChi

Còn ở TH2 :
- Nó sẽ phải xét cả mảng do dùng Countif
PHP:
For lCount = 1 To WorksheetFunction.CountIf(Columns(1), "Sun")
- Mỗi khi For tăng lên 1 thì sẽ SET Find 1 lần Find(Next)


Nhưng dù sao thì đây cũng là một ý tưởng hay, tuy nhiên nếu áp dụng cho nhiều cột thì có vẻ khó hơn cho For Next (dùng Countif)

VD : Tìm các khách hàng có một trong các cột , họ, tên đệm, tên, địa chỉ có ký tự ch để cho vào danh sách.

Thân!
 
Lần chỉnh sửa cuối:
Nhưng dù sao thì đây cũng là một ý tưởng hay, tuy nhiên nếu áp dụng cho nhiều cột thì có vẻ khó hơn cho For Next (dùng Countif)

VD : Tìm các khách hàng có một trong các cột , họ, tên đệm, tên, địa chỉ có ký tự ch để cho vào danh sách.
Cám ơn lời gợi ý, nhờ vậy mình mới tìm thấy cái hay của find. Các bạn xem thử code sau, tìm trong A, B, C có những cell nào có "ch". Ta chọn thử MyRng là 3 cột A, B, C
PHP:
Sub Find_CaiGiDo()
Dim lCount As Long '(Ozgrid.com)
Dim rFoundCell As Range, MyRng As Range, Dem As Long
    Set MyRng = Sheet2.Range(Cells(1, 1), Cells(25, 3))
    MyRng.ClearComments
    Set rFoundCell = Range("A1")
    Dem = WorksheetFunction.CountIf(MyRng, "*ch*")
        For lCount = 1 To Dem
            Set rFoundCell = MyRng.Find(What:="ch", After:=rFoundCell, _
                LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByColumns, _
                SearchDirection:=xlNext, MatchCase:=False)
             With rFoundCell
                .Value = rFoundCell
                .ClearComments
                .AddComment Text:="Ozgrid.com"
             End With
        Next lCount
End Sub

Dem = WorksheetFunction.CountIf(MyRng, "*ch*")
Lúc này ta sẽ vận dụng sức mạnh của countif
LookAt:=xlPart: tìm một phần
LookAt Optional Variant. Can be one of the following XlLookAt constants: xlWhole or xlPart.
LookAt (Cách thức tìm kiếm): Không bắt buộc, khai báo dạng Variant. Có thể là một trong các dạng XILookAt hằng số theo sau đây: xlWhole (Tìm toàn bộ) hoặc xlPart (tìm một phần)
SearchOrder:=xlByColumns hay là
SearchOrder:=xlByRows
Cái này cũng có tác dụng của nó, nếu row > iR có thể exit sub.
Và cũng không nên quên
MatchCase:=False/True
 
To: Thầy Long
Code của Thầy còn thiếu
range(....).select
Đúng là thiếu. Lúc chạy thử đang đã chọn cột A nên nó chạy tốt nhờ Selection.Find ...

Còn nếu column(1).select
rF1 = column(1).Find(What:=sFind, After:=Cells(1, 1)).Row
thì dòng lệnh này dư After:=Cells(1, 1), bởi chắc rằng ta đang tìm trên côt 1.
Thú thật cái After:=ActiveCells này có cần thiết với find không thì em chưa biết, bởi vì khi ta select thì ta chắc rằng find tìm hết selection.
rF1 = column(1).Find(What:=sFind, After:=Cells(1, 1)).Row tìm ô đầu tiên thỏa mãn điều kiện tìm thì After:=Cells(1, 1) thừa.
Nhưng các lần tìm tiếp theo thì không thừa vì nếu không khai báo nó chỉ tìm ô đầu tiên thỏa mãn điều kiện tìm.
After:=ActiveCells, nó tìm ô phía sau ô ActiveCells nên mới tìm ô kế tiếp thỏa mãn điều kiện tìm được.
 
Tạo Phiếu nhập kho từ BK Nhập theo PP Find!

Vân dụng find để tạo ra phiếu nhập kho theo dữ liệu. Cách này cũng gần giống Advance Filter (AF), nhưng khỏi gán vào vùng phụ. Thấy nó cũng nhanh.
Trong file này đang làm theo soCT đã sort. Đúng ra có thể dùng match và countif để giới hạn Range, như đây là ứng dụng của Find Method nên dùng thử. Có thể triển khai nếu SoCT chưa sort. Giống hệt như AF còn nhanh hơn không thì chưa có can đảm để test.
PHP:
Sub TaoPN()
Dim iRow As Long, EndR As Long
Dim MyRng As Range, rFoundCell As Range, SoCT As String
With Application
       .DisplayAlerts = False
       .ScreenUpdating = False
       .Calculation = xlCalculationManual
End With
Sheets("PhNK").Select
    [a14:i27].ClearContents
    [C6:C8].ClearContents
    SoCT = [H5]
With Sheets("BKNhap")
    EndR = .[a65000].End(xlUp).Row
    Set MyRng = .Range(.Cells(1, 5), .Cells(EndR, 5)) 'Sửa 2 thành 1'
    EndR = WorksheetFunction.CountIf(MyRng, SoCT)
    Set rFoundCell = MyRng(1)
        Set rFoundCell = MyRng.Find(What:=SoCT, After:=rFoundCell, _
            LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, _
            SearchDirection:=xlNext, MatchCase:=True)
        With rFoundCell
               Cells(4, 4) = .Offset(iRow, -4).Value
               Cells(6, 3) = .Offset(iRow, 1).Value
               Cells(8, 3) = "Nhap theo HD" & .Offset(iRow, -1).Value
            For iRow = 0 To EndR - 1
               Cells(iRow + 14, 1) = iRow + 1
               Cells(iRow + 14, 2) = .Offset(iRow, 2).Value
               Cells(iRow + 14, 3) = .Offset(iRow, 3).Value
               Cells(iRow + 14, 4) = .Offset(iRow, 7).Value
               Cells(iRow + 14, 6) = .Offset(iRow, 4).Value
               Cells(iRow + 14, 7) = .Offset(iRow, 5).Value
               Cells(iRow + 14, 8) = .Offset(iRow, 6).Value
               Cells(iRow + 14, 9) = "HD" & .Offset(iRow, -1).Value
            Next
        End With
End With
Set MyRng = Nothing
Set rFoundCell = Nothing
With Application
    .DisplayAlerts = True
    .ScreenUpdating = True
    .Calculation = xlCalculationAutomatic
End With
End Sub
File này là chuẩn theo mẫu có thể áp dụng được ngay trong kế tóan khi bạn muốn in phiếu nhập kho.
Trong code tôi có dùng:
LookAt:=xlWhole

MatchCase:=True
ie tìm toàn bộ theo SoCT
Các Bác xem và góp ý để mình ứng dụng, cám ơn.
Đang tìm cách vận dụng find để lấy data theo hơn 1 điều kiện khác cột.
 

File đính kèm

Lần chỉnh sửa cuối:
Qua những gì tiện ích do Find Method mang lại. Đề nghị Kiệt, Danh viết 1 intro về Find Method. Mình xin gởi 1 file về tìm những Cells(x,y) trong Range(Cells(1,1), Cells(i,j)) với
.Value=Value
.Format=Format
Cái này thì AdFi thua rồi. Chỉ có for hoặc Do ...Loop thôi.
Code này tìm trong cột 1 với Cells(i,j) = "Sun" và có format bold và màu đỏ.
PHP:
Sub Find_Format1()
Dim lCount As Long
Dim rFoundCell As Range, MyRng As Range, Dem As Long
    Set MyRng = Sheet1.Range(Cells(1, 1), Cells(50, 1))
    MyRng.ClearComments
    Set rFoundCell = Range("A1")
    Dem = WorksheetFunction.CountIf(MyRng, "sun")
        For lCount = 1 To Dem
            Set rFoundCell = MyRng.Find(What:="sun", After:=rFoundCell, _
                LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByColumns, _
                SearchDirection:=xlNext, MatchCase:=False)
            With rFoundCell
                If .Font.Bold = True And .Font.ColorIndex = 3 Then
                    .AddComment Text:="TN"
                End If
             End With
        Next lCount
End Sub
Sub Find_Format()
Dim lCount As Long
Dim rFoundCell As Range, MyRng As Range, Dem As Long
    Set MyRng = Sheet1.Range(Cells(1, 1), Cells(50, 1))
    MyRng.ClearComments
    Set rFoundCell = Range("A1")
    Dem = WorksheetFunction.CountIf(MyRng, "sun")
    With Application.FindFormat.Font
        .FontStyle = "Bold"
        .ColorIndex = 3
    End With
        For lCount = 1 To Dem
            Set rFoundCell = MyRng.Find(What:="sun", After:=rFoundCell, _
                LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByColumns, _
                SearchDirection:=xlNext, MatchCase:=False, searchFormat:=True)
                On Error Resume Next
            With rFoundCell
                .AddComment Text:="Tim thay roi TN oi!"
            End With
        Next lCount
End Sub
Qua những code sau ta có thể vận dụng Find thay thế AdFi.

Kiệt, Danh viết thêm Find với What:= Số nào đó.
 

File đính kèm

Ta sẽ dùng phương thức Find để tìm ra trong vùng A1:A10 những ô nào có ký tự 1
Ta dùng chuột bôi đen vùng A1:A10 và cho chạy Macro sau :
PHP:
Sub Test1()
Dim Rng As Range
Set Rng = Selection.Find("1*", LookIn:=xlValues, LookAt:=xlWhole)
If Not Rng Is Nothing Then
Do
MsgBox Rng.Address
Set Rng = Selection.FindNext(Rng)
Loop
End If
End Sub

Xin lỗi các hạ xíu, nếu là chen ngang.

Nếu tìm những ô có ký tự là 1 thì phải là :
PHP:
Set Rng = Selection.Find("*1*", LookIn:=xlValues, LookAt:=xlWhole)
chứ nếu như Code trên thì chỉ là : Tìm những Cell bắt đầu bằng ký tự 1.

Nếu có gì sai sót thì mong các hạ bỏ qua vì với VBA thì tại hạ mới là nhập môn thôi.

Kính!
 
Xin lỗi các hạ xíu, nếu là chen ngang.

Nếu tìm những ô có ký tự là 1 thì phải là :
PHP:
Set Rng = Selection.Find("*1*", LookIn:=xlValues, LookAt:=xlWhole)
chứ nếu như Code trên thì chỉ là : Tìm những Cell bắt đầu bằng ký tự 1.

Nếu có gì sai sót thì mong các hạ bỏ qua vì với VBA thì tại hạ mới là nhập môn thôi.

Kính!

Đúng là như thế.
Mục đích của mình tìm chuỗi bắt đầu với số 1. Do trong VD mình không nói rõ.
Cảm ơn bạn!
 
Cám ơn lời gợi ý, nhờ vậy mình mới tìm thấy cái hay của find. Các bạn xem thử code sau, tìm trong A, B, C có những cell nào có "ch". Ta chọn thử MyRng là 3 cột A, B, C
PHP:
Sub Find_CaiGiDo()
Dim lCount As Long '(Ozgrid.com)
Dim rFoundCell As Range, MyRng As Range, Dem As Long
    Set MyRng = Sheet2.Range(Cells(1, 1), Cells(25, 3))
    MyRng.ClearComments
    Set rFoundCell = Range("A1")
    Dem = WorksheetFunction.CountIf(MyRng, "*ch*")
        For lCount = 1 To Dem
            Set rFoundCell = MyRng.Find(What:="ch", After:=rFoundCell, _
                LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByColumns, _
                SearchDirection:=xlNext, MatchCase:=False)
             With rFoundCell
                .Value = rFoundCell
                .ClearComments
                .AddComment Text:="Ozgrid.com"
             End With
        Next lCount
End Sub

Dem = WorksheetFunction.CountIf(MyRng, "*ch*")
Lúc này ta sẽ vận dụng sức mạnh của countif
LookAt:=xlPart: tìm một phần

SearchOrder:=xlByColumns hay là
SearchOrder:=xlByRows
Cái này cũng có tác dụng của nó, nếu row > iR có thể exit sub.
Và cũng không nên quên
MatchCase:=False/True


Đề bài này không phải là thay thế bác ạ, vì vậy bác phải thêm 1 lệnh If nữa

VD : Tìm các khách hàng có một trong các cột , họ, tên đệm, tên, địa chỉ có ký tự ch để cho vào danh sách.

Có nghĩa là nó sẽ tìm theo hàng (Row), nếu thấy có ký tự ch thì thôi, nhảy xuống hàng dưới, nếu không thấy thì tiếp tục tìm ở cột họ . . . .

VD : Tìm khách hàng có hoặc tên có ký tự V ở mảng dưới đây

Makhach|Ten khach
NHNTVN|Ngân hàng Ngoại thương Việt Nam
TUGIA|Cty TNHH Tứ Gia
TTKTTT|Trung tâm kỹ thuật thông tấn Việt Nam
DAIPHONG|Cty TNHH T.Mại và Công nghệ Đại Phong
BHBD|Bảo hiểm Xã hội Thành phố Hà Nội
DAIPHONG|Cty TNHH T.Mại và Công nghệ Đại Phong
LTXLAN|Lê Thị Xuân Lan



thì nếu như của bác thì
  1. Ngân Hàng Ngoại Thương sẽ lấy 2 lần
  2. Trung tâm kỹ thuật thông tấn Việt Nam : Xếp gần cuối trong khi đó nó là đứng thứ 2
Bác tham khảo chủ đề này nhé :
http://www.giaiphapexcel.com/forum/showthread.php?t=8954


Sao lại có thêm 1 đề tài nữa thế này :
Góp ý cho bài viết về "Tổng quan về phương thức FIND() trong Excel"

Thân!
 
Lần chỉnh sửa cuối:
Sơ lượt mục lục cho bài tổng hợp về Phương Thức Find

Sau khi tham khảo các ý kiến góp ý của các anh chị, em xin phép gửi lên mục lục sơ khảo cho bài viết tổng hợp về Phương thức Find như sau:
==============================================================
Mục lục
Find Method (Help) (Phương thức Find (Trợ Giúp))
A. Basic Conception (Khái niệm cơ bản):
B. How to implement the Find Method? (Ứng dụng phương thức Find như thế nào?):
C. Remarks (Một số lưu ý):
D. Examples for Using Find Method (Các tình huống áp dụng phương thức Find):
==============================================================
Find Method (Help)
Phương thức Find (Trợ Giúp)
--------------------------------------------------------------------------
A. Basic Conception (Khái niệm cơ bản):

The Excel Find Method is an excellent tool to use when writing Excel VBA macros. Unfortunately most end up using a VBA loop instead of the Find Method.
Phương thức Find của excel quả là một công cụ tuyệt vời khi ứng dụng vào việc lập trình các tạo các macros bằng VBA trong excel. Tuy nhiên, hầu như người dùng thông thường lại sử dụng một vòng lặp VBA thay cho việc sử dụng phương thức Find.

Find method as applies to the Range object
Phương thức Find áp dụng cho đối tượng Range.

Finds specific information in a range, and returns a Range object that represents the first cell where that information is found. Returns Nothing if no match is found. Doesn’t affect the selection or the active cell.
Phương thức này sẽ tìm kiếm các dữ liệu/thông tin đặc trưng riêng trong một vùng, và trả về kết quả là một đối tượng Range đại diện là ô đầu tiên chứa dữ liệu/thông tin được tìm thấy hoặc trả về kết quả là Nothing nếu không tìm thấy thông tin và không ảnh hưởng/tác động đến vùng được chọn hoặc ô hiện hành.

The syntax for the Find Method is as shown below/Cú pháp tổng quát như sau:
expression.Find(What, After, LookIn, LookAt, SearchOrder, SearchDirection, MatchCase, MatchByte, SearchFormat)
expression: Required. An expression that returns a Range object.
Biểu thức: Yêu cầu phải khai báo. Biểu thức này trả về một đối tượng Range.

Where "expression" is any valid range Object, e.g. Range("A1:A100"), Columns(2) etc. Also, a Range Object is returned whenever we use the Find Method. The Range Object returned will of course be the Range where the value being sought resides.
“Expression” với dạng biểu thức là một vùng xác định, ví dụ: Range("A1:A100"), Columns(2) v.v… Cho nên, khi dùng phương thức Find này, giá trị trả về cũng sẽ là một đối tượng Range. Đối tượng Range này dĩ nhiên sẽ là một Range chứa dữ liệu/thông tin cần tìm.

What: Required Variant. The data to search for. Can be a string or any Microsoft Excel data type.
What: Yêu cầu phải khai báo ở dạng Variant (dạng biến thể). Đây là dữ liệu/thông tin cần tìm kiếm. Có thể là một chuỗi ký tự hoặc bất kỳ dạng dữ liệu nào có trong Excel.

After: Optional Variant. The cell after which you want the search to begin. This corresponds to the position of the active cell when a search is done from the user interface. Note that After must be a single cell in the range. Remember that the search begins afterthis cell; the specified cell isn’t searched until the method wraps back around to this cell. If you don’t specify this argument, the search starts after the cell in the upper-left corner of the range.
After: Không bắt buộc, khai báo dạng Variant. Đây là ô mà việc tìm kiếm sẽ được bắt đầu sau ô này. Ô này tương ứng với vị trí của ô hiện hành sau khi việc tìm kiếm hoàn tất từ giao diện người dùng. Lưu ý rằng After phải là một ô đơn lẻ trong vùng tìm kiếm. Và việc tìm kiếm sẽ bắt đầu sau ô này; ô được khai báo này sẽ không được đưa vào quá trình tìm kiếm trừ khi phương thức này (phương thức Find) bao phủ cả ô này. Nếu ta không khai báo đối số này thì việc tìm kiếm sẽ bắt đầu sau ô trên cùng bên trái của vùng cần tìm kiếm.

LookIn: Optional Variant. The type of information.
LookIn: Không bắt buộc, khai báo dạng Variant. Đây là dạng của dữ liệu/thông tin.

LookAt: Optional Variant. Can be one of the following XlLookAt constants: xlWhole or xlPart.
LookAt (Cách thức tìm kiếm): Không bắt buộc, khai báo dạng Variant. Có thể là một trong các dạng XILookAt hằng số theo sau đây: xlWhole (Tìm toàn bộ) hoặc xlPart (tìm một phần)


SearchOrder: Optional Variant. Can be one of the following XlSearchOrder constants: xlByRows or xlByColumns.
SearchOrder (thứ tự tìm kiếm): Không bắt buộc, khai báo dạng Variant. Có thể là một trong các dạng XlSearchOrder hằng số theo sau đây: xlByRows (theo thứ tự dòng) hoặc xlByColumns (theo thứ tự cột)

SearchDirection Optional XlSearchDirection. The search direction. XlSearchDirection can be one of these XlSearchDirection constants: xlNext default or xlPrevious

SearchDirection: Không bắt buộc XlSearchDirection. Hướng tìm kiếm. XlSearchDirection có thể là một trong các hằng số sau: xlNext default (Tìm kế tiếp) – Mặc định hoặc xlPrevious (Tìm trước đó)

MatchCase Optional Variant. True to make the search case sensitive. The default value is False.
MatchCase (trường hợp so khớp): Không bắt buộc, khai báo dạng Variant. Khai báo là TRUE nếu muốn thực hiện tìm kiếm chính xác. Giá trị mặc định là False.

MatchByte Optional Variant. Used only if you’ve selected or installed double-byte language support. True to have double-byte characters match only double-byte characters. False to have double-byte characters match their single-byte equivalents.
MatchByte (So khớp dạng Byte): Không bắt buộc, khai báo dạng Variant. Chỉ sử dụng khi ta đã chọn hoặc cài đặt bộ hỗ trợ ngôn ngữ ký tự byte kép (1byte=8 bit, double byte = 16 bit). Khai báo là TRUE để tìm và so sánh chỉ với các ký tự 16 bit. Khai báo là False để tìm và so sánh giữa ký tự 16 bit và ký tự 8 bit tương đương.

SearchFormat Optional Variant. The search format.
SearchFormat (tìm kiếm theo định dạng): Không bắt buộc, khai báo dạng Variant. Tìm kiếm theo định dạng.

(continue....)
 

File đính kèm

Lần chỉnh sửa cuối:
B. How to implement the Find Method? (Ứng dụng phương thức Find như thế nào?):

- The single best way to get the code needed for the Find Method is to record a macro using it on any Excel Worksheet. You will end with code like shown below:
Cách tốt nhất để tạo 1 code cần thiết cho phương thức Find là dùng công cụ Record macro ghi lại quá trình thao tác tại bất kỳ Excel Worksheet (WS) nào. Bạn sẽ thấy kết quả như sau:
Ta tự ghi lại 1 macro trong quá trình tìm từ “SUN” trong toàn bộ các cell của WS. Chọn nút ghi macro, nhấn Ctr A, sau đó Ctr F và bạn nhập từ “SUN”
Kết quả sẽ là như sau:
PHP:
Cells.Find(What:="SUN", After:=ActiveCell, LookIn:=xlValues, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, _
SearchFormat:=False).Activate
Code trên nghĩa là:
Tìm toàn bộ cell (Cells)
What:=”SUN”: tìm từ SUN
After:=ActiveCell: vị trí bắt đầu tìm: từ sau cell active
LookIn:=xlValues: Tìm giá trị (phần này còn có thông số formulas)

Các thông số khác:
LookAt:= xlPart, MatchCase:=False và
LookAt:= xlWhole, MatchCase:=True
Muốn dễ hiểu nhất thì khi bạn ghi macro, Ctr F vào khung option và tùy chọn các
- Match entire cell contents
- Match case
Bạn sẽ hình dung cụ thể.

SearchOrder:=xlByRows, SearchDirection:=xlNext, SearchFormat:=False
Các thông số còn lại đã diễn giải phần trên.

- From here we can modify the code to suit any exact needs.
Từ đó, chúng ta có thể sửa đổi code cho phù hợp với bất kỳ nhu cầu cụ thể nào.

- You can use the FindNext and FindPrevious methods to repeat the search.
When the search reaches the end of the specified search range, it wraps around to the beginning of the range. To stop a search when this wraparound occurs, save the address of the first found cell, and then test each successive found-cell address against this saved address.
Ta có thể dùng phương thức FindNextFindPrevious để lặp lại việc tìm kiếm.
Khi đến vị trí cuối của vùng tìm kiếm được xác định trước đó, excel sẽ bao phủ từ vị trí này đến vị trí đầu tiên của vùng tìm kiếm. Để ngưng việc tìm kiếm ngay khi động tác bao phủ này xảy ra, hãy lưu lại địa chỉ của ô đầu tiên tìm được, sau đó thử so sánh lần lượt mỗi địa chỉ ô được tìm thấy kế tiếp với địa chỉ ô vừa được lưu này.

- This example finds all cells in the range A1:A500 on worksheet one that contain the value 2 and changes it to 5.
Ví dụ này sẽ tìm kiếm tất cả các ô trong vùng A1:A500 trên worksheet 1, những ô nào có giá trị là 2 sẽ được thay bằng giá trị 5.
PHP:
Sub TestFind()
With Worksheets("Sheet1").Range("A1:A500")
Set Rng = .Find(2, LookIn:=xlValues) 
If Not Rng Is Nothing Then ‘Nếu giá trị Rng trả về không phải là Nothing thì
firstAddress = Rng.Address ‘Lưu lại địa chỉ ô đầu tiên tìm được.
Do
Rng.Value = 5
Set Rng = .FindNext(Rng) ‘Tìm tiếp
Loop While Not Rng Is Nothing And Rng.Address <> firstAddress 
‘Dừng vòng lặp Do..Loop khi giá trị Rng trả về là Nothing hoặc 
‘địa chỉ Rng trả về trùng với địa chỉ của ô tìm được đầu tiên.
End If
End With
End Sub
 
Lần chỉnh sửa cuối:
Web KT

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

Back
Top Bottom