Giáo trình Nhập môn hệ quản trị cơ sở dữ liệu - Nguyễn Kim Sao (Phần 2)

CHƢƠNG 7: LẬP TRÌNH CƠ SỞ DỮ LIỆU TRONG MS ACCESS

1. Giới thiệu lập trình Visual Basic Application

MS Access không chỉ đơn thuần là một hệ quản trị cơ sở dữ liệu (CSDL) quan hệ mà

nó còn cung cấp một môi trƣờng lập trình với các công cụ khá đầy đủ, dễ sử dụng để

phát triển các ứng dụng quản lý vừa và nhỏ.

Ngôn ngữ lập trình đƣợc phát triển trong MS Access là Access Basic. Tuy nhiên từ

phiên bản MS Access for Windows 95, Access Basic đƣợc thay thế bởi Visual Basic

(VB). Hai ngôn ngữ này khá giống nhau và đều đƣợc phát triển từ một thành phần

thiết kế chung. Nhƣng ngày nay, VB trở thành ngôn ngữ lập trình chung của chƣơng

trình ứng dụng MS Office bao gồm: Access, Excel, Word, PowerPoint và đƣợc gọi là

VBA (Visual Basic for Applications). Việc có đƣợc một ngôn ngữ lập trình chung

xuyên suốt mọi chƣơng trình ứng mang lại một số lợi điểm quan trọng là:

pdf 112 trang phuongnguyen 6780
Bạn đang xem 20 trang mẫu của tài liệu "Giáo trình Nhập môn hệ quản trị cơ sở dữ liệu - Nguyễn Kim Sao (Phần 2)", để tải tài liệu gốc về máy hãy click vào nút Download ở trên

Tóm tắt nội dung tài liệu: Giáo trình Nhập môn hệ quản trị cơ sở dữ liệu - Nguyễn Kim Sao (Phần 2)

Giáo trình Nhập môn hệ quản trị cơ sở dữ liệu - Nguyễn Kim Sao (Phần 2)
131 
CHƢƠNG 7: LẬP TRÌNH CƠ SỞ DỮ LIỆU TRONG MS ACCESS 
1. Giới thiệu lập trình Visual Basic Application 
MS Access không chỉ đơn thuần là một hệ quản trị cơ sở dữ liệu (CSDL) quan hệ mà 
nó còn cung cấp một môi trƣờng lập trình với các công cụ khá đầy đủ, dễ sử dụng để 
phát triển các ứng dụng quản lý vừa và nhỏ. 
Ngôn ngữ lập trình đƣợc phát triển trong MS Access là Access Basic. Tuy nhiên từ 
phiên bản MS Access for Windows 95, Access Basic đƣợc thay thế bởi Visual Basic 
(VB). Hai ngôn ngữ này khá giống nhau và đều đƣợc phát triển từ một thành phần 
thiết kế chung. Nhƣng ngày nay, VB trở thành ngôn ngữ lập trình chung của chƣơng 
trình ứng dụng MS Office bao gồm: Access, Excel, Word, PowerPoint và đƣợc gọi là 
VBA (Visual Basic for Applications). Việc có đƣợc một ngôn ngữ lập trình chung 
xuyên suốt mọi chƣơng trình ứng mang lại một số lợi điểm quan trọng là: 
 Ngƣời lập trình chỉ cần biết một ngôn ngữ lập trình để tùy biến, phát triển 
ứng dụng. 
 Dễ dàng hợp nhất các đối tƣợng trong các chƣơng trình ứng dụng. 
VBA là ngôn ngữ có một số đặc điểm: 
 Không phân biệt chữ hoa, thƣờng 
 Hƣớng sự kiện và hƣớng đối tƣợng 
Việc tổ chức chƣơng trình theo mô hình hƣớng đối tƣợng và hƣớng sự kiện khiến cho 
các mã lệnh của chƣơng trình, suy cho đến cùng nhất, chỉ đƣợc gọi khi có sự kiện 
(event) nào đó xảy ra trên các đối tƣợng (object) cụ thể. Sự kiện của các đối tƣợng 
đƣợc sinh ra có thể do ngƣời dùng tác động chuột/bàn phím vào điều khiển. Ví dụ sự 
kiện OnClick() của điều khiển Button trên form. Sự kiện cũng có thể đƣợc sinh ra 
trong quá trình biên dịch. Ví dụ sự kiện Load() của một form. Tuy nhiên, không phải 
bất kỳ đối tƣợng nào cũng có các sự kiện. Các đối tƣợng là các điều khiển (control) 
đƣơng nhiên có các sự kiện. Ví dụ TextBox, CommandButton, Form,  đều có các sự 
kiện; trong khi đó đối tƣợng DBEngine lại không thể có sự kiện nào. 
Nhƣ vậy, toàn bộ mã lệnh của chƣơng trình ứng dụng Access đƣợc tổ chức là các 
hàm/thủ tục (function/sub) độc lập, bình đẳng (chúng ta sẽ phân biệt hàm và thủ tục 
trong phần sau). Không có hàm/thủ tục nào là cha, chứa các hàm/thủ tục khác. Không 
có “điểm vào” của chƣơng trình. Nghĩa là, không có hàm/thủ nào đƣợc chƣơng trình 
gọi trƣớc nhất để từ đó gọi đến các hàm/thủ tục khác. Tất cả các hàm/thủ tục chỉ đƣợc 
gọi để đáp ứng các sự kiện tƣơng ứng hoặc đƣợc gọi tƣờng minh trong hàm/thủ tục 
khác. 
132 
Chƣơng này sẽ trình bày các nội dung sau: 
 Module và Access Class Object 
 Các kiểu dữ liệu, hằng và biến 
 Các cấu trúc điều khiển 
 Hàm và thủ tục 
 Các mô hình truy cập CSDL 
2. Module 
Module là một đối tƣợng nguyên thủy của môi trƣờng lập trình VBA. Toàn bộ mã 
lệnh VBA trong CSDL đƣợc lƣu trong module dƣới dạng các thủ tục (gồm hàm và thủ 
tục con). Các thủ tục này có thể độc lập hoặc liên quan đến form/report. 
Nói cách khác, module là một phƣơng tiện của MS Access để giúp ngƣời lập trình tổ 
chức mã nguồn của họ sao cho “gọn gàng”, dễ kiểm soát. Ví dụ, ngƣời lập trình nên 
gom các đoạn mã (hàm/thủ tục) làm việc với CSDL vào một module đặt tên là 
DataAccessModule, gom các đoạn mã là việc với form vào một module đặt tên là 
FormModule hay nên viết ra một lớp Student (Class Module) để làm việc với các bản 
ghi thuộc bảng Student trong CSDL,  
MS Access 2013 cung cấp 03 loại module: module chuẩn (Standard Module), module 
lớp (Class Module) và module gắn với form/report (Form/Report Module) 
Standard module chủ yếu bao gồm tập các hàm/thủ tục. Mỗi hàm/thủ tục này đƣợc gọi 
từ các hàm/thủ tục khác hoặc từ sự kiện của đối tƣợng hay điều khiển. Khi đó, toàn bộ 
mã lệnh của chƣơng trình đƣợc tổ chức thành các đơn vị hàm/thủ tục. Các đơn vị 
hàm/thủ tục này đƣợc gom lại trong một hoặc một số Standard Module để giúp lập 
trình viên dễ quản lý mã lệnh của mình hơn. 
Class module thực chất là một lớp do ngƣời dùng định nghĩa. Mỗi Class Module là 
một lớp của ngƣời dùng có tên chính là tên của Class Module. Lớp của ngƣời dùng 
định nghĩa cũng đƣợc đối xử bình đẳng nhƣ các lớp đã đƣợc định nghĩa bởi hệ thống 
(built-in language class). 
Điều quan trọng ở đây là bạn phải biết khi nào dùng Standard Module và khi nào dùng 
Class Module hay cả hai. Nó phụ thuộc vào cách thiết kế ứng dụng của bạn. Nếu ứng 
dụng của bạn đƣợc tổ chức theo kiểu “hƣớng chức năng” (phần mềm là một tập các 
chức năng có quan hệ với nhau) thì bạn sẽ có xu hƣớng sử dụng Standard Module 
nhiều hơn. Nếu ứng dụng của bạn đƣợc thiết kế theo mô hình lập trình “phân lớp” (03 
lớp chẳng hạn: giao diện, logic, truy cập dữ liệu) thì bạn sẽ đƣơng nhiên sẽ sử dụng 
Class Module nhiều hơn. 
Sau đây là chi tiết về các loại module. 
133 
2.1 Module chuẩn (Standard Module) 
Module này chứa các biến, thủ tục con có thể đƣợc gọi từ query, form, report, macro, 
biểu thức, thủ tục khác hoặc từ bất cứ đâu trong chƣơng trình ứng dụng. 
Nhƣ vậy, ta có thể viết trong Standard Module các nội dung sau đây: 
 Các khai báo tùy chọn dùng chung cho tất cả các hàm/thủ tục trong Standard 
Module. Ví dụ: Option Explicit là một khai báo tùy chọn yêu cầu tất cả các 
biến sau này dùng trong các hàm/thủ tục phải đƣợc khai báo tƣờng minh trƣớc 
khi dùng 
 Các khai báo hằng, biến toàn cục 
 Các hàm/thủ tục 
Các hàm/thủ tục trong Standard Module với phạm vi truy xuất public (mặc định) có 
thể đƣợc gọi từ bất kỳ đâu trong CSDL bao gồm các lời gọi từ: 
 Các hàm/thủ tục khác trong cùng Standard Module với nó 
 Các hàm/thủ tục trong các Class Module khác 
 Các thủ tục gắn với các form/report trong MS Access Class Objects 
Các hàm/thủ tục có phạm vi truy xuất private chỉ đƣợc gọi trong các hàm/thủ tục khác 
thuộc cùng module với nó. 
Để tạo Standard Module, trong cửa sổ thiết kế CSDL, chọn lệnh CREATE trên thanh 
menu, sau đó chọn nút lệnh Module (vùng khoanh đỏ) nhƣ trong hình 7.1 
Hình 7.1: Tạo Standard Module từ cửa sổ thiết kế CSDL 
134 
Kết quả bạn nhận đƣợc là cửa sổ để viết code trong Standard Module nhƣ trong hình 
7.2 
Hình 7.2 : Cửa sổ code của Standard Module 
Trong hình 7.2, cửa sổ màn hình đƣợc chia làm 02 panel bao gồm : panel bên trái là 
Project Explorer Panel để hiển thị các đối tƣợng module. Trong panel này, bạn có 
thể thêm/bớt hoặc sửa tên (F4) Standard Module, panel bên phải là Code Panel, đây 
là cửa sổ để bạn viết mã cho mỗi Standard Module đƣợc chọn bên panel trái. 
Chú ý : bạn có thể bật/tắt các panel này theo ý muốn để vùng quan sát của bạn đƣợc 
rộng hơn. Ví dụ khi code bạn muốn cửa sổ code (Code Panel) đƣợc rộng bạn nên tắt 
panel bên trái bằng cách click chuột vào biểu tƣợng dấu X ở góc trên bên phải nhất của 
panel đó. Khi cần bạn có thể mở lại bằng cách chọn lệnh VIEW/Project Explore trên 
thanh menu. 
Khi muốn ghi lại code, bạn cần chọn lệnh File/Save hoặc chọn biểu tƣợng save 
(chiếc đĩa mềm) trên thanh menu. Lần đầu tiên lƣu, bạn sẽ đƣợc hỏi đặt tên cho 
Standard Module, những lần sau, MS Access sẽ tự ghi vào tên bạn đã đặt từ lần đầu. 
Hình 7.3 minh họa cửa sổ lƣu Module3 đƣợc đặt tên là commonFunction. 
Code 
panel 
Project 
Explorer Panel 
135 
Hình 7.3 Đặt tên cho Standard Module 
Khi muốn sửa tên module đã đặt, bạn chọn vào tên module đó trong Project Explorer 
Panel rồi ấn phím F4. Ví dụ hình 7.4 minh họa cửa sổ đổi tên cho module1 thành tên 
mới là checkValidFunction 
Hình 7.4 Đổi tên cho Standard Module đã có 
Chúng ta quan tâm nhiều đến Code Panel. Sau đây, chúng ta sẽ phân tích Panel này. 
Phần trên cùng của Panel là hai hộp danh sách thả xuống. Hộp danh sách bên trái luôn 
có một mục là (General), hộp danh sách bên phải là danh sách các hàm, thủ tục trong 
Nút lệnh save 
Bạn nhập tên mới cho 
module ở thuộc tính 
(Name) 
136 
Standard Module (trong hình 7.2 vì chƣa có hàm, thủ tục nào đƣợc viết trong Standard 
Module nên chỉ có một mục (Declarations) đƣợc hiển thị). 
Cửa sổ soạn thảo mã lệnh gồm 03 phần, phần khai báo các tùy chọn, khai báo các 
hằng, biến dùng chung cho các hàm, thủ tục trong module và phần định nghĩa các 
hàm, thủ tục trong Standard Module. 
2.1.1 Khai báo các tùy chọn 
Các tùy chọn nếu đƣợc khai báo có thể khai báo sau hằng, biến toàn cục nhƣng phải 
trƣớc phần định nghĩa các hàm/thủ tục. Phần khai báo các tùy chọn ở đây có thể có các 
tùy chọn sau đƣợc khai báo: 
 Option Base Statement 
Khai báo chỉ số thấp nhất cho mảng trong toàn module, mặc định là 0. 
Cú pháp khai báo: 
Option Base {0 | 1} 
Ví dụ: Khi định nghĩa một mảng theo cú pháp 
Dim a(100) as Integer 
Mặc định ta sẽ đƣợc một mảng tên là a, các chỉ số chạy từ 0 đến 99. 
Nếu có tùy chọn Option Base 1 thì mảng a sẽ có 100 phần tử, chỉ số chạy từ 1 đến 
100. 
Tùy chọn này (nếu có) phải đƣợc khai báo trƣớc bất kỳ hàm, thủ tục nào và nó chỉ có 
tác dụng trong module chứa nó. Option Base chỉ đƣợc khai báo một lần trong một 
module và phải trƣớc các khai báo mảng. 
 Option Compare Statement 
Khai báo phƣơng thức so sánh cho các biểu thức thuộc kiểu chuỗi (String). 
Cú pháp khai báo: 
Option Compare {Binary | Text | Database} 
Option Compare Binary: so sánh chuỗi theo kiểu nhị phân, nghĩa là theo thứ tự sắp 
xếp của các ký tự trong bảng mã ASCII. Đây là kiểu mặc định 
Ví dụ: khi có khai báo Option Compare Binary thì ta sẽ có “A” < “B” < ”C”  < 
“a” < “b” < “c” vì mã ASCII của “A” và “a” tƣơng ứng là 65 và 97 (hệ thập phân) 
Option Compare Text: so sánh theo kiểu trật tự của các ký tự không phân biệt chữ 
hoa, thƣờng. 
137 
Ví dụ: Khi khai báo Option Compare Text thì "A" = "a", "B" = "b", , "À" = "à", 
"Ê" = "ê",  
Option Compare Database: so sánh xâu dựa trên trật tự đƣợc xác định cục bộ trong 
Database chứa module đó. 
 Option Explicit Statement 
Khai báo để yêu cầu các biến phải đƣợc khai báo tƣờng minh trƣớc khi sử dụng. Tùy 
chọn này (nếu có) phải đƣợc đặt trƣớc mọi khai báo biến và định nghĩa các hàm, thủ 
tục con. 
Cú pháp khai báo: 
Option Explicit 
Ví dụ 1: 
[1] Option Explicit 
[2] Dim a 
[3] a = 100 
Trong đoạn mã này: 
+ dòng [1]: yêu cầu các biến phải đƣợc khai báo tƣờng minh trƣớc khi sử dụng 
+ dòng [2] khai báo một biến a 
+ dòng [3] gán cho a giá trị 100 
Nhƣ vậy, cuối cùng biến a đƣợc nhận giá tri là 100 
Ví dụ 2: 
[1] Option Explicit 
[2] a = 100 
Trong đoạn mã này: 
+ dòng [1]: yêu cầu các biến phải đƣợc khai báo tƣờng minh trƣớc khi sử dụng 
+ dòng [2]: gán cho biến a giá trị 100 mà không có khai báo trƣớc 
Đoạn mã này khi dịch trình biên dịch sẽ thông báo lỗi “Variable not defined”. Và do 
đó cần khai báo biến a trƣớc khi gán giá trị cho nó (Dim a) hoặc ta bỏ khai báo Option 
Explicit đi. 
 Option Private Statement 
138 
Khai báo tùy chọn để cấm các truy xuất từ bên ngoài (các ứng dụng, dự án khác) vào 
các thành phần của module. 
Cú pháp khai báo: 
Option Private Module 
Chú ý: Tùy chọn này chỉ cấm các truy cập từ các dự án (có thể trong cùng ứng dụng), 
ứng dụng khác tới các thành phần (hằng, biến, hàm, thủ tục, kiểu ngƣời dùng định 
nghĩa) của module. Mọi truy xuất từ các module, query, form,  khác trong cùng cơ 
sở dữ liệu là đƣợc. 
2.1.2 Khai báo hằng, biến toàn cục 
Hằng, biến toàn cục có phạm vi hoạt động trong toàn bộ module mà nó đƣợc khai báo 
hoặc có thể rộng hơn (từ các module khác) tùy thuộc vào việc bạn quy định phạm vi 
truy xuất cho nó là private hay public. Hằng, biến toàn cục có thể đƣợc khai báo trƣớc 
hoặc sau các khai báo tùy chọn nhƣng bắt buộc phải khai báo trƣớc các hàm/thủ tục. 
Mặc định hằng, biến toàn cục ở đây có phạm vi truy xuất là private. Tức là, bạn chỉ có 
thể truy xuất đƣợc chúng từ các hàm, thủ tục trong cùng module với chúng. Bạn không 
thể truy xuất đƣợc các hằng, biến này từ các module khác. Tuy nhiên, bạn sõ thể thiết 
lập phạm vi truy xuất public cho chúng với khai báo từ khóa public trƣớc khai báo tên 
hằng, biến 
Chú ý: nên hạn chế việc sử dụng hằng/biến toàn cục 
Cú pháp khai báo hằng, biến sẽ đƣợc trình bày chi tiết trong phần sau. 
2.1.3. Hàm, thủ tục (function/sub) 
 Sau các khai báo tùy chọn và hằng, biến là phần định nghĩa các hàm/thủ tục của 
module. Các hàm/thủ tục đƣợc ra nhƣ là một thƣ viện, việc gọi thi hành chúng phải là 
tƣờng minh. Mặc định các hàm/thủ tục trong Standard Module có phạm vi truy xuất là 
public. Chi tiết về hàm và thủ tục sẽ đƣợc trình bày trong phần sau. 
2.1.4 Ví dụ 
Sau đây chúng ta phân tích một Standard Module có tên là commonFunction với dụng 
ý là module để lƣu các hàm cơ bản, dùng chung. Trong commonFunction chúng ta sẽ 
định nghĩa một số hàm làm việc với mảng các số double. Mục dích của ví dụ là minh 
họa các thành phần trong Standard Module 
Chú ý: để viết các chú thích (comment) trong vùng viết code của MS Access ta sử 
dụng dấu „ (dấu phẩy) trong dòng chú thích. Ví dụ: ‘ This is a comment. Khi gặp các 
dòng bắt đầu bằng dấu „, trình biên dịch sẽ bỏ qua tất cả những gì sau dấu „ cho đến 
khi gặp dòng tiếp theo. 
‘Khai báo tùy chọn chỉ số bắt đầu của mảng từ 1 mặc định 
139 
‘là 0 và tùy chọn phải khai báo biến tường minh trước 
‘khi dùng 
Option Base 1 
Option Explicit 
‘Khai báo một biến mảng toàn cục dùng chung a 
‘Khai báo một hằng n dụng ý là số phần tử của mảng 
‘Phạm vi truy xuất mặc định của a, n là private 
Dim a(100) As Double 
Const n As Integer = 10 
‘Định nghĩa các hàm/thủ tục 
‘Thủ tục khởi tạo ngẫu nhiên các giá trị mảng a gồm 
‘10 phần tử, các phần tử có giá trị <= 100 
Sub InitArray() 
 Dim i As Integer 
‘Khởi tạo bộ sinh số ngẫu nhiên từ 0 đến 1 
‘sử dụng cho hàm rnd sau này 
 Randomize 
 For i = 1 To n 
 a(i) = Rnd * 100 
 Next 
End Sub 
‘Thủ tục in các giá trị của mảng a ra màn hình hộp thoại, 
‘mỗi giá trị xuất hiện trong một lần hộp thoại xuất hiện, 
‘click vào nút lệnh OK để hiển thị phần tử kế tiếp 
Sub showArray() 
140 
 Dim i 
 For i = 1 To n 
 MsgBox ("a[" & Str(i) & "] = " & Str(a(i))) 
 Next 
End Sub 
‘Thủ tục xếp các phần tử của mảng a theo thứ tự tăng dần 
Sub sortArrayASC() 
 Dim i, j As Integer 
 For i = 1 To n - 1 
 For j = i + 1 To n 
 If (a(i) > a(j)) Then 
 Dim tg As Double 
 tg = a(i) 
 a(i) = a(j) 
 a(j) = tg 
 End If 
 Next 
 Next 
End Sub 
‘Hàm trả về giá trị True/False tương ứng khi 
‘x thuộc mảng hoặc không 
Function containInArray(x As Double) 
 Dim i As Integer 
 Dim kt As Boolean 
 kt = False 
 For i = 1 To n 
 If x = a(i) Then 
kt = True 
141 
Exit For 
 Next 
 containInArray = kt 
End Function 
Bạn nên đọc kỹ các chú ý sau đây. 
Trong đoạn mã trên: 
+ Biến mảng a và hằng n không khai báo phạm vi truy xuất là public hay private, thì 
mặc định là private. Điều này có nghĩa là, bạn không thể truy xuất đến a hay n từ bên 
ngoài module commonFunction. Ví dụ sau đây minh họa với bạn điều đó. Bạn có thể 
truy xuất a, n từ khắp nơi trong phạm vi module commonFunction nhƣ trong đoạn mã 
trên nhƣng sang module checkValidFunction bạn không thể truy xuất chúng nữa. 
Hình 7.5 Không nhìn thấy được a và n từ ngoài module commonFunction 
Bạn có thể sửa cho a, n thành phạm vi public bằng cách khai báo nhƣ sau: 
Public a(100) As Double 
Public Const n As Integer = 10 
Nhƣ hình 7.6 dƣới đây, bạ ...  = 
C:\Users\M11x-R3\Desktop\Access\qldt.accdb; Persist Security 
Info=False" 
Set cn = New adodb.Connection 
Set rec = New adodb.Recordset 
cn.Open cnstr 
sql = “SELECT * FROM Course WHERE CName =‟C++‟” 
rec.Open sql, cn, adOpenDynamic, adLockOptimistic 
while (not rec.EOf) 
rec.Delete 
rec.moveNext 
wend 
rec.Close: cn.Close: set cn = Nothing 
Ví dụ: Lấy một tập các bản ghi 
Đoạn mã sau đây sẽ lấy tất cả các bản ghi trong bảng Course thuộc CSDL 
C:\Users\M11x-R3\Desktop\Access\qldt.accdb rồi viết vào cửa sổ Immediate tên các 
khóa học, mỗi tên trên một dòng. 
Dim cn As adodb.Connection 
Dim cnstr, sql 
Dim rec As adodb.Recordset 
cnstr = "Provider=Microsoft.ACE.OLEDB.12.0; Data source = 
C:\Users\M11x-R3\Desktop\Access\qldt.accdb; Persist Security 
Info=False" 
Set cn = New adodb.Connection 
Set rec = New adodb.Recordset 
cn.Open cnstr 
sql = "SELECT * FROM Course" 
rec.Open sql, cn 
While Not rec.EOF 
Debug.Print rec.Fields(“CName”) 
rec.MoveNext 
227 
Wend 
rec.Close : cn.close: set cn = Nothing 
4. Đối tƣợng Record 
Là một bản ghi (row) của đối tƣợng Recordset. 
5. Field 
Thể hiện một cột (column) dữ liệu của đối tƣợng Recordset. 
6. Property 
Chứa các thuộc tính động của đối tƣợng ADO đƣợc định nghĩa bởi provider 
7. Parameter 
Chứa các tham số của đối tƣợng Command. Đó là các tham số cho truy vấn tham số và 
thủ tục nội 
8. Đối tƣợng Error 
Chứa chi tiết về các lỗi truy cập dữ liệu. 
9. Đối tƣợng Stream 
Là một dòng (stream) dữ liệu dạng nhị phân. 
10. Tập hợp Errors 
Chứa tất cả các đối tƣợng Error đƣợc sinh ra khi truy cập với dữ liệu. 
11. Tập hợp Fields 
Chứa tất cả các đối tƣợng Field của đối tƣợng Recordset. 
12. Tập hợp Parameters 
Chứa tất cả các đối tƣợng Parameter của đối tƣợng Command 
13. Tập hợp Properties 
Chứa tất cả các đối tƣợng Property của một đối tƣợng cụ thể. 
Ví dụ: 
Sau đây chúng tôi sẽ minh họa lại chƣơng trình trong phần kiến trúc DAO theo kiến 
trúc ADO. 
Lƣu ý một số khác biệt bao gồm: 
228 
+ Câu lệnh SELECT với toán tử LIKE, ADO yêu cầu sử dụng ký tự % để đại diện cho 
mọi ký tự trong khi DAO sử dụng ký tự * 
+ 
Option Compare Database 
Dim editingCID As Integer 
Dim con As ADODB.Connection 
Const cnstr As String = "Provider=Microsoft.ACE.OLEDB.12.0; Data source = 
C:\Users\M11x-R3\Desktop\Access\qldt.accdb; Persist Security Info=False" 
Private Sub cmdAddNew_Click() 
 'Lay cac du lieu nguoi dung nhap tu form 
 'Dua vao bang Course 
 'Hien thi ket qua ra ListBox 
 cmdEdit.SetFocus: cmdEdit.Caption = "Edit": editingCID = -1 
 Dim cn As String: txtCN.SetFocus: cn = txtCN.Text 
 Dim Duration As String: txtDuration.SetFocus: Duration = 
txtDuration.Text 
 Dim Des As String: txtDes.SetFocus: Des = txtDes.value 
 If (cn = "") Then 
 MsgBox "The name of the course must be required!" 
 Exit Sub 
 End If 
 Dim rec As ADODB.Recordset 
 If (con Is Nothing) Then 
 Set con = New ADODB.Connection 
 con.Open cnstr 
 End If 
 If (IsNull(con)) Then 
 Set con = New ADODB.Connection 
 con.Open cnstr 
 End If 
 If (IsEmpty(con)) Then 
 Set con = New ADODB.Connection 
 con.Open cnstr 
 End If 
229 
 Set rec = New ADODB.Recordset 
 rec.Open "SELECT * FROM Course", con, adOpenKeyset, adLockOptimistic 
 rec.AddNew 
 rec.Fields("CName").value = cn 
 'Kiem tra Duration phai la mot so nguyen nho hon 500 
 If (Duration "") Then 
 If (IsNumeric(Duration) = False) Then 
 MsgBox "Duration must be less than or equal 500!" 
 rec.Close: con.Close 
 Set con = Nothing 
 Exit Sub 
 End If 
 Dim pos1, pos2 As Integer 
 pos1 = -1 
 pos2 = -1 
 pos1 = InStr(1, Duration, ",", vbTextCompare) 
 pos2 = InStr(1, Duration, ".", vbTextCompare) 
 If (pos1 > 0) Or (pos2 > 0) Then 
 MsgBox "Duration must be less than or equal 500!" 
 rec.Close: con.Close 
 Set con = Nothing 
 Exit Sub 
 End If 
 Dim num As Integer 
 num = CInt(Duration) 
 If (num = Null) Or (num > 500) Then 
 MsgBox "Duration must be less than or equal 500!" 
 rec.Close: con.Close 
 Set con = Nothing 
 Exit Sub 
 End If 
230 
 rec.Fields("DurationInHour").value = num 
 End If 
 If (Des "") Then 
 rec.Fields("Description").value = Des 
 End If 
 rec.Update: rec.Close: con.Close 
 Set con = Nothing 
 LoadDataToListBox 
End Sub 
Private Sub cmdDelete_Click() 
 'Lay ra cac dong (item) ma nguoi dung chon trong ListBox 
 'Xoa ban ghi do trong bang Course 
 'Hien thi lai ket qua trong ListBox 
 cmdEdit.SetFocus: cmdEdit.Caption = "Edit": editingCID = -1 
 If (lbCourse.ItemsSelected.count = 0) Then 
 MsgBox "You must select at least 1 item in the ListBox to delete!" 
 Exit Sub 
 End If 
 Dim count As Integer: count = lbCourse.ItemsSelected.count 
 Dim varitem As Variant, i As Integer 
 Dim sql As String 
 sql = "SELECT * FROM Course WHERE (CID = " & CStr(lbCourse.Column(0, 
lbCourse.ItemsSelected.item(0))) & ")" 
 For i = 1 To lbCourse.ItemsSelected.count - 1 
 sql = sql & " OR (CID=" & CStr(lbCourse.Column(0, 
lbCourse.ItemsSelected(i))) & ")" 
 Next 
 If (con Is Nothing) Then 
 Set con = New ADODB.Connection 
 con.Open cnstr 
 End If 
 If (IsNull(con)) Then 
 Set con = New ADODB.Connection 
 con.Open cnstr 
231 
 End If 
 If (IsEmpty(con)) Then 
 Set con = New ADODB.Connection 
 con.Open cnstr 
 End If 
 Dim rec As ADODB.Recordset 
 Set rec = New ADODB.Recordset 
 rec.Open sql, con, adOpenDynamic, adLockOptimistic 
 While (rec.EOF = False) 
 rec.Delete 
 rec.MoveNext 
 Wend 
 rec.Close: con.Close: Set con = Nothing 
 LoadDataToListBox 
End Sub 
Private Sub cmdEdit_Click() 
 'Thay lai Text trong Caption cua nut cho phu hop 
 'kiem tra nguoi dung chi duoc chon 1 item de sua 
 'tai item do vao cac dieu khien tren form 
 'nguoi dung sua cac gia tri 
 'cap nhat lai bang Course cac gia tri moi 
 'Hien thi ket qua sua item do 
 Dim cap, cn, Dur, Des As String 
 cn = "": Dur = "": Des = "" 
 cmdEdit.SetFocus: cap = cmdEdit.Caption 
 cap = Trim(cap): cap = LCase(cap) 
 If (cap = "edit") Then 
 cap = "Save Edit" 
 If (lbCourse.ItemsSelected.count = 0) Then 
 MsgBox "You must select only 1 item in the ListBox to edit!" 
 Exit Sub 
 End If 
 Dim count As Integer: count = lbCourse.ItemsSelected.count 
232 
 If (count > 1) Then 
 MsgBox "You must select only 1 item in the ListBox to edit!" 
 Exit Sub 
 End If 
 editingCID = lbCourse.Column(0, lbCourse.ItemsSelected.item(0)) 
 If (lbCourse.Column(1, lbCourse.ItemsSelected.item(0)) "") Then 
 cn = lbCourse.Column(1, lbCourse.ItemsSelected.item(0)) 
 End If 
 If (lbCourse.Column(2, lbCourse.ItemsSelected.item(0)) "") Then 
 Dur = lbCourse.Column(2, lbCourse.ItemsSelected.item(0)) 
 End If 
 If (lbCourse.Column(3, lbCourse.ItemsSelected.item(0)) "") Then 
 Des = lbCourse.Column(3, lbCourse.ItemsSelected.item(0)) 
 End If 
 txtCN.SetFocus: txtCN.Text = cn 
 txtDuration.SetFocus: txtDuration.Text = Dur 
 txtDes.SetFocus: txtDes.value = Des 
 Else 
 cap = "Edit" 
 txtCN.SetFocus: cn = txtCN.Text 
 txtDuration.SetFocus: Dur = txtDuration.Text 
 txtDes.SetFocus: Des = txtDes.value 
 If (cn = "") Then 
 MsgBox "The name of the course must be required!" 
 Exit Sub 
 End If 
 Dim sql As String: sql = "SELECT * FROM Course WHERE CID=" & 
CStr(editingCID) 
 If (con Is Nothing) Then 
 Set con = New ADODB.Connection 
 con.Open cnstr 
 End If 
 If (IsNull(con)) Then 
233 
 Set con = New ADODB.Connection 
 con.Open cnstr 
 End If 
 If (IsEmpty(con)) Then 
 Set con = New ADODB.Connection 
 con.Open cnstr 
 End If 
 Dim rec As ADODB.Recordset 
 Set rec = New ADODB.Recordset 
 rec.Open sql, con, adOpenDynamic, adLockOptimistic 
 rec.Fields("CName").value = cn 
 If (Dur "") Then 
 If (IsNumeric(Dur) = False) Then 
 MsgBox "Duration must be less than or equal 500!" 
 Exit Sub 
 End If 
 Dim pos1, pos2 As Integer 
 pos1 = -1 
 pos2 = -1 
 pos1 = InStr(1, Dur, ",", vbTextCompare) 
 pos2 = InStr(1, Dur, ".", vbTextCompare) 
 If (pos1 > 0) Or (pos2 > 0) Then 
 MsgBox "Duration must be less than or equal 500!" 
 Exit Sub 
 End If 
 Dim num As Integer 
 num = CInt(Dur) 
 If (num = Null) Or (num > 500) Then 
 MsgBox "Duration must be less than or equal 500!" 
 Exit Sub 
 End If 
 rec.Fields("DurationInHour").value = num 
234 
 End If 
 If (Des "") Then 
 rec.Fields("Description").value = Des 
 End If 
 rec.Update 
 rec.Close: con.Close: Set con = Nothing 
 End If 
 cmdEdit.SetFocus 
 cmdEdit.Caption = cap 
 LoadDataToListBox 
End Sub 
Private Sub cmdRefresh_Click() 
 txtCN.SetFocus: txtCN.Text = "" 
 txtDes.SetFocus: txtDes.value = "" 
 txtDuration.SetFocus: txtDuration.Text = "" 
 editingCID = -1 
 cmdEdit.SetFocus 
 cmdEdit.Caption = "Edit" 
 LoadDataToListBox 
End Sub 
Private Sub cmdSearch_Click() 
 'Lay cac du lieu nguoi dung nhap tu form 
 'SELECT du lieu theo dieu kien tim kiem 
 'Hien thi ket qua ben duoi ListBox 
 cmdEdit.SetFocus: cmdEdit.Caption = "Edit": editingCID = -1 
 Dim cn As String: txtCN.SetFocus: cn = txtCN.Text 
 Dim Duration As String: txtDuration.SetFocus: Duration = 
txtDuration.Text 
 Dim Des As String: txtDes.SetFocus: Des = txtDes.value 
 Dim foundCN As Boolean: foundCN = False 
 Dim foundDur As Boolean: foundDur = False 
 Dim foundDes As Boolean: foundDes = False 
 If (cn "") Then 
 foundCN = True 
235 
 End If 
 If (Duration "") Then 
 foundDur = True 
 End If 
 If (Des "") Then 
 foundDes = True 
 End If 
 If (foundCN = False) And (foundDur = False) And (foundDes = False) Then 
 MsgBox "You must input either Name or Duration or Description of 
the course!" 
 Exit Sub 
 End If 
 Dim sql As String 
 sql = "SELECT * FROM Course WHERE" 
 If (foundCN) And (foundDur) And (foundDes) Then 
 sql = sql & " (CName Like '%" & cn & "%')" 
 sql = sql & " and (DurationInHour = " & Duration & ")" 
 sql = sql & " and (Description LIKE '%" & Des & "%')" 
 Else 
 If (foundCN) And (foundDur) And (Not foundDes) Then 
 sql = sql & " (CName Like '%" & cn & "%')" 
 sql = sql & " and (DurationInHour = " & Duration & ")" 
 Else 
 If (foundCN) And (Not foundDur) And (foundDes) Then 
 sql = sql & " (CName Like '%" & cn & "%')" 
 sql = sql & " and (Description LIKE '%" & Des & "%')" 
 Else 
 If (foundCN) And (Not foundDur) And (Not foundDes) Then 
 sql = sql & " (CName Like '%" & cn & "%')" 
 Else 
 If (Not foundCN) And (foundDur) And (foundDes) Then 
 sql = sql & " (DurationInHour = " & Duration & ")" 
 sql = sql & " and (Description LIKE '%" & Des & "%')" 
 Else 
236 
 If (Not foundCN) And (foundDur) And (Not foundDes) Then 
 sql = sql & " (DurationInHour = " & Duration & ")" 
 Else 
 If (Not foundCN) And (Not foundDur) And (foundDes) Then 
 sql = sql & "(Description LIKE '%" & Des & "%')" 
 End If 
 End If 
 End If 
 End If 
 End If 
 End If 
 End If 
 If (con Is Nothing) Then 
 Set con = New ADODB.Connection 
 con.Open cnstr 
 End If 
 If (IsNull(con)) Then 
 Set con = New ADODB.Connection 
 con.Open cnstr 
 End If 
 If (IsEmpty(con)) Then 
 Set con = New ADODB.Connection 
 con.Open cnstr 
 End If 
 Dim rec As ADODB.Recordset 
 Set rec = New ADODB.Recordset 
 rec.Open sql, con, adOpenDynamic 
 If (rec.RecordCount = 0) Then 
 lblSearch.Caption = "There is no item found!" 
 rec.Close: con.Close 
 Set con = Nothing 
 Exit Sub 
237 
 Else 
 rec.MoveLast 
 lblSearch.Caption = "There are " & CStr(rec.RecordCount) & " items 
found" 
 Dim i As Integer 
 While (lbCourse.ListCount > 0) 
 i = lbCourse.ListCount - 1 
 lbCourse.RemoveItem Index:=i 
 Wend 
 lbCourse.ColumnCount = 4 
 lbCourse.AddItem item:="CID;Course Name;Duration (in hour) ; 
Description;", Index:=0 
 Dim item As String: item = "" 
 rec.MoveFirst 
 While (rec.EOF = False) 
 item = CStr(rec.Fields("CID").value) 
 If rec.Fields("CName") "" Then 
 item = item & ";" & rec.Fields("CName").value 
 Else 
 item = item & "; " 
 End If 
 If IsNull(rec.Fields("DurationInHour")) = False Then 
 item = item & ";" & 
CStr(rec.Fields("DurationInHour").value) 
 Else 
 item = item & "; " 
 End If 
 If rec.Fields("Description") "" Then 
 item = item & ";" & rec.Fields("Description").value 
 Else 
 item = item & "; " 
 End If 
 lbCourse.AddItem item:=item 
 rec.MoveNext 
238 
 Wend 
 rec.Close: con.Close 
 Set con = Nothing 
 End If 
End Sub 
Private Sub Form_Load() 
 cmdEdit.SetFocus: cmdEdit.Caption = "Edit": editingCID = -1 
 LoadDataToListBox 
End Sub 
Private Sub LoadDataToListBox() 
'Ham nay se tai du lieu tu bang Coourse vao ListBox lbCourse 
 'lbCourse.RowSource = "" 
 Dim rec As ADODB.Recordset 
 If (con Is Nothing) Then 
 Set con = New ADODB.Connection 
 con.Open cnstr 
 End If 
 If (IsNull(con)) Then 
 Set con = New ADODB.Connection 
 con.Open cnstr 
 End If 
 If (IsEmpty(con)) Then 
 Set con = New ADODB.Connection 
 con.Open cnstr 
 End If 
 Set rec = New ADODB.Recordset 
 rec.Open "SELECT * FROM Course", con, adOpenDynamic 
 If (rec.RecordCount = 0) Then 
 lblSearch.Caption = "There is no item found!" 
 rec.Close: con.Close: Set con = Nothing 
 Exit Sub 
 Else 
 rec.MoveLast 
239 
 lblSearch.Caption = "There are " & CStr(rec.RecordCount) & " items 
found" 
 rec.MoveFirst 
 Dim i As Integer 
 While (lbCourse.ListCount > 0) 
 i = lbCourse.ListCount - 1 
 lbCourse.RemoveItem Index:=i 
 Wend 
 lbCourse.AddItem item:="CID;Course Name;Duration (in hour) ; 
Description;", Index:=0 
 Dim item As String: item = "" 
 While (rec.EOF = False) 
 item = CStr(rec.Fields("CID").value) 
 If rec.Fields("CName") "" Then 
 item = item & ";" & rec.Fields("CName").value 
 Else 
 item = item & "; " 
 End If 
 If IsNull(rec.Fields("DurationInHour")) = False Then 
 item = item & ";" & 
CStr(rec.Fields("DurationInHour").value) 
 Else 
 item = item & "; " 
 End If 
 If rec.Fields("Description") "" Then 
 item = item & ";" & rec.Fields("Description").value 
 Else 
 item = item & "; " 
 End If 
 lbCourse.AddItem item:=item 
 rec.MoveNext 
 Wend 
 rec.Close 
 con.Close 
240 
 Set con = Nothing 
 End If 
End Sub 
241 
BÀI TẬP CHƢƠNG 7 
1. Hãy cài đặt lại chƣơng trình trong ví dụ về một chƣơng trình hoàn chỉnh sử 
dụng các đối tƣợng khác Recordset trong các kiến trúc DAO và ADO 
2. Hãy cài đặt thêm chức năng phân trang cho ListBox của bài tập trên. Số bản 
ghi trên 1 trang (PageSize) sẽ do ngƣời dùng nhập vào, tại mỗi thời điểm 
ListBox chỉ hiển thị PageSize bản ghi và các nút 1, 2, 3, 4,  để chuyển 
trang. Khi ngƣời dùng chọn 1 trang bất kỳ thì ListBox chỉ hiển thị các bản 
ghi thuộc trang đó và nút hiển thị trang đó sẽ nổi bật lên. 
242 
TÀI LIỆU THAM KHẢO 
[1] Access 2013, Microsoft, 2013 
[2] Đặng Thị Thu Hiền và Đỗ Thanh Thủy, Bài giảng Nhập môn hệ quản trị cơ sở dữ 
liệu Access, Trƣờng ĐH Giao Thông Vận Tải, 2007. 
[3] MSDN Library – October 2012 
[4] Teresa Hennig, Ben Clothier, George Hepworth and Dagi (Doug) Yudovich, 
Professional Access 2013 Programming, ISBN: 978-1-118-53083-2, Wrok, August 
2013. 
[5]  
[6]  

File đính kèm:

  • pdfgiao_trinh_access_dhgtvt1_2_3827_525935.pdf