Giáo trình Nhập môn hệ quản trị cơ sở dữ liệu (Phần 2)
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.
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 (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ạn đang ở module checkvalidFunction, bạn hoàn toàn có thể
nhìn thấy (truy xuất) a và n trong module ... im 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 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:
giao_trinh_nhap_mon_he_quan_tri_co_so_du_lieu_phan_2.pdf

