• FORM NHẬP LIỆU P1: Dùng 1 Form nhập cho nhiều Table (cùng thiết kế Fields)
  • FORM NHẬP LIỆU P1: Dùng 1 Form nhập cho nhiều Table (cùng thiết kế Fields)

    ongke0711 > 14-07-18, 05:27 PM

    Dùng chung 1 Form nhập liệu (Unbound) cho các Table tham chiếu (dạng danh mục)

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

    Chào các bạn,

    Thấy tình hình diễn đàn khá im ắng bữa giờ nên kiếm chuyện post bài để thảo luận 014  007 .

    Các bạn đã từng vật vã với việc thiết kế các Table làm sao cho nó không thừa cũng không thiếu, dễ truy vấn dữ liệu, không chiếm tài nguyên bộ nhớ v.v.. Sau đó bước kế tiếp theo tôi cũng cực kỳ quan trọng là làm sao nhập liệu cho nó một cách chính xác, đủ, đúng dữ liệu. Do đó việc thiết kế một Form nhập liệu cũng phải cực kỳ cẩn trọng: làm sao để một người dùng phổ thông cũng có thể hiểu, thao tác nhập liệu dễ dàng và đảm bảo luôn nhập đúng yêu cầu của dữ liệu. Để làm được như vậy theo chút kinh nghiệm  của tôi thì cần quan tâm một số yếu tố chính như sau:
    - Giao diện (User Interface): dễ tập trung những chỗ nhập liệu, không rối mắt (font chữ, màu sắc, bố cục...) 
    - Trải nghiệm người dùng (User experience): người dùng dễ dàng thao tác nhập liệu đúng và nhanh, không bị bỡ ngỡ, bối rối (đánh đố người dùng) không biết nhập thông tin như thế nào, nhập ở đâu...
    - Nội dung: phải đảm bảo đủ, đúng yêu cầu của Table
    - Bẫy lỗi: tránh trường hợp nhập liệu sai, hướng dẫn người dùng nhập liệu đúng. Người ta có câu "Garbage In, Garbage Out" tức là bạn đưa dữ liệu sai (dữ liệu rác) vào thì kết quả nhận được từ nguồn dữ liệu đó cũng là rác. 007

    Về phần giao diện, trải nghiệm người dùng, tôi sẽ chia sẻ ở bài sau từ các bài tôi học được trên cộng đồng và dịch lại thôi (chưa đủ bản lĩnh để tự đưa ra các nguyên tắc thiết kế  014 ) . 

    Nói sơ khởi vậy thôi, sau đây là phần Form nhập liệu đơn giản nhưng code không phải thuộc sơ cấp (cách làm có thể gọi là "Suy nghĩ phức tạp để đưa ra giải pháp đơn giản"). Do trong thực tế khi có những table chứa dữ liệu để tham chiếu như: table giới tính, phòng ban, chức vụ, Dân tộc v.v.. mà dữ liệu nhập thì cũng đơn giản có vài field (như mã phòng ban, tên phòng ban, ghi chú). Ứng với mỗi table này mà thiết kế 1 form nhập liệu cho nó thì cũng tốn kém Form nên tôi đã điều chỉnh lại thiết kế table, form để có thể sử dụng nhập liệu chung cho tất cả các table trên thông qua 1 Form. 
    Demo trong bài là thực tế trong ứng dụng quản lý nhân sự tôi trích ra để minh hoạ.

    [Hình: 43350804152_9256bde161_o.png]

    Khi nhìn form danh sách trên, chắc chắn có bạn sẽ thắc mắc sao không cho nhập liệu trực tiếp lên trong form này luôn cho đỡ đơn giản, cần gì tạo form khác, code kiết chi cho dài dòng, chỉ cần AllowEdit= True, Data Entry=Yes hoặc AllowAddition = True là nhập luôn được rồi. Hơn nữa mấy form này chỉ nhập liệu vài lần lúc đầu rồi ít khi bổ sung thì cần gì làm cho cầu kỳ. 

    [Hình: 42494707765_3046f0de86_o.png]

    Cách làm như hình trên là nhanh nhất, ít tốn kém nhất nhưng tôi thì lại không ưa chuộng kiểu nhập liệu này (quan điểm, sở thích cá nhân) vì:
    - Nếu để người dùng có thể thao tác trực tiếp lên toàn bộ các record thì không an toàn nếu như khi đang ở chế độ chỉnh sửa, lỡ đụng chuột, đụng phím làm nó thay đổi dữ liệu ở các dòng khác không mong muốn và cũng không để ý thấy để sửa lại rồi lưu dẫn đến dữ liệu bị sai.
    - Nếu vô chế độ Data Entry = True thì không can thiệp được các dòng dữ liệu trước đó nhưng sẽ không nhìn thấy tổng thể dữ liệu đã có trước đó để thêm dữ liệu mới không bị trùng.
    Do đó cách thiết kế của tôi là luôn tạo 1 danh sách để xem tổng thể như trên rồi khi cần nhập liệu sẽ mở 1 Single Form để nhập/sửa dữ liệu (có thể Bound hoặc Unbound).
    Trong demo này tôi dùng 1 form nhập liệu là Unbound Form để đỡ phải bẫy lỗi tự động lưu dữ liệu của Bound Form 007 . Khi bấm vào Tab nào và muốn cập nhật dữ liệu cho table đó thì sẽ hiện lên Form nhập liệu với các tên Label được đổi theo tương ứng tên field của table đó. 

    Thủ thuật chia sẻ trong demo này:
    - Dùng OpenArgs. Truyền nhiều tham số thông qua OpenArgs.
    - Các hàm tự động Load record cho Unbound Form, AddNew, Update cho table từ Unbound Form.
    - Một số bẫy lỗi khi thao tác cập nhật dữ liệu.

    Một số hình demo:
    [Hình: 41591093200_a14675c6cb_o.png]

    [Hình: 42495103155_e284f8243e_o.png]

    Hy vọng sẽ có ích cho các bạn.

    Bài kế tôi sẽ chia sẻ với các bạn một số kiểu thiết kế Form nhập liệu (Bound và Unbound) để tham khảo.


    Link demo (Access 2013): http://www.mediafire.com/file/4cag4j7jzv...accdb/file
  • RE: FORM NHẬP LIỆU P1: Dùng 1 Form nhập cho nhiều Table (cùng thiết kế Fields)

    cpucloi > 14-07-18, 07:03 PM

    Ngoài các kỹ năng về viết code, cái này cần phải có thời gian tích lũy kinh nghiệm mới "phát hiện" và áp dụng được. Những người  mới (đặc biệt là amateur như mình) thì lúc đầu phải cần nhiều forms (và hình như thấy càng nhiều forms, càng thiết kế màu mè càng thích, hjxx), đến khi có một số kinh nghiệm nhất định thì mới biết cách thực hiện như vậy. Mong bạn tiếp tục chia sẽ kỹ năng về code cho mọi người trên 4rum tham khảo.
  • RE: FORM NHẬP LIỆU P1: Dùng 1 Form nhập cho nhiều Table (cùng thiết kế Fields)

    NguyenDungAnh > 17-07-18, 10:50 PM

    Cám ơn bác cho ra nhiều bài viết thế này nữa nhé để anh em tham khảo
  • RE: FORM NHẬP LIỆU P1: Dùng 1 Form nhập cho nhiều Table (cùng thiết kế Fields)

    NguyenDungAnh > 20-07-18, 08:33 AM

    [Hình: 42801225984_09121cfa1b_b.jpg]ongke loi by anh nguyễn, trên Flickr

    EM bị báo lỗi ở dòng đỏ này là bị sao hả bác
    em dùng win 7 office 2016 64bit
  • RE: FORM NHẬP LIỆU P1: Dùng 1 Form nhập cho nhiều Table (cùng thiết kế Fields)

    ongke0711 > 20-07-18, 11:32 AM

    (20-07-18, 08:33 AM)NguyenDungAnh Đã viết: EM bị báo lỗi ở dòng đỏ này là bị sao hả bác
    em dùng win 7 office 2016 64bit

    Bạn sửa dòng khai báo hàm API của windows lại như sau:

    Mã PHP:
    Option Compare Database
    Option Explicit

    #If VBA7 Then
       Private Declare PtrSafe Function GetActiveWindow Lib "user32" () As Long
       Private 
    Declare PtrSafe Function MessageBoxW Lib "user32" (ByVal hWnd As LongPtrByVal lpText As StringByVal lpCaption As StringByVal wType As Long) As Long
    #Else
       Private Declare Function GetActiveWindow Lib "user32" () As Long
       Private 
    Declare Function MessageBoxW Lib "user32" (ByVal hWnd As LongByVal lpText As StringByVal lpCaption As StringByVal wType As Long) As Long
    #End If 
  • RE: FORM NHẬP LIỆU P1: Dùng 1 Form nhập cho nhiều Table (cùng thiết kế Fields)

    NguyenDungAnh > 20-07-18, 04:05 PM

    Cám ơn bác
  • RE: FORM NHẬP LIỆU P1: Dùng 1 Form nhập cho nhiều Table (cùng thiết kế Fields)

    NguyenDungAnh > 20-07-18, 04:23 PM

    Public Function MsgBoxUni(ByVal PromptUni As Variant, Optional ByVal Buttons As VbMsgBoxStyle = vbOKOnly, Optional ByVal TitleUni As Variant = vbNullString) As VbMsgBoxResult

    lại bị lỗi ở dòng này bác ạ. lúc thêm mới hay sửa thì bị
  • RE: FORM NHẬP LIỆU P1: Dùng 1 Form nhập cho nhiều Table (cùng thiết kế Fields)

    NguyenDungAnh > 20-07-18, 04:25 PM

    Private Sub cmdDong_Click()
    On Error GoTo Err_cmdDong_Click
        On Error Resume Next
        rs.Close
        Set rs = Nothing
        db.Close
        Set db = Nothing
        
        DoCmd.Close

    lúc đóng forms thì bị lỗi ở dòng rs.close
  • RE: FORM NHẬP LIỆU P1: Dùng 1 Form nhập cho nhiều Table (cùng thiết kế Fields)

    ongke0711 > 20-07-18, 08:56 PM

    (20-07-18, 04:23 PM)NguyenDungAnh Đã viết: Public Function MsgBoxUni(ByVal PromptUni As Variant, Optional ByVal Buttons As VbMsgBoxStyle = vbOKOnly, Optional ByVal TitleUni As Variant = vbNullString) As VbMsgBoxResult

    lại bị lỗi ở dòng này bác ạ. lúc thêm mới hay sửa thì bị

    Bạn copy lại dòng khai báo ở trên.
    Nguyên tác nếu là hàm API khi khai báo cho Win 64bit thì phải thêm từ khoá "PtrSafe" và kiểu "Long" phải đổi thành "LongPtr" nếu đó là biến con trỏ hoặc handle (có chữchữ hw, lp ở đầu tên biến). 

    Còn vụ lỗi rs.Close: Form này nó khởi động theo một trình tự từ Form danh sách để lấy các tham số từ OpenArgs do vậy khi bạn mở Form View từ chế độ Design của nó sẽ gặp một số lỗi liên quan đến biến. Nên test form theo logic của ứng dụng là mở form từ các menu của Form danh sách.
  • RE: FORM NHẬP LIỆU P1: Dùng 1 Form nhập cho nhiều Table (cùng thiết kế Fields)

    pvhung76 > 21-07-18, 04:56 PM

    (14-07-18, 05:27 PM)ongke0711 Đã viết: Dùng chung 1 Form nhập liệu (Unbound) cho các Table tham chiếu (dạng danh mục)

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

    Chào các bạn,

    Thấy tình hình diễn đàn khá im ắng bữa giờ nên kiếm chuyện post bài để thảo luận 014  007 .

    Các bạn đã từng vật vã với việc thiết kế các Table làm sao cho nó không thừa cũng không thiếu, dễ truy vấn dữ liệu, không chiếm tài nguyên bộ nhớ v.v.. Sau đó bước kế tiếp theo tôi cũng cực kỳ quan trọng là làm sao nhập liệu cho nó một cách chính xác, đủ, đúng dữ liệu. Do đó việc thiết kế một Form nhập liệu cũng phải cực kỳ cẩn trọng: làm sao để một người dùng phổ thông cũng có thể hiểu, thao tác nhập liệu dễ dàng và đảm bảo luôn nhập đúng yêu cầu của dữ liệu. Để làm được như vậy theo chút kinh nghiệm  của tôi thì cần quan tâm một số yếu tố chính như sau:
    - Giao diện (User Interface): dễ tập trung những chỗ nhập liệu, không rối mắt (font chữ, màu sắc, bố cục...) 
    - Trải nghiệm người dùng (User experience): người dùng dễ dàng thao tác nhập liệu đúng và nhanh, không bị bỡ ngỡ, bối rối (đánh đố người dùng) không biết nhập thông tin như thế nào, nhập ở đâu...
    - Nội dung: phải đảm bảo đủ, đúng yêu cầu của Table
    - Bẫy lỗi: tránh trường hợp nhập liệu sai, hướng dẫn người dùng nhập liệu đúng. Người ta có câu "Garbage In, Garbage Out" tức là bạn đưa dữ liệu sai (dữ liệu rác) vào thì kết quả nhận được từ nguồn dữ liệu đó cũng là rác. 007

    Về phần giao diện, trải nghiệm người dùng, tôi sẽ chia sẻ ở bài sau từ các bài tôi học được trên cộng đồng và dịch lại thôi (chưa đủ bản lĩnh để tự đưa ra các nguyên tắc thiết kế  014 ) . 

    Nói sơ khởi vậy thôi, sau đây là phần Form nhập liệu đơn giản nhưng code không phải thuộc sơ cấp (cách làm có thể gọi là "Suy nghĩ phức tạp để đưa ra giải pháp đơn giản"). Do trong thực tế khi có những table chứa dữ liệu để tham chiếu như: table giới tính, phòng ban, chức vụ, Dân tộc v.v.. mà dữ liệu nhập thì cũng đơn giản có vài field (như mã phòng ban, tên phòng ban, ghi chú). Ứng với mỗi table này mà thiết kế 1 form nhập liệu cho nó thì cũng tốn kém Form nên tôi đã điều chỉnh lại thiết kế table, form để có thể sử dụng nhập liệu chung cho tất cả các table trên thông qua 1 Form. 
    Demo trong bài là thực tế trong ứng dụng quản lý nhân sự tôi trích ra để minh hoạ.

    [Hình: 43350804152_9256bde161_o.png]

    Khi nhìn form danh sách trên, chắc chắn có bạn sẽ thắc mắc sao không cho nhập liệu trực tiếp lên trong form này luôn cho đỡ đơn giản, cần gì tạo form khác, code kiết chi cho dài dòng, chỉ cần AllowEdit= True, Data Entry=Yes hoặc AllowAddition = True là nhập luôn được rồi. Hơn nữa mấy form này chỉ nhập liệu vài lần lúc đầu rồi ít khi bổ sung thì cần gì làm cho cầu kỳ. 

    [Hình: 42494707765_3046f0de86_o.png]

    Cách làm như hình trên là nhanh nhất, ít tốn kém nhất nhưng tôi thì lại không ưa chuộng kiểu nhập liệu này (quan điểm, sở thích cá nhân) vì:
    - Nếu để người dùng có thể thao tác trực tiếp lên toàn bộ các record thì không an toàn nếu như khi đang ở chế độ chỉnh sửa, lỡ đụng chuột, đụng phím làm nó thay đổi dữ liệu ở các dòng khác không mong muốn và cũng không để ý thấy để sửa lại rồi lưu dẫn đến dữ liệu bị sai.
    - Nếu vô chế độ Data Entry = True thì không can thiệp được các dòng dữ liệu trước đó nhưng sẽ không nhìn thấy tổng thể dữ liệu đã có trước đó để thêm dữ liệu mới không bị trùng.
    Do đó cách thiết kế của tôi là luôn tạo 1 danh sách để xem tổng thể như trên rồi khi cần nhập liệu sẽ mở 1 Single Form để nhập/sửa dữ liệu (có thể Bound hoặc Unbound).
    Trong demo này tôi dùng 1 form nhập liệu là Unbound Form để đỡ phải bẫy lỗi tự động lưu dữ liệu của Bound Form 007 . Khi bấm vào Tab nào và muốn cập nhật dữ liệu cho table đó thì sẽ hiện lên Form nhập liệu với các tên Label được đổi theo tương ứng tên field của table đó. 

    Thủ thuật chia sẻ trong demo này:
    - Dùng OpenArgs. Truyền nhiều tham số thông qua OpenArgs.
    - Các hàm tự động Load record cho Unbound Form, AddNew, Update cho table từ Unbound Form.
    - Một số bẫy lỗi khi thao tác cập nhật dữ liệu.

    Một số hình demo:
    [Hình: 41591093200_a14675c6cb_o.png]

    [Hình: 42495103155_e284f8243e_o.png]

    Hy vọng sẽ có ích cho các bạn.

    Bài kế tôi sẽ chia sẻ với các bạn một số kiểu thiết kế Form nhập liệu (Bound và Unbound) để tham khảo.


    Link demo (Access 2013): http://www.mediafire.com/file/4cag4j7jzv...accdb/file

    Đã cho thì cho cho trót luôn đi! Cho em xin phần Queries trong data luôn đi,...!
    CHân thành cảm ơn đó!