Tìm trong:Webe-CHÍP

Bộ gõ (kiểu Vni/Telex/Viqr)Tắt (Alt+T)Mở (Alt+M)

 
Trang chủ ĐÓ HỎI, ĐÂY TRẢ LỜI TC 125

Quản lý trình đơn trong Access

Đó hỏi: Tôi đã làm xong form bảo mật và phân quyền trong Access. Tôi muốn khi đăng nhập vào chương trình, đối với mỗi username và passord, chỉ được chọn một mục trên menu bar, còn các mục khác thì mờ đi. Mong e-CHÍP chỉ giúp. (Vanbang_sg@)

Đây trả lời: Có một số vấn đề cơ bản bạn cần nắm:
• Một menu bar là một đối tượng CommandBar và thực chất là một tool bar có thuộc tính Type là Menu Bar. Như hình 1, một menu bar gồm một hay nhiều pad menu (như Hệ thống, Tập tin,...), mỗi pad menu lại có một popup trong đó có một hay nhiều menu item (như Mở tập tin, Kết thúc,...). Đến lượt mình, mỗi menu item có thể có một popup.
• Mỗi pad menu, menu item là một đối tượng CommandBarControl và đều có thuộc tính Tag để ta có thể sử dụng như là tên phân biệt. Ví dụ: bạn có thể đặt thuộc tính Tag cho mục Hệ thống là HeThong, cho mục Tập tin là TapTin, còn mục Mở tập tin là sysMoTapTin (từ sys để ám chỉ mục này thuộc nhóm chức năng liên quan đến pad menu Hệ thống). Không nên đặt tên có dấu tiếng Việt vì khi lập trình VBA có thể gặp lỗi về tên biến.
• Hệ thống menu bar có thể gồm nhiều cấp tùy theo tổ chức các chức năng trong ứng dụng của bạn. Tuy nhiên, để đơn giản, bạn chỉ nên phân quyền đến mức đầu tiên (như hình 1). Khi đã quen, bạn mới tổ chức phân quyền sâu hơn.
• Ngoài ra, nếu được thì bạn nên tổ chức thêm cấp nhóm người sử dụng (group) rồi phân quyền theo nhóm người sử dụng lẫn từng người sử dụng.
• Bạn nên tạo một table chi tiết (giả sử có tên tbChiTietMenu) có cấu trúc gồm một field UserName (để liên kết one-to-many với table chứa thông tin người sử dụng) và một field TagDuocPhep (chứa thông tin về mục chọn trên menu có Tag tương ứng được phép sử dụng). Như vậy, nếu một user name được phép sử dụng 5 mục thì tương ứng sẽ có 5 record trong table tbChiTietMenu.
• Ứng với một user name (sau khi login vào ứng dụng), bạn thực hiện một query để lọc ra từ table tbChiTietMenu các record cho biết thông tin về các tên Tag được phép. Sau đó, lần lượt đọc từng record và cho hiển thị (thuộc tính Enabled = True) mục đó trên menu bar.
Ví dụ sau đây minh họa cách thay đổi thuộc tính Enabled cho các mục chọn trên menu dựa trên thuộc tính Tag. Trước tiên, bạn thiết kế một menu có tên tbrQuanLyMenu gồm các mục như hình 1. Lần lượt đặt thuộc tính Tag cho mục Hệ thống là HeThong, cho mục Tập tin là TapTin, còn mục Mở tập tin là sysMoTapTin (hình 2). Tạo một form mới và vẽ lên form các nút lệnh có tên cmdNotHeThong, cmdNotTapTin, cmdNotMoTapTin rồi gõ đoạn mã 1 vào form.
Để sử dụng hành vi FindControl, trong cửa sổ soạn thảo VBA, bạn chọn Tools > References, chọn mục Microsoft Office 11.0 Object Library trong hộp thoại References. Bạn lưu ý thông số Recursive trong hành vi FindControl để yêu cầu tìm hết các CommandBarControl trên menu bar.

Hình 1: Menu bar cần thiết kế

Hình 2: Đặt thuộc tính Tag

Đoạn mã 1

Dim myMenu As CommandBar
Private Sub Form_Load()
  Set myMenu = CommandBars("tbrQuanLyMenu")
End Sub
Private Sub cmdNotHeThong_Click()
  Dim popCtrl As CommandBarControl
  Set popCtrl = myMenu.FindControl(Type:=msoControlPopup, Tag:="HeThong")
  If Not (popCtrl Is Nothing) Then
    popCtrl.Enabled = False
  End If
End Sub
Private Sub cmdNotTapTin_Click()
  Dim popCtrl As CommandBarControl
  Set popCtrl = myMenu.FindControl(Type:=msoControlPopup, Tag:="TapTin")
  If Not (popCtrl Is Nothing) Then
    popCtrl.Enabled = False
  End If
End Sub
Private Sub cmdNotMoTapTin_Click()
  Dim popCtrl As CommandBarControl
  Set popCtrl = myMenu.FindControl(Type:=msoControlPopup, _
  Tag:="sysMoTapTin", Recursive:=True)
  If Not (popCtrl Is Nothing) Then
    popCtrl.Enabled = False
  End If
End Sub

Sắp xếp phòng thi bằng Access

Đó hỏi: Để sắp xếp phòng thi cho học sinh, tôi dùng hai bảng trong Access: table1 có hai cột PHONGTHI và SOLUONG, table2 có các cột SBD, HOTEN, MONTHI, PHONGTHI. Tôi muốn gán tên phòng thi ở table1 vào tên phòng thi ỏ table2 với điều kiện: những học sinh có cùng môn thi thì ở chung phòng thi và số học sinh không được quá số lượng trong table1, nếu vượt quá số lượng thì cho qua phòng kế tiếp. Xin hướng dẫn. (vanbang_sg@)

Đây trả lời: Ví dụ sau đây dựa trên hai bảng có tên tbDSPhongThi (vai trò như table1 của bạn) và tbDSThiSinh (vai trò như table2 của bạn), trong đó field PhongThi của tbDSPhongThi có thuộc tính Index là Yes (No Duplicates) (không phải là Primary Key), và field MonThi của tbDSThiSinh cũng có thuộc tính Index là Yes (No Duplicates). Việc tạo index chỉ để sắp thứ tự các thí sinh của cùng môn thi vào một nhóm, cũng như sắp thứ tự phòng thi theo tên.
Trên form bạn vẽ một nút lệnh có tên cmdSapXepPhongThi, rồi gõ đoạn mã 2 vào thủ tục xử lý tình huống Click.
Căn cứ vào ví dụ này, bạn có thể áp dụng vào nhu cầu thực tế của mình. Bạn lưu ý: để sử dụng các đối tượng Database và Recordset, trong cửa sổ soạn thảo VBA, bạn chọn Tools > References, rồi chọn mục Microsoft DAO 3.6 Object Library (hoặc phiên bản cao nhất của DAO Object Library) trong hộp thoại References.

Đoạn mã 2

Private Sub cmdSapXepPhongThi_Click()
     Dim db As Database, rsDSPhongThi As Recordset, rsDSThiSinh As Recordset
     Dim sMonThi As String, nSoLuongHienHanh As Byte
     Set db = CurrentDb
     Set rsDSPhongThi = db.OpenRecordset("tbDSPhongThi")
     Set rsDSThiSinh = db.OpenRecordset("tbDSThiSinh")
     rsDSPhongThi.Index = "PhongThi"   
' Không phải Primary key, chỉ để sắp thứ tự
     rsDSPhongThi.MoveFirst
     rsDSThiSinh.Index = "MonThi" 
' Không phải Primary key, chỉ để sắp thứ tự
     With rsDSThiSinh
          nSoLuongHienHanh = 0
          .MoveFirst
          sMonThi = !MonThi
          Do While Not .EOF
               If !MonThi <> sMonThi Then
' Sang môn thi khác
                    rsDSPhongThi.MoveNext 
' Sang phòng thi khác
                    If rsDSPhongThi.EOF Then
' Hết phòng
                         MsgBox "Hết phòng thi rồi!"
                         Exit Do
                    End If
                    nSoLuongHienHanh = 0
                    sMonThi = !MonThi
               End If
               If nSoLuongHienHanh >= rsDSPhongThi!SoLuong Then ' Het cho
                    rsDSPhongThi.MoveNext 
' Sang phòng thi khác
                    If rsDSPhongThi.EOF Then
' Hết phòng
                         MsgBox "Hết phòng thi rồi!"
                         Exit Do
                    End If
                    nSoLuongHienHanh = 0
               End If
               .Edit
               !PhongThi = rsDSPhongThi!PhongThi
               .Update
               nSoLuongHienHanh = nSoLuongHienHanh + 1
               .MoveNext
          Loop
     End With
     rsDSThiSinh.Close
     rsDSPhongThi.Close
     db.Close
End Sub

Khai Trí

[Đầu trang]