• Nên chuyển đổi dùng Field dạng Yes/No sang dạng Number
  • Nên chuyển đổi dùng Field dạng Yes/No sang dạng Number

    ongke0711 > 14-11-17, 12:24 AM

    Nên chuyển đổi dùng Field dạng Yes/No sang dạng Number
    —————————————————————————————————
    (Trích lượt từ bài viết của Allen Browne)

    Sau đây là lý do chúng ta nên hạn chế (hoặc không) sử dụng field dạng Yes/No trong table Ms Access.
    1. Khi Microsoft thiết kế Field dạng Yes/No cho Access, họ mặc định field này sẽ không có giá trị Null và bộ máy quản lý dữ liệu (JET) cũng xử lý Field này như vậy. Trong thực tế ứng dụng, có các query truy vấn table có field dạng Yes/No đã bị báo lỗi “No current record” mà người lập trình không tìm ra lý do tại sao. Query sẽ bị báo lỗi là query có sử dụng “Outer join” vì tất cả các Field bên nhánh Outer table có thể chứa giá trị Null mà field Yes/No thì không có Null. Một trong những cách khác phục lỗi của “Outer Join” là dùng hàm Int() chuyển đổi field Yes/No sang dạng số trong câu lệnh truy vấn. Ví dụ:

    [Hình: 24511259528_0d0cf4f9a0_z.jpg]

    [Hình: 37667797064_9d54eff8cc_o.png]

    - Khi dùng hàm Int() để chuyển đổi Yes/No sang Integer thì Access nó chấp nhận giá trị Null cho dạng Number và sẽ không báo lỗi nữa nhưng đổi lại việc tốc độ truy vấn sẽ bị ảnh hưởng (đối với dữ liệu cỡ chục ngàn dòng) vì không còn sử dụng được Index của field Yes/No này.

    2. Nếu sau này chúng ta muốn nâng cấp CSDL lên SQL Server thì Field dạng Yes/No của Access dễ gặp lỗi trong SQL Server. Trong Access, nếu bạn không cung cấp giá trị cho Yes/No field thì nó sẽ mặc định “hiển thị” là False (No). Nhưng khi trong SQL (dạng Bit) nó chưa 3 giá trị phân biệt là True, False và Null, khi đó bạn truy vấn giá trị False trong SQL server nó sẽ không hiển thị hết nhưng record mà bạn thấy là False trong Access. Một trong nhưng các khắc phục trường hợp này là: kiểm tra các giá trị Null trong field Yes/No của table Access trước rồi chuyển đổi nó thành giá trị mặc định (ví dụ là False) trước khi nâng cấp
    lên SQL server.

    -----------------------------------------------------------------------------------------------------------------------------------------

    Giải pháp:

    Một giải pháp thay thế tốt đó là đổi field Yes/No sang dạng Number để vượt qua các lỗi đã đề cập ở trên và linh động sử dụng được giá trị Null. Bạn sẽ không đánh đổi tốc độ truy vấn vì vẫn dùng được Index của field Number, và không bị lỗi “No current record”. Với Field type dạng Number, để giống như Yes/No mà bạn quen dùng, bạn chọn Field size: Integer, bạn dùng số -1 cho TRUE (Yes) và 0 cho FALSE (No). Nếu muốn loại bỏ giá trị NULL luôn thì thiết lập Default Value: 0Validation Rule: 0 Or -1, Required: Yes. Nếu muốn dùng giá trị NULL thì thiết lập “Validation Rule: Is Null Or 0 Or -1”. 

    [Hình: 38327953596_7aac2415bc.jpg]   [Hình: 38383111211_7a2127748e.jpg]

    * Bạn vẫn có thể sử dụng "Check Box" cho Field dạng Number
    - Dùng Check box trong trường hợp bạn không muốn lưu giá trị Null. Mặc định trong Table, đối với Field dạng Number -> Tab Lookup -> Display Control: sẽ không có tùy chọn "Check box", chỉ có Textbox hoặc Combobox. Để có thêm tùy chọn "Check box" bạn dùng hàm SetPropertyDAO() dưới đây để thêm nó. Copy đoạn code này vào module đặt tên modSetPropertyDAO:

    Mã PHP:
    Option Compare Database
    Option Explicit

    Function SetPropertyDAO(obj As ObjectstrPropertyName As StringintType As Integer_
       varValue 
    As VariantOptional strErrMsg As String) As Boolean
    On Error 
    GoTo ErrHandler

       If HasProperty
    (objstrPropertyNameThen
           obj
    .Properties(strPropertyName) = varValue
       Else
           obj
    .Properties.Append obj.CreateProperty(strPropertyNameintTypevarValue)
       End If
       SetPropertyDAO True

    ExitHandler
    :
       Exit Function

    ErrHandler:
       strErrMsg strErrMsg obj.Name "." strPropertyName " not set to " _
           varValue 
    ". Error " Err.Number " - " Err.Description vbCrLf
       Resume ExitHandler
    End 
    Function
    Public Function 
    HasProperty(obj As ObjectstrPropName As String) As Boolean
       
    'Purpose: Return true if the object has the property.
       Dim varDummy As Variant

       On Error Resume Next
       varDummy = obj.Properties(strPropName)
       HasProperty = (Err.Number = 0)
    End Function 

    - Mở cửa số Immediate (Ctr-G), paste dòng code này vô -> Enter.

    Call SetPropertyDAO(CurrentDb.TableDefs("TenTable").Fields("TenFieldYesNo"), "DisplayControl", dbInteger, CInt(acCheckbox))

    [Hình: 37678426734_7e4c7b6d20_o.png]

    Sau khi chạy dòng code trên thì Field vừa chọn sẽ hiển thị dạng "Check box" (Display Control: 106), bạn có thể sử dụng như Yes/No field nhưng sẽ không  gặp lỗi "Outer join" nữa.

    Nếu bạn muốn lưu giá trị Null thì không dùng "Check Box" được mà phải đổi sang "ComboBox". Dùng Check Box thì không hiển thị được giá trị Null nhưng đối với Combo box, nếu để trống thì nó là Null rồi.

    [Hình: 24520436588_8fe7a0c2f6_o.png]

    Nói tóm lại, việc chuyển đổi từ Yes/No field sang dạng Number không có phức tạp nhưng khắc phục được nhiều vấn đề thì bạn cũng nên tham khảo thêm giải pháp này trong ứng dụng Access của bạn.  :007:

    Link file demo: http://www.mediafire.com/file/8d5hkccktx...cement.mdb