Chào mừng đến với Diễn đàn Dân Kế Toán - Kế toán tổng hợp thực tế.
Trang 1 của 2 12 CuốiCuối
Kết quả 1 đến 10 của 19
  1. #1
    Ngày tham gia
    Dec 2015
    Bài viết
    4

    Dùng các phương thức Find của Recordset

    Trong bài này, tôi sẽ nói việc sử dụng các phương thức Find của một đối tượng Recordset thuộc thư viện DAO.

    Trước tiên, xin lưu ý trong thư viện ADO cũng có đối tượng Recordset, nhưng phương thức Find của đối tượng này sẽ khác với phương thức Find của DAO.Recordset.

    Có bốn phương thức Find của DAO.Recordset:
    - FindFirst: khi gọi phương thức này, con trỏ record sẽ nhảy ngay về record đầu tiên và tiến hành việc tìm kiếm record đầu tiên thỏa điều kiện tìm. Trong trường hợp recordset không có record nào (RecordCount = 0) thì phương thức này sẽ gây ra một lỗi khi gọi nó.
    - FindNext: khi gọi phương thức này, việc tìm kiếm sẽ thực hiện bắt đầu từ vị trí record mà con trỏ record đang đứng đến record cuối cùng. Cũng tương tự như FindFirst, Trong trường hợp recordset không có record nào (RecordCount = 0) thì phương thức này sẽ gây ra một lỗi khi gọi nó. Ngoài ra nếu khi đã con trỏ record duyệt tới record EOF (End of File) mà phương thức này được gọi thì sẽ xảy ra một lỗi.
    - FindPrevious: khi gọi phương thức này, việc tìm kiếm sẽ thực hiện bắt đầu từ vị trí record mà con trỏ record đang đứng trở về record đầu tiên. Cũng tương tự như FindFirst, Trong trường hợp recordset không có record nào (RecordCount = 0) thì phương thức này sẽ gây ra một lỗi khi gọi nó. Ngoài ra nếu khi đã con trỏ record duyệt tới record BOF (Begin of File) mà phương thức này được gọi thì sẽ xảy ra một lỗi.
    - FindLast: khi gọi phương thức này, con trỏ record sẽ nhảy ngay về record cuối cùng và tiến hành việc tìm kiếm record đầu tiên thỏa điều kiện tìm nhưng ngược từ dưới lên. Trong trường hợp recordset không có record nào (RecordCount = 0) thì phương thức này sẽ gây ra một lỗi khi gọi nó.

    Cách gọi phương thức:
    đối_tượng_recordset.FindFirst điều_kiện
    đối_tượng_recordset.FindNext điều_kiện
    đối_tượng_recordset.FindPreviuos điều_kiện
    đối_tượng_recordset.FindLast điều_kiện

    Trong đó điều_kiện là chuỗi thể hiện nội dung tìm kiếm.

    Để minh họa cho cách sử dụng các phương thức trên, chúng ta đặt ra một bài toán sau:
    Giả sử chúng ta thiết kế một form nhập liệu danh sách khách hàng (makh, tenkh, diachi). Trong form này có một nút Tìm (cmdFind). Khi nhấn nút này sẽ cho hiện ra một form khác để người sử dụng nhập vào tên khách hàng cần tìm (textbox tenkh) và 3 nút: Thi hành (cmdFind), Tìm tiếp (cmdFindNext) và Thôi (cmdClose).
    Khi nhấn nút Thi hành sẽ cho thực hiện một thủ tục, trong đó tìm kiếm xem có khách hàng nào thỏa mãn điều kiện tìm không. Nếu có thì cho hiển thị thông tin của khách hàng đó ở form KhachHang. Nếu không thì báo là không tìm thấy.
    Khi nhấn nút Tiếp, sẽ cho thực hiện một thủ tục xem có khách hàng nào còn thỏa mãn điều kiện tìm không. Nếu có thì cho hiển thị thông tin của khách hàng đó ở form KhachHang. Nếu không thì báo là không còn tìm thấy.
    Nút Thôi chủ yếu là đóng form Tim lại mà thôi.

    Bây giờ vào code đây:

    Bước 1: ở form KhachHang, thiết lập thủ tục sự kiện Click cho nút lệnh cmdFind như sau:
    DoCmd.OpenForm "TIM" ' Để cho hiển thị form Tim

    Bước 2: Ở form Tim, trong khu vực Declaration (tức là dưới dòng lệnh Option Explicit và/hoặc Option Compare Database), cho dòng lệnh khai báo sau:
    Dim st As String, rs As DAO.Recordset

    Thiết lập các thủ tục sự kiện sau:

    Private Sub Form_Load ()
    Set rs = Forms("KHACHHANG").RecordsetClone ' gán dữ liệu nguồn của form KhachHang vào recordset
    End Sub

    Private Sub cmdFind_Click ()
    st = "tenkh LIKE '*" & tenkh & "*'" 'dùng toán tử LIKE để tìm kiếm tương đối
    On Error GoTo loi_Find
    rs.FindFirst st
    If rs.NoMatch Then ' nếu không tìm thấy
    MsgBox "Không tìm thấy."
    Else
    Forms("KHACHHANG").Bookmark = rs.Bookmark 'cho hiển thị lên form KhachHang thông tin khách đã tìm thấy
    End If
    thoat_Find:
    Exit Sub
    loi_Find:
    MsgBox "Lỗi. Có thể danh sách khách hàng đang trống."
    Resume thoat_Find
    End Sub

    Private Sub cmdFindNext_Click ()
    On Error GoTo loi_FindNext
    rs.FindNext st
    If rs.NoMatch Then ' nếu không tìm thấy nữa
    MsgBox "Không còn tìm thấy."
    Else
    Forms("KHACHHANG").Bookmark = rs.Bookmark 'cho hiển thị lên form KhachHang thông tin khách đã tìm thấy
    End If
    thoat_FindNext:
    Exit Sub
    loi_FindNext:
    MsgBox "Lỗi. Có thể danh sách khách hàng đang trống."
    Resume thoat_FindNext
    End Sub

    Private Sub cmdClose_Click ()
    DoCmd.Close acForm, Me.Name
    End Sub


    Trên chỉ là những đoạn code chính, các bạn có thể thêm mắm muối vào cho hợp ý mình.

    Thấy hay thì vỗ tay, còn dỡ thỉ chê ít ít thôi cho đỡ quê !!!

  2. #2
    Ngày tham gia
    Nov 2015
    Bài viết
    16
    Phatnq2002 ơi bạn có thể gởi vd đính kèm không? Mình thử làm nhưng không được.

  3. #3
    Ngày tham gia
    Nov 2015
    Bài viết
    0
    Phat oi ban có thể giúp tôi phân biệt giửa "Seek" và "Find" không? mình thắc mắc lâu rồi và cũng đã hỏi bạn 1 lần nhưng chưa thấy hồi âm.

    Còn về Vd của bạn mình thấy không cần dùng đến Find method mà chì cần làm một form với source là 1 query, ờ cột mã khách hàng mình đặt điều kiện là like * Name và kết hợp với thuộc tính afterupdate là xong


    Các bạn có thể tham khảo vd về dan mục khách hàng qua ví dụ đính kẻm của mình



    Download : Tại đây

  4. #4
    Ngày tham gia
    Nov 2015
    Bài viết
    0
    Cám ơn Phatnq2002, Bài viết của bạn có hệ thống và hay quá. Mình không hiểu bookmark là gì bạn có thể hướng dẫn mình cách sử dụng không?



    Mã:
    Forms("KHACHHANG").Bookmark = rs.Bookmark

  5. #5
    Ngày tham gia
    Aug 2015
    Bài viết
    3
    Bạn Simon mến:
    Bạn dùng Seek khi bạn mở recordset theo mode table, nghĩa là:
    Dim rs = CurrentDB.OpenRecordset("source", dbOpenTable)
    và đồng thời bạn mở kèm chỉ mục:
    rs.Index = "index_name"
    Khi đó phương thức Seek sẽ mặc định dò tìm trên các trường thuộc khóa Index mà bạn đang mở cho Recordset. Nói tóm lại, Seek là phương thức tìm kiếm theo chỉ mục.
    Còn Find là phương thức tìm kiếm dựa theo điều kiện tìm kiếm bất kỳ trên recordset mở theo bất kỳ mode nào.
    Vấn đề thứ hai, đó cũng là một cách giải quyết tốt. Tuy nhiên, mục đích ví dụ của tôi chủ yếu để minh họa thôi.

    Bạn bichtram mến:
    Cái ví dụ tôi đưa là do tôi "tự chế", nên không có source gốc. bạn thông cảm nhé.

    Bạn binhnt mến:
    Bookmark là một thuộc tính của recordset trả về một giá trị chuỗi định vị một record. Mỗi record có một bookmark riêng, không trùng lặp.
    Ngoài ra bạn có thể tham khảo thuộc tính AbsolutePosition (trả về dữ liệu kiểu số) chỉ ra số thứ tự vật lý của record. Record đầu tiên có AbsolutePosition bằng 0.

  6. #6
    Ngày tham gia
    Aug 2015
    Bài viết
    0
    Cám ơn Phát nhiều ( Không biết tên bạn có phải không). Nhưng mình cung chưa hiểu rõ phương thức seek này lắm. Mình đọc sách thấy Index = primarykey, vậy index và seek liên hệ như thế nào?

    Hình như seek có thể có nhiều điều kiện , bạn có thể cho mình một vd không?

    Thanks trước nhé

  7. #7
    Ngày tham gia
    Nov 2015
    Bài viết
    0
    Seek là một phương thức tìm kiếm dựa trên một chỉ mục được mở cho recordset hiện hành mà bạn đang làm việc với nó.

    Cú pháp của Seek:
    recordset.Seek comparison, key1, key2...key13

    Trong đó:
    comparison: là một trong những toán tử so sánh sử dụng trong việc dò tìm: <, <=, >=, >
    key1, key2, ..., key13: các giá trị tương ứng với các field của index được mở được sử dụng như giá trị tìm kiếm.

    Dưới đây là ví dụ lấy từ Help của Microsoft để bạn tham khảo.
    Thủ tục dưới đây mở table Products theo chế độ Table, đồng thời mở chỉ mục đi kèm là chỉ mục khóa chính (Primary key) - có thể hiểu là sẽ tìm kiếm trên field ProductID. Sau đó cho người dùng nhập vào một mã số ID, nếu tìm thấy thì hiển thị thông tin của Prodcut đó, nếu không thì thông báo không tìm thấy. Nếu người dùng không nhập thì chấm dứt tìm.

    Sub SeekX()
    Dim dbsNorthwind As Database
    Dim rstProducts As Recordset
    Dim intFirst As Integer
    Dim intLast As Integer
    Dim strMessage As String
    Dim strSeek As String
    Dim varBookmark As Variant
    Set dbsNorthwind = OpenDatabase("Northwind.mdb")
    ' You must open a table-type Recordset to use an index,
    ' and hence the Seek method.
    Set rstProducts = _
    dbsNorthwind.OpenRecordset("Products", dbOpenTable)
    With rstProducts
    ' Set the index.
    .Index = "PrimaryKey"
    ' Get the lowest and highest product IDs.
    .MoveLast
    intLast = !ProductID
    .MoveFirst
    intFirst = !ProductID
    Do While True
    ' Display current record information and ask user
    ' for ID number.
    strMessage = "Product ID: " & !ProductID & vbCr & _
    "Name: " & !ProductName & vbCr & vbCr & _
    "Enter a product ID between " & intFirst & _
    " and " & intLast & "."
    strSeek = InputBox(strMessage)
    If strSeek = "" Then Exit Do
    ' Store current bookmark in case the Seek fails.
    varBookmark = .Bookmark
    .Seek "=", Val(strSeek)
    ' Return to the current record if the Seek fails.
    If .NoMatch Then
    MsgBox "ID not found!"
    .Bookmark = varBookmark
    End If
    Loop
    .Close
    End With
    dbsNorthwind.Close
    End Sub

  8. #8
    Ngày tham gia
    Aug 2015
    Bài viết
    0
    Ðề: Dùng các phương thức Find của Recordset

    Các bạn cần hiểu rõ bạn chất của SEEK và FINDFIRST để tận dụng khả năng làm việc với CSDL lớn:
    SEEK là phép tìm kiếm trên trường đã được SORT cho nên thời gian tìm kiếm sẽ nhanh hơn. Ví dụ Table "Nhanvien" có trường "Hoten" được sắp xếp, và ta muốn tìm với nội dung "Lê". Khi chương trình tìm tới vần "M" mà không thấy sẽ dừng tìm kiếm và ra thông báo "Không thấy". Như vậy muốn sử dụng SEEK bạn phải có khai báo .INDEX=....
    Nhưng FINDFIRST thì nó cứ ngó ngẩn tìm hoài cho đến cùng nếu nó không tìm thấy cái nó cần.

  9. #9
    Ngày tham gia
    Aug 2015
    Bài viết
    0
    Ðề: Dùng các phương thức Find của Recordset




    Trích dẫn Gửi bởi dangtuanson
    Các bạn cần hiểu rõ bạn chất của SEEK và FINDFIRST để tận dụng khả năng làm việc với CSDL lớn:
    SEEK là phép tìm kiếm trên trường đã được SORT cho nên thời gian tìm kiếm sẽ nhanh hơn. Ví dụ Table "Nhanvien" có trường "Hoten" được sắp xếp, và ta muốn tìm với nội dung "Lê". Khi chương trình tìm tới vần "M" mà không thấy sẽ dừng tìm kiếm và ra thông báo "Không thấy". Như vậy muốn sử dụng SEEK bạn phải có khai báo .INDEX=....
    Nhưng FINDFIRST thì nó cứ ngó ngẩn tìm hoài cho đến cùng nếu nó không tìm thấy cái nó cần.
    Mỗi phương thức tìm có những ưu điểm và nhược điểm của nó.
    Nếu một table có chứa dữ liệu mà có thể tạo ra nhiều truy vấn tìm kiếm thì không lẽ chúng ta phải tạo sẵn tất cả các chỉ mục?
    Và liệu rằng từng ấy chỉ mục bạn tạo sẵn đã đáp ứng nhu cầu của người dùng.
    Trường hợp khác nếu bạn tạo ra một dạng "tìm kiếm động", cón nghĩa là biểu thức điều kiện tìm kiếm sẽ tùy biến theo ý người sử dụng dựa trên một số field mà bạn đề nghị (VD dùng 4 field để tạo nội dung tìm kiếm) thì bạn cần có sẵn 1 x 2 x 3 x 4 = 24 chỉ mục tạo sẵn. Bạn có đủ can đảm làm điều đó không?
    Một vấn đề khác, khi bạn mở một recordset có từ khóa ORDER BY thì có khác gì đâu giữa SEEK và Find ? Bởi nếu tìm không thấy nó cũng nhảy đến EOF cơ mà? Có lẽ chỗ này bạn nhầm chăng?
    Tôi không có tham vọng áp đặt các bạn phải dùng theo kiểu của tôi mà tôi chỉ muốn rằng những kinh nghiệm mà tôi đã làm sẽ có ích cho các bạn thôi.

  10. #10
    Ngày tham gia
    Nov 2015
    Bài viết
    0
    Ðề: Dùng các phương thức Find của Recordset

    Sau khi thực hành xong thấy cũng ổn nhưng còn một số vấn đề sau :
    - Nếu tìm thấy 1 người, xong thoát về form chính thì không vấn đề gì, nhưng nếu đến người thứ 2 trở lên thì bất tiện ở chổ sẽ không biết người thứ nhất là ai? (vì bị cái form "Tim" che mất). giải pháp là phải làm cái form "tìm" thật nhỏ. Nếu mình muốn hiện Msgbox báo cho mình biết đã tìm thấy tên gì và một số chi tiết khác thì làm cách nào?
    -Tôi muốn tìm chính xác họ tên, không dùng LIKE thì phải code như thế nảo
    - muốn cho form luôn nằm ở góc trái, phía trên màn hình thì phải làm sao? (để khỏi che mất form chính)
    Kính mong các bác giải đáp giúp !!!

 

 
Trang 1 của 2 12 CuốiCuối

Quyền viết bài

  • Bạn Không thể gửi Chủ đề mới
  • Bạn Không thể Gửi trả lời
  • Bạn Không thể Gửi file đính kèm
  • Bạn Không thể Sửa bài viết của mình
  •