Khi đang thực hiện thao tác thêm mới hay chỉnh sửa dữ liệu trên Form, nếu người dùng di chuyển sang mẩu tin khác thì MS Access sẽ tự động ghi nhận mẩu tin mới thêm hay những thay đổi của mẩu tin hiện hành xuống cơ sở dữ liệu. Ta có thể tận dụng tính năng này để lưu tự động các mẩu tin thêm mới hay mẩu tin được cập nhật xuống bảng dữ liệu nguồn của Form.
Bên cạnh đó, ta có thể lấy lại giá trị cũ của điều khiển sau khi bị thay đổi bằng cách nhấn phím ESC, với điều kiện là giá trị mới thay đổi chưa được cập nhật xuống bảng.
Nhấn phím ESC hai lần để bỏ qua thao tác thêm mới hay những thay đổi dữ liệu vừa thực hiện trên mẩu tin hiện hành của Form.
Chứng chỉ B Tin Học Quốc Gia Trang 95/131
Ở trên là 2 cơ chế tự động xử lý dữ liệu thay đổi trên Form do môi trường Access cung cấp. Ngoài ra, Access còn cung cấp các lệnh để thực hiện việc xử lý ghi hay không ghi dữ liệu thay đổi trên Form một cách tường minh.
Sau đây ta sẽ tìm hiểu cách tạo chức năng lưu trữ dữ liệu trên Form bằng các lệnh do ngôn ngữ VBA hỗ trợ.
IV.1. Lưu dữ liệu trên Form xuống bảng IV.1.1. Thao tác lưu dữ liệu bằng lệnh
Tương tự như 2 chức năng thêm và sửa, việc lưu dữ liệu cũng có thể được quản lý bởi các chức năng do người tạo Form thiết kế mà không sử dụng cơ chế tự động lưu của Access. Chức năng lưu dữ liệu trên Form thường được thực hiện thông qua đối tượng Command Button.
Trong cửa sổ viết lệnh của VBA ta sẽ dùng bộ lệnh DoCmd để lưu dữ liệu trên Form theo cú pháp sau:
DoCmd.RunCommand acCmdSaveRecord
Một số lưu ý khi thiết kế chức năng lưu dữ liệu của Form:
Ta phải vô hiệu hoá các nút di chuyển trên Form (nếu có) để tránh việc người sử dụng di chuyển sang mẩu tin khác trước khi gọi chức năng lưu dữ liệu, nếu người dùng di chuyển trước khi gọi thực hiện lệnh lưu thì chức năng lưu dữ liệu sẽ không còn ý nghĩa. Khi lưu dữ liệu ta cần thực hiện thao tác kiểm tra một số ràng buộc liên quan đến dữ liệu như: ràng buộc về khoá chính, khoá ngoại, ràng buộc về kiểu dữ liệu và miền giá trị.
Chức năng lưu dữ liệu có 2 ngữ cảnh: lưu trong trường hợp đang thêm mới và lưu khi đang sửa dữ liệu. Trong mỗi trường hợp có một số thao tác xử lý khác nhau và một số thao tác thì hoàn toàn giống nhau.
Vì chức năng lưu dữ liệu sẽ được thực hiện sau khi người sử dụng gọi thực hiện thao tác Thêm hay Sửa cho nên ta phải thực hiện một số thao tác để thiết lập lại giá trị của các thuộc tính của Form và của điều khiển cho phù hợp. Ví dụ khi thực hiện chức năng thêm thì ta gán thuộc tính AllowAdditions là True, sau khi lưu dữ liệu phải thiết lập giá trị của thuộc tính là AllowAdditions lại là False.
IV.1.2. Các bước thực hiện
Bước 1: Kiểm tra dữ liệu cần lưu là thêm mới hay do chỉnh sửa để có xử lý thích hợp
Bước 2: Kiểm tra ràng buộc về khoá chính, khoá ngoại, miền giá trị, kiểu dữ liệu. Thiết lập các thuộc tính cần thiết
Nếu đang thêm mới thì:
+ Kiểm tra tất cả các ràng buộc trên
Chứng chỉ B Tin Học Quốc Gia Trang 96/131
Nếu đang sửa thì:
+ Kiểm tra tất cả các ràng buộc trên ngoại trừ ràng buộc về khoá chính
+ Gán giá trị cho thuộc tính AllowEdits
+ Mở khoá cho các điều khiển là khoá chính Bước 3: Thực hiện lệnh ghi dữ liệu
Bước 4: Cập nhật trạng thái các điều khiển trên Form Sau đây là chi tiết các bước thực hiện
Bước 1: Kiểm tra trạng thái của dữ liệu hiện hành trên Form
Để biết được trạng thái dữ liệu hiện hành của Form ta dùng thuộc tính NewRecord của Form để biết Form hiện hành đang được thêm dữ liệu hay dữ liệu trên Form đang sửa. Thuộc tính NewRecord có kiểu là Boolean. Nếu giá trị của NewRecord bằng True thì
Form đang được thêm mới, ngược lại thì dữ liệu đang được sửa.
Ví dụ:
Khi Click vào nút Ghi ta cần kiểm tra xem Form đang thêm hay đang sửa
Chọn sự kiện click của nút Ghi, giả sử đặt tên cho nút là cmdGhi Trong thủ tục của sự kiện click ta viết đoạn lệnh sau:
Private Sub cmdGhi_Click() If NewRecord = True Then
‘ thực hiện các xử lý trong trường hợp đang thêm Else
‘ thực hiện các xử lý trong trường hợp sửa dữ liệu End If
End Sub
Bước 2: Kiểm tra ràng buộc và thiết lập thuộc tính liên quan
Thao tác kiểm tra ràng buộc sẽ được trình bày ở phần bên dưới. Thiết lập giá trị cho các thuộc tính liên quan tuỳ theo từng trường hợp:
+ AllowAdditions = False: nếu ghi khi đang thêm mới mẩu tin
+ AllowEdits = False: nếu đang thực hiện thao tác sử mẩu tin hiện hành
Chứng chỉ B Tin Học Quốc Gia Trang 97/131
+ Thuộc tính Locked của các điều khiển là khoá chính được gán là False
Ví dụ:
Khi Click vào nút Ghi xử lý gán giá trị cho các thuộc tính tuỳ theo trạng thái của Form:
Private Sub cmdGhi_Click() If NewRecord = True Then AllowAdditions = False Else AllowEdits = False txtMaNV.Locked = False End If End Sub
Bước 3: Thực hiện lệnh ghi dữ liệu
Thực hiện câu lệnh: DoCmd.RunCommand acCmdSaveRecord.
Bước 4: Cập nhật trạng thái các điều khiển
Sau khi thực hiện thao tác ghi dữ liệu, ta cần trả lại trạng thái của điều khiển trên Form giống như trước khi thực hiện thao tác Thêm hay Sửa.
Ví dụ: trên màn hình có nhóm chức năng Thêm, Sửa, Xoá, Ghi, Không. Ban đầu trước khi chọn chức năng Sửa thì bộ nút (Thêm, Sửa, Xoá) ở trạng thái sáng và (Ghi, Không) ở trạng thái mờ. Khi đang thực hiện chức năng Sửa thì sẽ làm mờ các điều khiển của chức năng (Thêm, Sửa, Xoá) và cho chức năng (Ghi, Không) ở trạng thái sáng. Do đó, sau khi thực hiện ghi dữ liệu thì trạng thái của các nút chức năng phải quay lại giống như trước khi sửa.
IV.1.3. Ví dụ
Private Sub cmdGhi_Click() If NewRecord = True Then AllowAdditions = False Else AllowEdits = False txtManv.Locked = False End If DoCmd.RunCommand acCmdSaveRecord ‘ Cho sáng các chức năng Thêm, Xoá, Sửa cmdThem.Enabled = True cmdSua.Enabled = True cmdXoa.Enabled = True ‘ Mờ 2 nút Ghi, Không cmdGhi.Enabled = False cmdKhong.Enabled = False End Sub
Chứng chỉ B Tin Học Quốc Gia Trang 98/131
IV.2. Kiểm tra ràng buộc khi lưu IV.2.1. Những ràng buộc cần kiểm
+ Các ràng buộc về khoá: − Khoá chính rỗng − Khoá chính trùng
− Sự tồn tại của khoá ngoại
+ Kiểm tra miền giá trị của các Field
+ Kiểm tra về kiểu dữ liệu của Field
IV.2.2. Kiểm tra ràng buộc về khoá
Thao tác kiểm tra khoá rỗng và khoá trùng sẽ được thực hiện trước khi dữ liệu của Form được ghi xuống các bảng. Trước khi dữ liệu được ghi ta có thể xử lý ở 2 sự kiện tuỳ theo thiết kế của form:
Nếu Form sử dụng chế độ ghi tự động của Access thì ta sẽ xử lý trong sự kiện BeforeUpdate của Form.
Khi trên Form có chức năng Ghi (nút Ghi) thì ta sẽ thực hiện việc kiểm tra khoá trong sự kiện click của nút, đoạn lệnh kiểm tra sẽ đặt trước lệnh ghi dữ liệu.
Khoá chính rỗng
Khi nhập dữ liệu cho bảng, ta phải đảm bảo giá trị của Field là khoá chính trong bảng phải được nhập, nếu không có giá trị thì ta sẽ yêu cầu người dùng nhập vào.
Để kiểm tra khoá chính rỗng, ta sử dụng hàm IsNull với đối tượng cần kiểm tra.
Ví dụ:
Để kiểm tra khoá chính của Form trên, giá trị của Mã nhân viên, có bị rỗng hay không ta thực hiện như sau:
Chọn sự kiện click của nút Ghi, giả sử đặt tên cho nút là cmdGhi Trong thủ tục của sự kiện click ta viết đoạn lệnh sau:
Chứng chỉ B Tin Học Quốc Gia Trang 99/131
Private Sub cmdGhi_Click() If IsNull(txtManv) Then
MsgBox “Ma nhan vien khong duoc rong” Exit Sub
End If End Sub
Khoá chính trùng
Giá trị của Field là khoá chính khi thêm mới phải phải khác với những giá trị đã có trong bảng đang thêm. Nếu người dùng nhập một giá trị đã có thì phải thông báo và yêu cầu họ nhập lại. Việc kiểm tra trùng khoá có thể được thực hiện bằng hàm DCount hay DLookup.
Ví dụ:
Lấy lại ví dụ trên, thao tác kiểm tra khoá chính trùng bằng DCount như sau:
Private Sub cmdGhi_Click()
If DCount(“MaNv”, “DMNV”, “MaNv = ‘” & txtMaNv & “’”) Then MsgBox “Ma nhan vien nay co roi”
Exit Sub End If
DoCmd.RunCommand acCmdSaveRecord End Sub
Lấy lại ví dụ trên, thao tác kiểm tra khoá chính trùng bằng DLookup như sau:
Private Sub cmdGhi_Click()
If Not IsNull(DLookup(“MaNv”, “DMNV”, “MaNv = ‘” & txtMaNv & “’”)) Then MsgBox “Ma nhan vien nay co roi, hay nhap ma nv khac”
Exit Sub End If
DoCmd.RunCommand acCmdSaveRecord End Sub
Sự tồn tại của khoá ngoại
Khi thực hiện thao tác thêm hay sửa dữ liệu cho những bảng có mối quan hệ nhiều với bảng khác ta cần phải chú ý đến giá trị những Field là khoá ngoại của bảng. Khi nhập giá trị cho Field là khoá ngoại của bảng, phải kiểm tra giá trị nhập phải tồn tại trong bảng có quan hệ một với bảng đang thêm.
Thao tác kiểm tra sự tồn tại của khoá ngoại có thể được thực hiện trước khi dữ liệu trên điều khiển chứa Field khoá ngoại được ghi xuống bảng. Trước khi dữ liệu trên điều khiển được ghi xuống bảng, nó sẽ phát sinh ra sự kiện BeforeUpdate, ta sẽ viết lệnh xử lý trong sự kiện này của điều khiển.
Sử dụng hàm DCount hay DLookup để kiểm tra sự tồn tại của khoá ngoại như sau:
Chứng chỉ B Tin Học Quốc Gia Trang 100/131
Trong mối quan hệ trên, khi thêm dữ liệu vào trong bảng DMNV ta phải kiểm tra sự tồn giá trị của Field MATO trong bảng DMTO
Để kiểm tra sự tồn tại của Mã tổ khi nhập dữ liệu cho Form trên, Form dùng để cập nhật dữ liệu cho bảng DMNV, ta thực hiện như sau:
Đặt tên cho TextBox chứa mã tổ là txtMaTo Chọn sự kiện BeforeUpdate của txtMaTo
Trong thủ tục của sự kiện BeforeUpdate ta viết đoạn lệnh sau đây:
Private Sub txtMaTo_BeforeUpdate(Cancel As Integer)
If DCount("MaTo", "DMTO", "MaTo = '" & txtMaTo & "'") = 0 Then MsgBox "Ma to nay chua co trong co so du lieu"
Cancel = True End If
End Sub
Giá trị Cancel = True trong sự kiện trên dùng để bỏ qua thao tác ghi dữ liệu trên điều khiển và giữ con trỏ lại để người sử dụng nhập giá trị khác.
IV.2.3. Ràng buộc miền giá trị
Miền giá trị của một Field là những ràng buộc dữ liệu do người sử dụng đặt ra và khi nhập dữ liệu chương trình có nhiệm vụ kiểm tra giá trị nhập phải thoả mãn những qui định đó, ví dụ như qui định tuổi của một nhân viên nằm trong khoảng từ 22 đến 50.
Thao tác kiểm tra miền giá trị của Field nên thực hiện trước khi dữ liệu trên điều khiển chứa Field được ghi xuống bảng giống như khi kiểm tra sự tồn tại của khoá ngoại.
Chứng chỉ B Tin Học Quốc Gia Trang 101/131
Giả sử ta qui định tuổi của nhân viên phải từ 22 đến 50 thì khi nhập thông tin cho nhân viên trên Form trên, ta phải kiểm tra như sau:
Đặt tên cho Text Box chứa ngày sinh là txtNgaySinh Chọn sự kiện BeforeUpdate của txtNgaySinh
Trong thủ tục của sự kiện BeforeUpdate ta viết đoạn lệnh sau đây:
Private Sub txtNgaySinh_BeforeUpdate(Cancel As Integer) Dim tuoi As Integer
tuoi = Year(Now) – Year(txtNgaySinh) If tuoi < 22 Or tuoi > 50 Then
MsgBox "Tuoi cua nhan vien khong hop le, hay nhap lai" Cancel = True
End If End Sub
Giá trị Cancel = True trong sự kiện trên dùng để bỏ qua thao tác ghi dữ liệu trên điều khiển và giữ con trỏ lại để người sử dụng nhập giá trị khác
IV.2.4. Kiểm tra kiểu dữ liệu
Khi nhập dữ liệu cho các Field trên Form có một lỗi thường gặp đó là nhập sai kiểu dữ liệu cho những Field có kiểu ngày hay kiểu số. Khi có lỗi về kiểu dữ liệu Form sẽ tự động phát sinh ra sự kiện Error, ta sẽ viết lệnh xử lý về kiểu dữ liệu trong thủ tục của sự kiện này.
Để kiểm tra kiểu dữ liệu của một giá trị trên điều khiển ta sử dụng các hàm như: IsNumeric, IsDate.
Chứng chỉ B Tin Học Quốc Gia Trang 102/131
Giá trị của Field Phái trên màn hình trên phải là số, do đó nếu người dùng nhập giá trị chuỗi cho Field này thì sẽ phát sinh ra lỗi về kiểu dữ liệu.
Ta thực hiện thao tác xử lý lỗi bằng cách sau: Chọn sự kiện On Error của Form
Đặt tên của Text Box chứa Field phái là txtPhai Trong thủ tục của sự kiện Error ta viết đoạn lệnh sau:
Private Sub Form_Error(DataErr As Integer, Response As Integer) If Not IsNumeric(txtPhai.Text) Then
MsgBox "Phai cua nhan vien phai la so" Response = 0
End If End Sub
Giá trị Response = 0 trong sự kiện trên dùng để bỏ qua thông báo lỗi mà hệ thống sẽ phát sinh trong sự kiện On Error khi có lỗi. Ở đây ta sẽ sử dụng những thông báo của mình và bỏ qua những thông báo của hệ thống.
Giá trị của Field Ngày sinh trên màn hình trên phải là ngày, do đó nếu người dùng nhập giá trị chuỗi cho Field này thì sẽ phát sinh ra lỗi về kiểu dữ liệu.
Ta thực hiện thao tác xử lý lỗi bằng cách sau: Chọn sự kiện On Error của Form
Đặt tên của Text Box chứa Field Ngày Sinh là txtNgaySinh Trong thủ tục của sự kiện Error ta viết đoạn lệnh sau:
Private Sub Form_Error(DataErr As Integer, Response As Integer) If Not IsDate(txtNgaySinh.Text) Then
MsgBox "Ngay sinh phai la kieu ngay" Response = 0
End If End Sub
Chứng chỉ B Tin Học Quốc Gia Trang 103/131
IV.3. Không lưu dữ liệu mới thay đổi trên Form IV.3.1. Cơ chế không lưu dữ liệu trên Form
Giống với những chức năng trên, ta có thể can thiệp vào việc không lưu dữ liệu mới cập nhật trên Form bằng cách thực thi một hành động Undo của Form.
Khi thi hành hành động Undo của Form, chương trình sẽ bỏ qua những thay đổi dữ liệu vừa thực hiện trên màn hình tại mẩu tin hiện hành, tương tự như khi ta nhấn phím ESC 2 lần. Một điểm lưu ý là khi thực hiện lệnh Undo thì lệnh này sẽ phục hồi nguồn dữ liệu của Form về trạng thái trước khi có sự thay đổi và nếu ta đang thêm mới mẩu tin thì sau khi Undo ta vẫn đứng ở dòng dữ liệu trống, dòng dữ liệu do lệnh thêm mới di chuyển đến.
Do đó, khi ta gọi lệnh không ghi trong trường hợp đang thêm mới thì mẩu tin hiện hành của Form vẫn đứng tại vị trí mẩu tin trống, điều này có thể làm cho người sử dụng khó hiểu. Vì vậy, cùng với thao tác không ghi dữ liệu, ta nên kết hợp với việc di chuyển đến một mẩu tin nào đó trong nguồn dữ liệu, thường là mẩu tin đầu tiên hay mẩu tin cuối cùng.
IV.3.2. Các bước thực hiện chức năng không lưu dữ liệu
Bước 1: Gọi lệnh phục hồi dữ liệu cho Form
Bước 2: Kiểm tra xem dữ liệu trên Form là đang thêm mới hay đang sửa để di chuyển mẩu tin Bước 3: Cập nhật trạng thái các điều khiển trên Form
Chi tiết thực hiện các bước:
Bước 1: Gọi lệnh phục hồi dữ liệu cho Form
Chọn sự kiện của điều khiển sẽ thực hiện thao tác không lưu. Gọi thực hiện hành động Undo của Form.
Bước 2: Kiểm tra xem dữ liệu trên Form là đang thêm mới hay đang sửa để di chuyển mẩu tin
Sử dụng thuộc tính NewRecord của Form để biết dữ liệu của Form đang thêm hay sửa.
Nếu đang thêm thì di chuyển đến mẩu tin cuối cùng, còn nếu đang sửa thì mở khoá cho các điều khiển chứa Field khoá chính.
Bước 3: Cập nhật trạng thái các điều khiển trên Form
Chứng chỉ B Tin Học Quốc Gia Trang 104/131