BÀI TẬP LẬP TRÌNH HƯỚNG SỰ KIỆN - CHƯƠNG 5 KẾT NỐI VÀ THAO TÁC VỚI CSDL MỤC TIÊU: SAU KHI HOÀN THÀNH CÁC BÀI TẬP, NGƯỜI HỌC CÓ THỂ Kết nối đến CSDL bằng điều khiển ADO Data Control và Connection Truy cập (Select, Update, Delete, Insert) dữ liệu sử dụng Connection Gắn kết dữ liệu giữa các điều khiển với đối tượng Connection Viết được một số ứng dụng quản trị CSDL đơn giản Tạo và trình bày báo cáo (Report) để in ra máy in
Trang 1ch−¬ng v
kÕt nèi vµ thao t¸c víi csdl
MỤC TIÊU: SAU KHI HOÀN THÀNH CÁC BÀI TẬP, NGƯỜI HỌC CÓ THỂ
Kết nối đến CSDL bằng điều khiển ADO Data Control và Connection
Truy cập (Select, Update, Delete, Insert) dữ liệu sử dụng Connection
Gắn kết dữ liệu giữa các điều khiển với đối tượng Connection
Viết được một số ứng dụng quản trị CSDL đơn giản
Tạo và trình bày báo cáo (Report) để in ra máy in
A - ĐỀ BÀI TẬP
Qui ước
Các bài tập trong chương này đều liên quan đến việc kết nối và thao tác với một Cơ
sở dữ liệu (CSDL) nhất định, do vậy để đảm bảo sự thống nhất cũng như tránh hiểu sai trong một số tình huống, Ở đây chúng ta chủ yếu sử dụng cơ sở dữ liệu sẵn có khi cài bộ Visual Studio 6.0, có tên là : Nwind.mdb Sở dĩ chúng ta chọn CSDL này làm mẫu trong hầu hết các bài tập vì mấy lý do sau:
• Sẵn có trong máy tính khi cài Visual Basic
• Đây là một cơ sở dữ liệu được xây dựng thực tế từ quản lý bán hàng của hãng North Wind, do vậy các bài tập liên quan sẽ sát với thực tiễn hơn
• Số lượng bản ghi trong CSDL này tương đối nhiều, đủ để minh hoạ trong rất nhiều trường hợp, do đó không phải mất công sức để lại
• Trong CSDL này có nhiều bảng và đã được chuẩn hoá
• Có đầy đủ các mối quan hệ 1-nhiều, nhiều-nhiều để có thể thực hành với các truy vấn nâng cao, truy vấn trên nhiều bảng đồng thời
Cơ sở dữ liệu Nwind.mdb thường được lưu trong thư mục cùng với thư mục VB:
C:\Program Files\Microsoft Visual Studio\VB98\NWIND.MDB
Với đường dẫn rất dài như trên, nói chung là không được thuận tiện trong khi viết chương trình Ta sẽ giả thiết rằng, với mỗi chương trình, tệp Nwind.mdb sẽ được Copy vào trong cùng thư mục với tệp dự án Ví dụ, nếu ta có một dự án tên là : QLHSSV.VBP, đặt trong thư mục C:\Projects\QLHSSV thì tệp Nwin.mdb cũng phải được đặt trong thư mục này:
Hình 5.1 – Qui ước về việc copy và lưu tệp CSDL Nwind.mdb
Trang 2Ở đây cũng xin được cung cấp danh sách tất cả 8 bảng và mối quan hệ giữa các bảng này để chúng ta tiện theo dõi và tham khảo trong quá trình làm bài tập
Hình 5.2 – Các bảng và sơ đồ liên kết giữa chúng trong CSDL Nwind.mdb
Kiểu dữ liệu của mỗi trường trong từng bảng cũng xin được cung cấp tại đây:
Hãy lưu ý là chi tiết của từng kiểu dữ liệu (độ rộng) trong mỗi bảng có thể tham khảo bằng cách mở trực tiếp bảng đó ở chế độ Design View
Hình 5.3 - Bảng Suppliers (Nhà cung cấp)
Trang 3Hình 5.4 - Bảng Products (Sản phẩm)
Hình 5.5 - Bảng Order Details (Chi tiết đơn hàng)
Hình 5.6 - Bảng Orders (Đơn hàng)
Hình 5.7 - Bảng Customers (Khách hàng)
Trang 4Hình 5.8 - Bảng Categories (Chủng loại sản phẩm)
Hình 5.9 - Bảng Employees (Nhân viên bán hàng)
Hình 5.10 - Bảng Shippers (Công ty vận chuyển) Các bài tập (từ 1-11) sử dụng điều khiển ADO Data
Bài 1: Viết chương trình xem thông tin về khách hàng (Version 1)
a Giao diện:
Hình 5.11 – Xem thông tin về khách hàng bằng ADO Data control và Textbox
b Yêu cầu:
• Xây dựng giao diện chương trình như hình 11
• Có thể xem thông tin về khách hàng (gồm mã, họ tên, địa chỉ, số điện thoại)
Trang 5Bài 2: Viết chương trình xem thông tin về khách hàng (Version 2)
a Giao diện
Hình 5.12 – Xem thông tin về khách hàng sử dụng các phương thức của ADO
b Yêu cầu
• Xây dựng giao diện như hình 12
• Chương trình có thể di chuyển đến các bản ghi thông qua các nút nhấn
• Có cập nhật trạng thái (Enable/Disable) các nút khi đến BOF, EOF của bảng
• Nội dung trong các textbox không được phép thay đổi
Bài 3: Viết chương trình xem thông tin về khách hàng (Version 3)
a Giao diện
Hình 5.13 – Danh sách khách hàng hiển thị trong Data Grid Control
b Yêu cầu : Hiển thị tất cả các bản ghi trong bảng Customers trong một DataGrid
Bài 4: Viết chương trình xem thông tin về khách hàng (Version 4)
a Giao diện
Hình 5.14 – Thông tin hiển thị chỉ gồm 4 trường
b Yêu cầu: Như bài 3 nhưng thông tin hiển thị chỉ gồm 4 trường
Trang 6Bài 5: Viết chương trình xem một bảng CSDL bất kỳ trong CSDL NWind
a Giao diện
Hình 5.15 – Nạp một bảng bất kỳ trong CSDL NWind vào Data Grid
b Yêu cầu: Khi người dùng chọn tên bảng và click vào nút "Xem bảng này" thì
chương trình nạp và hiển thị bảng vừa được chọn trong một Data Grid
Bài 6: Viết chương trình nạp tất cả mã nhà cung cấp vào một hộp Combo
a Giao diện
Hình 5.16 -Nạp các mã nhà cung cấp vào một ComboBox
b Yêu cầu: Nạp tất cả các Mã nhà cung cấp (SupplierID) trong bảng Suppliers vào
Trang 7b Yêu cầu:
• Nạp tất cả các mã nhà cung cấp (Supplier) vào hộp Combo (Như bài số 6)
• Khi người dùng chọn một mã nhà cung cấp trong Hộp Combo và click nút
"Liệt kê các sản phẩm của NCC này" thì hiển thị tất cả các sản phẩm mà nhà cung cấp này đã cung ứng (Như hình 17)
Bài 8: Viết chương trình liệt kê các sản phẩm do 1 công ty cung cấp (ver 2)
a Giao diện
Hình 5.18 – Liệt kê các sản phẩm sử dụng TreeView và DataGrid
b Yêu cầu
• Nạp Mã (SupplierID) và tên Công ty (CompanyName) trong bảng Suppliers
vào một cây (TreeVIew), trong đó Mã được lưu trong trường Key và Tên công
ty được lưu trong trường Text của mỗi nút thuộc cây
• Khi người dùng click chuột lên một nút (tên công ty) trong cây thì hiển thị tất
cả các sản phẩm mà công ty đó cung cấp (Hiển thị tất cả các trường trong bảng Products) trong một Datagrid control như hình 18
Bài 9: Như bài 8 nhưng các sản phẩm được hiển thị trong một ListView (Để
cho ngắn gọn, hãy liệt kê 3 trường là ProductName,CategoryID,UnitPrice) như H.19
a Giao diện:
Hình 5.19 - Hiển thị sản phẩm trong ListView
Trang 8b Yêu cầu: Khi người dùng click vào tên nhà cung cấp thì hiển thị SP trong ListView
Bài 10: Xây dựng cây nhiều mức để xem thông tin về những sản phẩm đã bán
a Giao diện:
Hình 5.20 – Xem thông tin bán hàng của mỗi sản phẩm
b Yêu cầu:
• Nạp tên các công ty cung cấp sản phẩm vào cây (Nạp vào mức 1, sau gốc)
• Ứng với mỗi công ty, nạp các sản phẩm mà công ty sản xuất
• Khi người dùng click vào tên một sản phẩm (như hình 20) thì hiển thị các hoá đơn có xuất hiện sản phẩm này Thông tin hiển thị gồm Mã, giá, số lượng
Bài 11: Bổ sung thêm một trường mới trong câu lệnh SELECT
Hình 5.21 – Thêm một cột (trường) trong câu lệnh SELECT
Yêu cầu: Như bài 10 nhưng thông tin hiển thị có thêm trường "Giá trị", trường này
được dẫn xuất từ việc tính : Giá trị = Giá * Số lượng
Trang 9Các bài tập sử dụng đối tượng connection và Recordset
Ứng dụng này sẽ có 3 Form và một Module:
• Form thứ nhất có tên là frmNhapNCC: Để nhập thêm các nhà cung cấp vào
bảng Suppliers
• Form thứ hai có tên là frmNhapSP để nhập các sản phẩm mà một Nhà cung
cấp sản xuất
• Form chính: Tên là frmMain Form này sẽ hiển thị danh sách các nhà cung
cấp và sản phẩm (như bài tập số 9) Ngoài ra, trong form này có 2 nút lệnh là
"Nhập NCC" và "Nhập sản phẩm", khi click vào nút thứ nhất thì hiển thị frmNhapNCC, khi Click vào nút thứ hai thì hiển thị frmNhapSP
• Module có tên là modKetNoi: Trong module này sẽ khai báo biến toàn cục là đối tượng Connection tên là Cn Đối tượng Cn này sẽ được sử dụng chung
trong các form
b Giao diện khi chạy chương trình (Hình 22,23,24)
Hình 5.22 – Giao diện của form : frmMain
Trang 10Hình 5.23 – Giao diện form: frmNhapNCC
Hình 5.24 – Giao diện form: frmNhapSP Bài 15: Thiết kế báo cáo và kết xuất ra máy in danh sách các sản phẩm (ver 1)
Hình 5.25 – Báo cáo danh sách các sản phẩm để in ra máy in
Trang 11Bài 16: Thiết kế báo cáo và kết xuất ra máy in danh sách các sản phẩm (ver 2)
Hình 5.26 – Báo cáo có thêm khung viền (Border)
B- HƯỚNG DẪN - GIẢI MẪU
Bài 1: Viết chương trình xem thông tin về khách hàng (Version 1)
a Thiết kế giao diện
Hình 5.27 - Đặt tên cho các điều khiển trên Form
b Hướng dẫn : Sử dụng từ khoá SET để gắn kết các Textbox với ADO data Control
Có 2 cách để gắn kết, là gắn kết trong lúc thiết kế hoặc gắn kết thông qua mã lệnh
Để gắn kết, chỉ cần đặt 2 thuộc tính là DataSource và DataField Datasource cho biết
là lấy dữ liệu từ nguồn nào còn Datafield cho biết là lấy (hiển thị) trường nào ?
c Chương trình mẫu
Option Explicit
Private Sub Form_Load()
Dim strConn As String
strConn = "Provider=Microsoft.jet.oledb.4.0; Data Source=" & App.Path & "\Nwind.mdb" adoDSKH.ConnectionString = strConn
adoDSKH.CommandType = adCmdTable '/// Sẽ lấy một bảng
adoDSKH.RecordSource = "Customers" '/// Bảng có tên là Customers
adoDSKH.Refresh
Set txtMaKH.DataSource = adoDSKH '/// Nguồn dữ liệu lấy từ adoDSKH
txtMaKH.DataField = "CustomerID" '/// Trường hiển thị là CustomerID
Set txtHoTenKH.DataSource = adoDSKH
Trang 12thuộc tính RecordSource phải là một câu lệnh SQL (ví dụ Select, Update, Delete, Insert )
Bài 2: Viết chương trình xem thông tin về khách hàng (Version 2)
a Thiết kế giao diện
Hình 5.28 – Đặt tên cho các điều khiển trên Form
b Hướng dẫn : Sử dụng các phương thức di chuyển bản ghi có sẵn của đối tượng
con Recordset trong điều khiển ADO Data Tuy nhiên cần kiển tra trước khi di
chuyển (thông qua việc kiểm tra thuộc tính EOF và BOF)
c Chương trình mẫu
Option Explicit
Private Sub Form_Load()
Dim strConn As String
strConn="Provider=Microsoft.jet.oledb.4.0;Data Source=" & App.Path & "\Nwind.mdb" adoDSKH.ConnectionString = strConn
Trang 13Dim Cmd As Object
For Each Cmd In Controls
If TypeOf Cmd Is TextBox Then Cmd.Locked = True
cmdPrevious.Enabled = (adoDSKH.Recordset.BOF = False)
cmdNext.Enabled = (adoDSKH.Recordset.EOF = False)
End Sub
' -
'/// Trở về bản ghi đầu tiên
Private Sub cmdFirst_Click()
'/// Trở về bản ghi tiếp theo
Private Sub cmdNext_Click()
If adoDSKH.Recordset.EOF = False Then adoDSKH.Recordset.MoveNext
Call CapNhatNutNhan
End Sub
' -
'/// Trở về bản ghi đứng trước
Private Sub cmdPrevious_Click()
If adoDSKH.Recordset.BOF = False Then adoDSKH.Recordset.MovePrevious Call CapNhatNutNhan
End Sub
Bài 3: Viết chương trình xem thông tin về khách hàng (Version 3)
a Thiết kế giao diện
Hình 5.29 – Giao diện và tên các điều khiển
b Hướng dẫn: Sử dụng câu lệnh SET để gắn kết Datagrid với ADO Data
c Chương trình mẫu:
Trang 14Option Explicit
Private Sub Form_Load()
Dim strConn As String
strConn="Provider=Microsoft.jet.oledb.4.0;Data Source=" & App.Path & "\Nwind.mdb" adoDSKH.ConnectionString = strConn
d Ghi chú: Khi gắn kết DataGrid với ADO và thuộc tính CommandType của ADO
Data là adcmdTable thì người dùng có thể sửa, thêm bản ghi trực tiếp trên DataGrid (Với điều kiện thuộc tính AllowUpdate, AllowAddNew) Nói chung, không nên cho phép điều này bởi vì khi người dùng cập nhật trực tiếp như vậy, chúng ta rất khó có thể kiểm soát được dữ liệu nhập vào này
Bài 4: Viết chương trình xem thông tin về khách hàng (Version 4)
a Thiết kế giao diện: Giống như bài số 3
b Hướng dẫn: Vì ở đây chỉ hiển thị 3 trường chứ không phải tất cả, do vậy phải sử
dụng đến câu lệnh SQL Như vậy cần đặt lại thuộc tính CommandType=adcmdTable
và thuộc tính Recordsource là câu lệnh SELECT
c Chương trình mẫu
Option Explicit
Private Sub Form_Load()
Dim strConn As String, strSQL As string
strConn="Provider=Microsoft.jet.oledb.4.0;Data Source=" & App.Path & "\Nwind.mdb" adoDSKH.ConnectionString = strConn
strSQL = "SELECT Customerid,ContactName, Address, Phone from Customers"
d Ghi chú: Khi sử dụng câu lệnh SELECT để lấy dữ liệu về thì người dùng không
thể sửa đổi dữ liệu trực tiếp trên DataGrid
Trang 15Bài 5: Viết chương trình xem một bảng CSDL bất kỳ trong CSDL NWind
a Thiết kế giao diện
Hình 5.30 – Giao diện chương trình
b Hướng dẫn: Vẫn sử dụng cách trước đây là thay đổi tên bảng cho thuộc tính
Recordsource Tuy nhiên, vì một ADO Data được sử dụng nhiều lần và mở nhiều bảng do vậy trước khi mở bảng mới cần kiểm tra và đóng lại
c Chương trình mẫu
Option Explicit
Private Sub cmdXem_Click()
If Not (adoBang.Recordset Is Nothing) Then adoBang.Recordset.Close
adoBang.RecordSource = "[" & cboDSBang.Text & "]" '/// cần đặt trong [ ]
adoBang.Refresh
Set dgrHienThi.DataSource = adoBang
End Sub
' -
Private Sub Form_Load()
Dim strConn As String
strConn="Provider=Microsoft.jet.oledb.4.0;Data Source=" & App.Path & "\Nwind.mdb" adoDSKH.ConnectionString = strConn
Trang 16• Có thể sử dụng câu lệnh dạng Is Nothing để kiểm tra xem một đối tượng
có rỗng hay không (tức chưa trỏ tới đối tượng nào trước đó)
• Tên bảng trong Access có thể chứa dấu cách, khi đó để không bị lỗi thì tên bảng đó phải đặt trong cặp ngoặc [ ] trước khi gán cho thuộc tính Recordsource, giống như trong bài này Với các bảng mà tên không chứa dấu cách thì bạn có thể thêm vào hoặc không
• Khi thiết kế CSDL, không nên đặt tên bảng chứa dấu cách
Bài 6: Viết chương trình nạp tất cả mã nhà cung cấp vào một hộp Combo
a Thiết kế giao diện
Hình 5.31 – Giao diện chương trình
b Hướng dẫn: Sử dụng vòng lặp để duyệt các bản ghi trong Recordset
c Chương trình mẫu
Option Explicit
Private Sub Form_Load()
Dim strConn As String
strConn="Provider=Microsoft.jet.oledb.4.0;Data Source=" & App.Path & "\Nwind.mdb" adoDSKH.ConnectionString = strConn
d Ghi chú: Đây là công việc rất hay gặp phải, do vậy chúng ta nên nắm rõ
Bài 7: Viết chương trình liệt kê các sản phẩm do 1 công ty cung cấp (ver 1)
a Thiết kế giao diện
Hình 5.32 – Giao diện chương trình
Trang 17b Hướng dẫn: Do phải nạp dữ liệu vào 2 nơi (Combo và DataGrid) nên cần 2 điều
khiển ADO Data
c Chương trình mẫu
Option Explicit
Private Sub cmdLietKe_Click()
Dim strSQL As String, strConn As String
strConn="Provider=Microsoft.jet.oledb.4.0;Data Source=" & App.Path & "\Nwind.mdb" adoDSKH.ConnectionString = strConn
Private Sub Form_Load()
Dim strConn As String
strConn="Provider=Microsoft.jet.oledb.4.0;Data Source=" & App.Path &"\Nwind.mdb" adoMaNCC.ConnectionString = strConn
d Ghi chú : Đây là dạng bài toán rất hay gặp phải là : Click vào một mục thì sẽ hiển
thị thông tin về các con của mục đó
Bài 8: Viết chương trình liệt kê các sản phẩm do 1 công ty cung cấp (ver 2)
a Thiết kế giao diện:
Hình 5.33 – Giao diện và tên các điều khiển
Trang 18b Hướng dẫn: Nạp thông tin về nhà cung cấp (SupplierID và CompanyName) vào
các nút của cây Trong đó SupplierID nạp vào thuộc tính Key và Company nạp vào thuộc tính Text Tuy nhiên, cần lưu ý rằng, Thuộc tính Key của mỗi nút trên cây phải không được là số, trong khi đó thuộc tính SupplierID là một số (Autonumber) Do vậy, khi thêm ta sẽ ghép thêm một xâu ký tự - ví dụ "M1" – vào thuộc tính Key
Khi người dùng click vào một nút thì ta phải xem đó có phải là click vào Tên một công ty nào đó hay không ? Nếu đúng thì lấy các sản phẩm tương ứng với công ty này và cho hiển thị trong DataGrid Lưu ý là : trước đó, mỗi nút ta đã thêm "M1", nên khi chọn trong bảng CSDL cần phải bỏ xâu này trước khi so sánh
c Chương trình mẫu
Option Explicit
Sub NapMaNhaCC()
Dim strConn As String
strConn="Provider=Microsoft.jet.oledb.4.0;Data Source=" & App.Path & "\Nwind.mdb" adoDSKH.ConnectionString = strConn
adoMaNCC.CommandType = adCmdText
adoMaNCC.RecordSource = "SELECT SupplierID, CompanyName FROM Suppliers"
adoMaNCC.Refresh
tvwNhaCC.Nodes.Clear '/// Xoá cây
tvwNhaCC.LabelEdit = tvwManual '/// Không cho sửa đổi nhãn của nút
tvwNhaCC.Nodes.Add , , "NUT_GOC", "Tên các nhà cung cấp" '/// Tạo nút gốc
Do While adoMaNCC.Recordset.EOF = False
tvwNhaCC.Nodes.Add "NUT_GOC", tvwChild, "M1" &
adoMaNCC.Recordset!SupplierID, adoMaNCC.Recordset!CompanyName adoMaNCC.Recordset.MoveNext
Private Sub Form_Load()
Call NapMaNhaCC '/// Nạp các nhà cung cấp vào các nút của Cây
adoMaNCC.Visible = False '/// Ẩn adoMaNCC
adoSanPham.Visible = False '/// Ẩn adoSanPham
End Sub
' -
'/// Sự kiện này xuất hiện khi người dùng click lên một nút của cây
Private Sub tvwNhaCC_NodeClick(ByVal Node As MSComctlLib.Node)
If Node.Key = "NUT_GOC" Then Exit Sub '/// Nếu là nút gốc thì thoát
Dim MaNCC As String
MaNCC = Mid(Node.Key, 3) '///Bỏ xâu ký tự "M1" ở đầu đi, chỉ lấy phần Mã NCC thôi
'/// Cần phải kiểm tra nếu adoSanPham đang mở 1 bảng thì cần phải đóng lại
If Not (adoSanPham.Recordset Is Nothing) Then adoSanPham.Recordset.Close
adoSanPham.ConnectionString = "Provider=Microsoft.jet.oledb.4.0; Data Source=" &
adoSanPham.CommandType = adCmdText
adoSanPham.RecordSource = "SELECT * FROM Products WHERE SupplierID=" &
Trang 19MaNCC adoSanPham.Refresh
Set dgrSanPham.DataSource = adoSanPham '/// Hiển thị các sản phẩm
End Sub
Bài 9: Sử dụng với TreeView
a Thiết kế giao diện
Hình 5.34 - Hiển thị sản phầm trong ListView
b Hướng dẫn: Tham khảo chương IV, phần Listview, TreeView Trong đó,
lvwSanPham.ListItems.Add để thêm một hàng (bản ghi) mới Sau đó trỏ tới bản ghi này và thêm nội dung của các cột 2, cột 3, )
Dim strConn As String
strConn="Provider=Microsoft.jet.oledb.4.0;Data Source=" & App.Path & "\Nwind.mdb" adoDSKH.ConnectionString = strConn
Do While adoMaNCC.Recordset.EOF = False
tvwNhaCC.Nodes.Add "NUT_GOC", tvwChild, "M1" & adoMaNCC.Recordset!SupplierID,
adoMaNCC.Recordset!CompanyName adoMaNCC.Recordset.MoveNext
Trang 20lvwSanPham.View = lvwReport
lvwSanPham.GridLines = True
End Sub
Private Sub Form_Load()
Call NapMaNhaCC '/// Nạp mã nhà cung cấp
Call KhoiTaoListView '/// Khởi tạo ListView
'/// Thủ tục này được kích hoạt khi người dùng click vào một nút trên cây
Private Sub tvwNhaCC_NodeClick(ByVal Node As MSComctlLib.Node)
If Node.Key = "NUT_GOC" Then Exit Sub '/// Nếu là nút gốc thì không xử lý
Dim MaNCC As String, Nut As ListItem
If Not (adoSanPham.Recordset Is Nothing) Then adoSanPham.Recordset.Close
MaNCC = Mid(Node.Key, 3) '///Bỏ xâu ký tự "M1" ở đầu đi, chỉ lấy phần Mã NCC thôi
adoSanPham.ConnectionString= "Provider=Microsoft.jet.oledb.4.0;Data Source=" & _
App.Path & "\Nwind.mdb"
Bài 10: Xây dựng cây nhiều mức để xem thông tin về những sản phẩm đã bán
a Thiết kế giao diện
Hình 5.35 – Tên của các điều khiển trong chương trình
b Hướng dẫn
Trang 21• Thuật toán ở đây là : Nạp từng Mã nhà cung cấp và ứng với mỗi nhà cung cấp thì lại nạp các sản phẩm vào nút của nhà cung cấp đó (Tức dùng vòng lặp lồng nhau)
• Lưu ý với điều khiển Treeview: Khi thêm một nút vào cây thì giá trị Key của mỗi nút không được là SỐ Nhưng trong CSDL, trường SupplierID lại là một trường số (Autonumber), do vậy để giải quyết sự bất tiện này thì trước khi thêm một nút thì ta thêm thuộc tính Key một xâu ký tự, ví dụ "M1", "M2" tương ứng với các mức Chẳng hạn với nút gốc (Mức 0) thì ta thêm xâu "M0", với mức 1 thì ta thêm xâu "M1" Điều này cũng rất thuận tiện về sau, khi người dùng click vào một nút thì chỉ cần lấy 2 ký tự đầu của thuộc tính Key ta
sẽ biết ngay là nút được click thuộc mức mấy để có xử lý phù hợp !
c Chương trình mẫu
Option Explicit
Dim strConn As String
' -
'//// Nạp Mã nhà cung cấp và các sản phẩm của nhà cung cấp đó khi nạp form
Private Sub Form_Load()
Do While adoMaNCC.Recordset.EOF = False
Key = "M1" & adoMaNCC.Recordset!SupplierID
tvwNhaCC.Nodes.Add "M0NUT_GOC",tvwChild, Key,adoMaNCC.Recordset!CompanyName
Trang 22' -
'/// Nạp các sản phẩm vào nút nhà cung cấp Nút này có mà là MaNCC
'/// Vì trường Key của mỗi nút chứa xâu "M1" & SupplierID, do vậy khi Select cần phải bỏ
'/// xâu "M1" đi bằng cách viết Mid(MaNCC,3)
'/// Cũng giống như trường SupplierID, trường ProductID cũng là trường số, do vậy cần
'/// phải thêm một xâu, ví dụ "M2" vào thuộc tính Key
' -
Sub NapSanPhamVaoNCC(MaNCC As String)
Dim MaSP As String, TenSP As String
' -'/// Hiển thị tất cả các hoá đơn có xuất hiện mặt hàng vừa được click chọn
'/// Vì nút đang được chọn có MaSP = "M2" & ProductID, do vậy để lấy ra mã sản phẩm
'/// thực sự cho câu lệnh truy vấn thì cần phải bỏ xâu "M2", tức là viết : Mid(MaSP,3)
' -Sub CTDonHang(MaSP As String)
Dim MucMoi As ListItem
Do While adoCTDonHang.Recordset.EOF = False
Set MucMoi = lvwCTDonHang.ListItems.Add(, , adoCTDonHang.Recordset!OrderID)
MucMoi.SubItems(1) = adoCTDonHang.Recordset!UnitPrice & " $"
'/// Khi người dùng click một nút thì cần trích 2 ký tự đầu để biết là người dùng click vào
'/// nút gốc (M0), tên nhà cung cấp (M1) hay sản phẩm (M2) để có xử lý phù hợp
'/// Thuộc tính Node sẽ cho biết thông tin (trỏ đến) nút được chọn
Private Sub tvwNhaCC_NodeClick(ByVal Node As MSComctlLib.Node)
Trang 23Select Case Left(Node.Key, 2) '/// Lấy 2 ký tự đầu
Case "M0" '/// Click vào nỳt gốc
Case "M1" '/// Click vào Nhà cung cấp
Case "M2" '/// Click vào sản phẩm
lblCTDonHang.Caption="Các đơn hàng có SP " &tvwNhaCC.SelectedItem.Parent.Text CTDonHang Node.Key
• Xột cõu lệnh SELECT ở trờn: adoSanPham.RecordSource = "Select * from
Products where SupplierID=" & Mid(MaNCC,3) ở đõy vỡ trường SupplierID là một trường số nờn ta khụng phải kốm thờm cặp dấu nhỏy đơn Trong trường hợp trường đem so sỏnh là trường text thỡ phải kốm thờm cặp nhỏy đơn Vớ
dụ nếu chọn cỏc bản ghi cú CompanyName = giỏ trị trong text1 thỡ phải viết:
adoSanPham.RecordSource = "Select * from Products where CompanyName
= '" & text1.text & "'"
• Trong cõu lệnh SQL, nếu tờn bảng (hoặc tờn trường) cú chứa dấu cỏch (Vớ dụ bảng "Order details") thỡ cần phải đặt trong cặp ngoặc vuụng Vớ dụ phải viết:
SELECT * FROM [Order details] Tổng quỏt, trong nhiều trường hợp, cú thể
giải quyết vấn đề tờn chứa dấu cỏch bằng việc thờm cặp ngoặc [ ]
• Cú 2 cỏch truy cập đến giỏ trị của một trường Cỏch viết
"Nếu người dựng click vào một nỳt thỡ lỳc đú mới nạp cỏc nỳt con !"
Bài 11: Bổ sung thờm một trường mới trong cõu lệnh SELECT
a Thiết kế giao diện : Như bài tập 10
b Hướng dẫn : Trong cõu lệnh SELECT, chỳng ta hoàn toàn cú thể bổ sung hoặc
thờm mới một trường Tờn trường mới cú thể dẫn xuất từ cỏc trường đó cú và được
đặt tờn bởi từ khoỏ AS Khi đú ta truy cập đến trường mới này một cỏch bỡnh thường
như cỏc trường khỏc Tuy nhiờn, trường này khụng thực sự thờm vào bảng gốc
c Chương trỡnh mẫu :
Option Explicit
Dim strConn As String
' -
'//// Nạp Mó nhà cung cấp và cỏc sản phẩm của nhà cung cấp đú khi nạp form
Private Sub Form_Load()
strConn = "Provider=Microsoft.jet.oledb.4.0;"
strConn = strConn & "Data source= " & App.Path & "\Nwind.mdb"
Call NapMaNhaCC
Trang 24Do While adoMaNCC.Recordset.EOF = False
Key = "M1" & adoMaNCC.Recordset!SupplierID
tvwNhaCC.Nodes.Add "M0NUT_GOC",tvwChild, Key,adoMaNCC.Recordset!CompanyName
'/// Nạp các sản phẩm vào nút nhà cung cấp Nút này có mà là MaNCC
'/// Vì trường Key của mỗi nút chứa xâu "M1" & SupplierID, do vậy khi Select cần phải bỏ
'/// xâu "M1" đi bằng cách viết Mid(MaNCC,3)
'/// Cũng giống như trường SupplierID, trường ProductID cũng là trường số, do vậy cần
'/// phải thêm một xâu, ví dụ "M2" vào thuộc tính Key
' -
Sub NapSanPhamVaoNCC(MaNCC As String)
Dim MaSP As String, TenSP As String