• Thứ Năm, 25/12/2003 09:46 (GMT+7)

    Sử dụng lớp để thiết kế giao diện trong Access

     Lớp và phương thức lập trình hướng đối tượng đã được đưa vào Microsoft Access từ phiên bản Access 95, sử dụng ngôn ngữ VBA (Visual Basic for Application). Tuy nhiên, rất ít nhà phát triển ứng dụng Access sử dụng các khối lớp (class module). Bài báo này giới thiệu ứng dụng hữu ích của lớp trong thiết kế giao diện Access: tạo một lớp “điều khiển” tự động thay đổi màu nền của đối tượng được kích hoạt. Ở đây sẽ thực hiện cả chương trình sử dụng lớp và chương trình không sử dụng lớp để có sự so sánh.

     

    Giới thiệu nhanh về lớp

    Về cơ bản, một khối lớp là một khuôn mẫu cho một đối tượng. Đồi tượng/lớp có thể có các thuộc tính và phương thức (method) tương tự như các ActiveX. Để tạo một khối lớp mới trong Access 97/2000, vào cửa sổ Database và chọn Insert.Class Module từ trình đơn. Bạn có thể tạo thuộc tính cho khối lớp mới này theo hai cách: khai báo các biến trong phần khai báo toàn cục của khối lớp hoặc sử dụng các thủ tục Property.

    Hình 1: Màn hình tạo thủ tục

    Các thủ tục Property thường được dùng hơn vì nó cho phép kiểm tra tính đúng đắn của dữ liệu và các thao tác cần thiết khác khi đọc hoặc ghi thuộc tính. Để tạo thủ tục thuộc tính, vào khối lớp và chọn Insert.Procedure từ menu (hình 1). Điền vào tên của thủ tục mới. Chọn kiểu (Type) là Property và phạm vi (Scope) là Public, nhấn OK. Hai thủ tục thuộc tính mới sẽ được tạo ra. Thủ tục Let gán giá trị cho thuộc tính và thủ tục Get lấy giá trị của thuộc tính. Bạn có thể tạo các phương thức cho lớp bằng cách định nghĩa các hàm Public hoặc các thủ tục con trong khối lớp.

    Khi bạn tạo một lớp, lớp này có hiệu lực đối với Access và VBA Editor như bất kỳ ActiveX nào. Điều này có nghĩa là bạn có thể xem chi tiết của lớp mới trong Object Browser, sử dụng Auto List trong VBA Editor để hiển thị danh sách các thuộc tính, và sử dụng các phương thức cho bất kỳ biến nào khai báo theo kiểu lớp mới.

     

    Thay đổi màu của đối tượng kích hoạt

    Ví dụ này thực hiện thay đổi màu nền của đối tượng kích hoạt. Việc thực hiện khá đơn giản: Thay đổi màu nền của đối tượng thành màu cho trước nào đó ở sự kiện GotFocus và trả lại màu nền cũ của nó ở sự kiện LostFocus.

    Bạn tạo form frmExample1_NoClass để minh họa cho trường hợp không sử dụng lớp. frmExample1_NoClass (hình 2) có 4 đối tượng theo mô tả trong bảng 1. Ở đây sử dụng nhiều loại đối tượng (text box, combo box, và list box) để thể hiện tính tổng quát. Các đối tượng sẽ gọi ColorChangeGotFocus khi có sự kiện GotFocus và ColorChangeLostFocus khi có sự kiện LostFocus. Dưới đây là các đoạn mã xử lý:

     

    Private mOldColor As Long

    Private Const FOCUS_COLOR = 8421631

     

    Private Sub ColorChangeGotFocus (ctrl As Control, lngColor As Long)

      lngColor = ctrl.BackColor

      ctrl.BackColor = FOCUS_COLOR

    End Sub

    Private Sub ColorChangeLostFocus (ctrl As Control, lngColor As Long)

      ctrl.BackColor = mOldColor

    End Sub

     

    Private Sub lstLock1_GotFocus()

      ColorChangeGotFocus lstLock1, mOldColor

    End Sub

     

    Private Sub lstLock1_LostFocus()

      ColorChangeLostFocus lstLock1, mOldColor

    End Sub

     

    Trong sự kiện GotFocus, bạn lưu màu nền hiện tại của đối tượng trong biến mOldColor trước khi thay đổi. Trong sự kiện LostFocus, màu nền đối tượng được trả trở lại giá trị màu lưu trong biến mOldColor.

    Bây giờ, nếu bạn đổi tên một đối tượng thì bạn phải đổi tên của tất cả các thủ tục sự kiện liên quan vì các hàm thủ tục mới được tự động tạo ra theo tên mới của đối tượng. Ví dụ, nếu bạn đổi tên lstLock1 thì đồng thời phải thực hiện các thay đổi liên quan cho lstLock1_GotFocus và lstLock1_LostFocus. Việc thay đổi như trên với phát triển ứng dụng dùng lớp sẽ đơn giản hơn rất nhiều.

     

    Sử dụng lớp

    Bạn tạo form frmExample1_Class có giao diện và cách thức đổi màu nền giống như ví dụ trên, ngoại trừ đoạn mã xử lý được thay đổi sử dụng lớp ActiveControlChangeColor. Dưới đây là đoạn mã được đưa vào trong phần khai báo form.

    Hình 2: Form frmExample1_NoClass

     

    Private objLock1 As ActiveControlChangeColor

    Private objLock2 As ActiveControlChangeColor

    Private objUnLock1 As ActiveControlChangeColor

    Private objUnLock2 As ActiveControlChangeColor

     

    Private Sub Form_Open (Cancel As Integer)

      Set objLock1 = New ActiveControlChangeColor

      Set objLock1.ctrl = lstLock1

     

      Set objLock2 = New ActiveControlChangeColor

      Set objLock2.ctrl = txtLock2

     

      Set objUnLock1 = New ActiveControlChangeColor

      Set objUnLock1.ctrl = txtUnLock1

      ObjUnlock1.FocusColor = vbBlue

     

      Set objUnLock2 = New ActiveControlChangeColor

      Set objUnLock2.ctrl = cboUnLock2

    End Sub

     

    Toàn bộ đoạn mã cần thiết để thay đổi màu nền của đối tượng kích hoạt được giới hạn trong phần khai báo và thủ tục sự kiện Form_Open. Bạn phải khai báo các biến ở cấp độ form và khởi tạo các biến trong thủ tục sự kiện Form_Open. Thuộc tính ctrl của biến được gán giá trị đối tượng mà bạn sẽ thay đổi màu.

    Đoạn mã xử lý giờ đây gọn gàng và dễ quản lý hơn. Nếu có thay đổi tên đối  tượng thì bạn chỉ phải thay đổi một dòng mã lệnh. Ví dụ này minh họa một trong nhiều ưu điểm của lớp và lập trình hướng đối tượng.

     

    Phát triển lớp ActiveControl ChangeColor

    Tạo một khối lớp mới bằng cách vào cửa sổ Database và chọn Insert.Class Module từ trình đơn. Lớp mới tạo sẽ có 2 thuộc tính (bảng 2). Dưới đây là đoạn mã được đưa vào khối lớp mới tạo.

     

    Private Const FOCUS_COLOR = 8421631

     

    Private WithEvents mTextBox As TextBox

    Private WithEvents mComboTextBox As ComboBox

    Private WithEvents mListBox As ListBox

    Private mFocusColor As Long

    Private mOldColor As Long

     

    Public Property Set ctrl (vNewValue As Control)

     

      If  TypeOf  vNewValue  Is  TextBox Then

         Set mTextBox = vNewValue

         mTextBox.OnGotFocus = “[Event Procedure]”

         mTextBox.OnLostFocus = “[Event Procedure]”

     

     ElseIf  TypeOf  vNewValue  Is  ListBox Then

         Set mListBox = vNewValue

         mListBox.OnGotFocus = “[Event Procedure]”

         mListBox.OnLostFocus = “[Event Procedure]”

     

     ElseIf  TypeOf  vNewValue  Is  ComboBox Then

         Set mComboBox = vNewValue

         mComboBox.OnGotFocus = “[Event Procedure]”

         mComboBox.OnLostFocus = “[Event Procedure]”

     EndIf

     

    End Property

     

    Public Property Get FocusColor() As Variant

      FocusColor = mFocusColor

    End Property

     

    Public Property Let FocusColor(ByVal vNewValue As Variant)

      mFocusColor = vNewValue

    End Property

     

    Private Sub Class_Initialize()

      mFocusColor = FOCUS_COLOR

    End Sub

     

    Private Sub mTextBox_GotFocus()

      mOldColor = mTextBox.BackColor

      mTextBox.BackColor = mFocusColor

    End Sub

     

    Private Sub mTextBox_LostFocus()

      mTextBox.BackColor = mOldColor

    End Sub

     

    Trong ví dụ này, các thủ tục Property được sử dụng để định nghĩa các thuộc tính thay vì các biến toàn cục. Các thủ tục Property khai báo các biến cục bộ và thực hiện các tác vụ cần thiết khác. Không có thủ tục Property Let cho thuộc tính CTRL, nhưng có thủ tục Property Set thực hiện việc khởi tạo biến đối tượng.

    Khai báo biến với từ khóa WithEvents có ý nghĩa đối với khối lớp giống như việc đặt textbox lên form đối với Form Module. Khi đặt một textbox lên form và mở Form Module, bạn có thể chọn tên của textbox trong menu sổ xuống để xem danh sách thủ tục sự kiện có thể dùng cho textbox. Tương tự, trình soạn thảo VBA hiển thị các thủ tục sự kiện cho mTextBox khi mở khối lớp. Do mTextBox được khai báo là một textbox nên nó có cùng các sự kiện như textbox.

    Các đối tượng sẽ được gán cho mTextBox, mComboBox và mListBox khi lớp được dùng và thuộc tính CTRL của đối tượng được thiết lập. Bạn phải dùng các biến đối tượng khác nhau cho mỗi kiểu đối tượng khác nhau vì không thể dùng từ khóa WithEvents với kiểu đối tượng Control. Ví dụ, khai báo sau sẽ không được chấp nhận:

     

    Private WithEvents mControl As Control

     

    Để khắc phục hạn chế này, trong thủ tục Property Set, bạn kiểm tra kiểu Control và gán cho biến thích hợp.

    Chuỗi “[Event Procedure]” gán cho các thuộc tính OnGotFocus và OnLostFocus nhằm đảm bảo sự kiện có thể kích hoạt.

    Sau cùng, đoạn mã xử lý trong các sự kiện GotFocus và LostFocus thực hiện thay đổi màu nền theo yêu cầu. Bạn có thể sử dụng lại đoạn mã trong ví dụ không dùng lớp ở phần trên cho hai hàm này mà không phải sửa đổi gì cả.

    Bạn cũng có thể sử dụng sự kiện Class_initialize để gán giá trị mặc định cho thuộc tính FocusColor. Giá trị màu mặc định này được dùng nếu không màu nào khác được xác định lúc thực khi.

     

    Kết luận

    Việc sử dụng lớp trong ứng dụng Access có nhiều ưu điểm:

    - Đoạn mã xử lý trong form được tập trung trong thủ tục sự kiện Form_open thay vì nằm rải rác trong nhiều thủ tục.

    - Đoạn mã xử lý dễ dùng lại hơn và dễ bảo trì hơn.

    Việc phát triển khối lớp yêu cầu nhiều công sức thiết kế hơn, nhưng nó sẽ giúp bạn tiết kiệm được nhiều thời gian khi phát triển các ứng dụng tiếp sau.

    Thanh Phong

    Access-VB-SQL Advisor 10/2001

     

     

    ID: A0202_72