188
TRUNG TÂM TIN HC – ĐẠI HC KHOA HC TNHIÊN TP.HCM 227 Nguyn Văn C- Qun 5- Tp.HChí Minh Tel: 8351056 – Fax 8324466 – Email: [email protected] Mã tài liu: DT_NCM_LT_TLGD_LTN1 Phiên bn 1.2 – Tháng 07/2006 TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏY CHÖÔNG TRÌNH KYÕ THUAÄT VIEÂN NGAØNH LAÄP TRÌNH Hoïc phaàn 3 VISUAL BASIC .NET

TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

  • Upload
    others

  • View
    4

  • Download
    0

Embed Size (px)

Citation preview

Page 1: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

TRUNG TÂM TIN HỌC – ĐẠI HỌC KHOA HỌC TỰ NHIÊN TP.HCM 227 Nguyễn Văn Cừ - Quận 5- Tp.Hồ Chí Minh Tel: 8351056 – Fax 8324466 – Email: [email protected]

Mã tài liệu: DT_NCM_LT_TLGD_LTN1 Phiên bản 1.2 – Tháng 07/2006

TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏY

CHÖÔNG TRÌNH KYÕ THUAÄT VIEÂN

NGAØNH LAÄP TRÌNH

Hoïc phaàn 3

VISUAL BASIC .NET

Page 2: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 2/187

MỤC LỤC GIỚI THIỆU ...........................................................................................................9

GIÁO TRÌNH LÝ THUYẾT......................................................................................10

TÀI LIỆU THAM KHẢO..........................................................................................10

Bài 1.....................................................................................................................11

TỔNG QUAN .NET FRAMEWORK ..........................................................................11

I. Tổng quan về .Net Framework ......................................................................12

II. Cấu trúc .Net Framework...............................................................................14

II.1. Hệ điều hành ...............................................................................................14

II.2. Cung cấp các chức năng xây dựng ứng dụng .................................................14

II.3. Common Language Runtime .........................................................................15

II.4. Bộ thư viện các lớp đối tượng .......................................................................15

II.5. Phân nhóm các lớp đối tượng theo loại ...........................................................16

III. Ứng dụng đầu tiên .........................................................................................17

III.1. Môi trường lập trình VS .NET .........................................................................17

III.2. Tạo mới một project .....................................................................................18

III.3. Ứng dụng Hello ............................................................................................19

III.4. Windows Form Designer................................................................................21

III.5. Thử nghiệm..................................................................................................23

III.6. Kỹ thuật lập trình hướng đối tượng ................................................................25

III.7. Xây dựng lớp đối tượng ................................................................................27

III.8. Sử dụng lại thành phần có sẵn ......................................................................28

III.9. Assembly - một loại DLL mới..........................................................................32

Bài 2.....................................................................................................................34

NGÔN NGỮ VISUAL BASIC .NET ..........................................................................34

I. Các kiểu dữ liệu và đặc điểm .........................................................................35

I.1. Các kiểu dữ liệu............................................................................................35

I.2. Đặc điểm của các kiểu dữ liệu .......................................................................36

Page 3: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 3/187

II. Biến – Tính chất, khai báo và khởi tạo...........................................................40

II.1. Tính chất .....................................................................................................40

II.2. Khai báo và khởi tạo .....................................................................................41

II.3. Kiểu trị và tham chiếu (Value Type và Reference Type)....................................42

II.4. Kiểu Enum (Enumeration)..............................................................................44

III. Mảng – Structure...........................................................................................45

III.1. Mảng ...........................................................................................................45

III.2. Structure......................................................................................................47

IV. Các toán tử ....................................................................................................47

IV.1. Toán tử toán học ..........................................................................................47

IV.2. Toán tử nối chuỗi..........................................................................................48

IV.3. Toán tử gán .................................................................................................48

IV.4. Toán tử so sánh............................................................................................48

IV.5. Toán tử luận lý và Bitwise..............................................................................49

V. Cấu trúc điều khiển........................................................................................49

V.1. Cấu trúc chọn...............................................................................................49

V.2. Cấu trúc lặp..................................................................................................51

VI. Những thay đổi trong VB.NET........................................................................52

VI.1. Thay đổi trong thủ tục và hàm.......................................................................52

VI.2. Khai báo Option Strict ...................................................................................53

VI.3. Kiểu chuỗi có độ dài cố định ..........................................................................54

VI.4. Chỉ thị #Region … #End Region.....................................................................54

VI.5. Imports không gian tên (Namespace).............................................................54

VII. Xử lý lỗi..........................................................................................................55

VII.1. Phân loại lỗi ............................................................................................55

VII.2. Xử lý lỗi ..................................................................................................55

Bài 3.....................................................................................................................59

LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG TRONG VISUAL BASIC .NET ............................59

I. Lập trình hướng đối tượng.............................................................................60

I.1. Tính trừu tượng............................................................................................60

I.2. Tính bao bọc ................................................................................................60

Page 4: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 4/187

I.3. Tính kế thừa.................................................................................................61

I.4. Tính đa hình.................................................................................................61

II. Lập trình hướng đối tượng trong VB.NET ......................................................62

II.1. Tạo một Class...............................................................................................62

II.2. Tạo một NameSpace mới...............................................................................63

II.3. Tạo một Class kế thừa ..................................................................................64

II.4. Khai báo phương thức (Method).....................................................................64

II.5. Khai báo thuộc tính (Property) .......................................................................67

II.6. Khai báo sự kiện (Event) ...............................................................................69

II.7. Từ khóa Me, Mybase, MyClass .......................................................................71

II.8. Khởi tạo thể hiện ..........................................................................................73

II.9. Abstract Base Class.......................................................................................73

II.10. Giao tiếp (Interface)......................................................................................74

II.11. Lớp lồng ghép ..............................................................................................75

II.12. Từ khóa Delegate .........................................................................................76

Bài 4.....................................................................................................................78

TỔNG QUAN VỀ ADO.NET ....................................................................................78

I. Tổng quan......................................................................................................79

II. Kiến trúc ADO .Net.........................................................................................80

III. Các đặc điểm của ADO.Net ............................................................................81

III.1. Interoperability – Tương tác giữa nhiều hệ thống khác nhau ............................81

III.2. Scalability - Hỗ trợ nhiều người dùng..............................................................82

III.3. Productivity - Mở rộng khả năng làm việc với CSDL..........................................82

III.4. Performance - Hiệu quả cao trong xử lý dữ liệu...............................................82

IV. Content Component.......................................................................................83

IV.1. DataSet........................................................................................................83

IV.2. DataTable ....................................................................................................84

IV.3. DataRelation.................................................................................................84

IV.4. Ràng buộc trên quan hệ ................................................................................84

IV.5. DataView .....................................................................................................85

V. Managed Provider Component ......................................................................85

Page 5: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 5/187

V.1. Connection ..................................................................................................86

V.2. Command ....................................................................................................86

V.3. DataReader .................................................................................................86

V.4. DataAdapter.................................................................................................86

Bài 5.....................................................................................................................88

CONNECTION, COMMAND, DATAADAPTER .........................................................88

I. Connection.....................................................................................................89

I.1. Data Provider ...............................................................................................89

I.2. ConnectionString ..........................................................................................89

I.3. Các thuộc tính khác của Connection ...............................................................91

I.4. Các phương thức trên Connection ..................................................................91

I.5. Minh họa tạo Connection ...............................................................................91

II. Command ......................................................................................................92

II.1. Tạo Command..............................................................................................92

II.2. Các thuộc tính của Command ........................................................................92

II.3. Parameter ....................................................................................................93

II.4. Thực hiện Command .....................................................................................95

II.5. DataReader ..................................................................................................96

III. DataAdapter ..................................................................................................97

III.1. Tạo DataAdapter ..........................................................................................97

III.2. Các thuộc tính chính của DataAdapter ............................................................98

III.3. Các chức năng của DataAdapter.....................................................................99

Bài 6...................................................................................................................105

DATASET, DATATABLE, DATARELATION VÀ DATAVIEW....................................105

I. DataSet........................................................................................................106

I.1. Khai báo DataSet ........................................................................................ 106

I.2. Các thuộc tính của DataSet.......................................................................... 106

I.3. Các phương thức của DataSet .................................................................... 106

II. DataTable ....................................................................................................112

II.1. Các thuộc tính của DataTable ...................................................................... 112

II.2. DataColumn ............................................................................................... 113

Page 6: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 6/187

II.3. DataRow.................................................................................................... 115

II.4. Constraint .................................................................................................. 117

II.5. Tập hợp Columns........................................................................................ 119

II.6. Tập hợp Rows ............................................................................................ 121

II.7. Tập hợp Constraints.................................................................................... 124

II.8. Một số phương thức của DataTable .............................................................. 124

II.9. Các sự kiện của DataTable........................................................................... 126

III. DataRelation................................................................................................127

III.1. Khởi tạo ..................................................................................................... 127

III.2. Các thuộc tính của DataRelation................................................................... 128

III.3. Minh họa thiết lập quan hệ .......................................................................... 128

IV. DataView .....................................................................................................129

IV.1. Khởi tạo ..................................................................................................... 129

IV.2. Các thuộc tính chính của DataView............................................................... 129

IV.3. Các thao tác chính của DataView ................................................................. 130

IV.4. DataRowView ............................................................................................. 131

Bài 7...................................................................................................................133

XÂY DỰNG CÁC LỚP XỬ LÝ................................................................................133

I. Mô hình đa tầng (N-tier)..............................................................................134

II. Xây dựng lớp xử lý lưu trữ...........................................................................134

II.1. Các khai báo .............................................................................................. 135

II.2. Khai báo các thuộc tính ............................................................................... 135

II.3. Khai báo phương thức khởi tạo .................................................................... 137

II.4. Khai báo phương thức xử lý - cung cấp thông tin .......................................... 137

II.5. Khai báo các phương thức thực hiện lệnh ..................................................... 139

II.6. Nhóm xử lý sự kiện..................................................................................... 140

III. Xây dựng lớp xử lý nghiệp vụ ......................................................................140

III.1. Khai báo phương thức khởi tạo .................................................................... 140

III.2. Khai báo phương thức tìm kiếm thông tin ..................................................... 141

Bài 8...................................................................................................................142

THIẾT KẾ CÁC MÀN HÌNH..................................................................................142

Page 7: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 7/187

I. Các điều khiển hiển thị dữ liệu ....................................................................143

I.1. Thuộc tính liên kết dữ liệu của điều khiển ..................................................... 143

I.2. ComboBox, ListBox, CheckListBox ................................................................ 143

I.3. DataGrid .................................................................................................... 144

I.4. DataGridTableStyle và TableStyles................................................................ 146

I.5. DataGridColumnStyle và GridColumnStyles.................................................... 146

I.6. Thiết kế DataGrid........................................................................................ 147

I.7. Hiển thị dữ liệu ra điều khiển ....................................................................... 150

II. Màn hình đơn...............................................................................................152

II.1. Các khai báo .............................................................................................. 152

II.2. Các thủ tục nhập xuất ................................................................................. 152

II.3. Các hàm kiểm tra........................................................................................ 153

II.4. Các xử lý sự kiện ........................................................................................ 154

III. Màn hình một nhiều.....................................................................................157

III.1. Màn hình một-nhiều hai trang ...................................................................... 157

III.2. Màn hình một-nhiều ba trang....................................................................... 159

IV. Màn hình lọc dữ liệu ....................................................................................160

IV.1. Màn hình lọc một điều kiện.......................................................................... 160

IV.2. Màn hình lọc hai điều kiện ........................................................................... 161

V. Màn hình một-nhiều-nhiều..........................................................................161

VI. Một số kỹ thuật trong hiển thị dữ liệu .........................................................161

VI.1. Tạo lớp DataGridColumnStyle chuyển đổi dữ liệu hiển thị ............................... 161

VI.2. Tạo lớp DataGridColumnStyle có ComboBox.................................................. 162

VI.3. Tạo lớp DataGridColumnStyle cho phép định dạng chi tiết.............................. 162

VI.4. Minh họa sử dụng....................................................................................... 162

Bài 9...................................................................................................................166

BÁO BIỂU CRYSTAL REPORT .............................................................................166

I. Giới thiệu Crystal Report .............................................................................167

II. Tạo báo biểu ................................................................................................167

II.1. Nguồn dữ liệu cho báo biểu ......................................................................... 169

II.2. Sử dụng Crystal Report Viewer để hiển thị báo biểu....................................... 170

Page 8: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 8/187

II.3. Nguồn dữ liệu cho báo biểu từ DataSet ........................................................ 171

II.4. Định lại dữ liệu cho báo biểu từ nguồn CSDL................................................. 173

II.5. Lọc dữ liệu báo biểu.................................................................................... 175

II.6. Truyền tham số cho báo biểu....................................................................... 175

II.7. Các loại kết xuất báo biểu............................................................................ 175

ĐỀ THI MẪU CUỐI HỌC PHẦN ...........................................................................177

ĐỀ THI MẪU KIỂM TRA CHUYÊN MÔN GIÁO VIÊN ............................................181

Page 9: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 9/187

GIỚI THIỆU Sau khi hoàn thành khóa học này, học viên sẽ có các khả năng:

Lập trình hướng đối tượng với Visual Basic .Net

Lập trình cơ sở dữ liệu với ADO.Net

Xây dựng ứng dụng với Visual Basic .Net

Với thời lượng là 36 tiết LT và 60 tiết TH được phân bổ như sau:

STT Bài học Số tiết LT Số tiết TH

1 Tổng quan .Net Framework, Visual Studio .Net 3

2 Ngôn ngữ Visual Basic .Net 3 5

3 Lập trình hướng đối tượng với VB.Net 6 10

4 Tổng quan ADO.Net 1 00

5 Đối tượng Connection, Command và DataAdapter 2 5

6 DataSet, DataTable, DataRelation Và DataView 6 5

7 Xây dựng các lớp xử lý 3 10

8 Thiết kế các màn hình 6 15

9 Báo biểu và in ấn 6 10

Tổng số tiết: 36 60

Page 10: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 10/187

GIÁO TRÌNH LÝ THUYẾT Sử dụng giáo trình “Visual Basic.Net” tập 2 của Nhóm Chuyên môn Lập trình.

TÀI LIỆU THAM KHẢO

Page 11: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 11/187

HƯỚNG DẪN PHẦN LÝ THUYẾT

Bài 1

TỔNG QUAN .NET FRAMEWORK

Tóm tắt Lý thuyết 3 tiết

Mục tiêu Các mục chính Bài tập

Giới thiệu các khái niệm cơ bản và cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một ứng dụng để giới thiệu về Visual Studio .Net.

1. Tổng quan .Net Framework

2. Cấu trúc .Net Framework

3. Ứng dụng đầu tiên

Page 12: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 12/187

I. Tổng quan về .Net Framework Ngày 13/02/2002, Microsoft chính thức giới thiệu bộ công cụ lập trình mới của mình – Visual Studio.NET. Sau 4 năm không tung ra phiên bản mới cho bộ Visual Studio 98, lần này Microsoft quyết tâm đặt cược vào thắng lợi của công nghệ mới: Microsoft .NET.

Trong thời đại công nghệ thông tin, dữ liệu trở nên quan trọng đến nỗi người ta mong muốn tất cả mọi thứ như điện thoại di động, máy tính xách tay, các máy PDA (Personal Digital Assistant) đều phải kết nối với nhau để chia sẽ dữ liệu và việc sử dụng các phần mềm để quản lý, sử dụng những dữ liệu đó là "không biên giới". Ứng dụng phải sẵn sàng để sử dụng từ trên máy tính cũng như trên điện thoại di động 24/24 giờ, ít lỗi, xử lý nhanh và bảo mật chặt chẽ.

Các yêu cầu này làm đau đầu những chuyên gia phát triển ứng dụng khi phần mềm chủ yếu viết cho hệ thống này không chạy trên một hệ thống khác bởi nhiều lý do như khác biệt về hệ điều hành, khác biệt về chuẩn giao tiếp dữ liệu, mạng. Thời gian và chi phí càng trở nên quý báu vì bạn không phải là người duy nhất biết lập trình. Làm sao sử dụng lại những ứng dụng đã viết để mở rộng thêm nhưng vẫn tương thích với những kỹ thuật mới?

Sun Microsystems đi đầu trong việc cung cấp giải pháp với Java. Java chạy ổn định trên các hệ điều hành Unix hay Solaris của Sun từ máy chủ tới các thiết bị cầm tay hay thậm chí trên các hệ điều hành Windows của Microsoft (một ví dụ rõ ràng đó là hầu hết các điện thoại di động thế hệ mới đều có phần mềm viết bằng Java). Kiến trúc lập trình dựa trên Java bytecode và thi hành trên máy ảo Java (JVM – Java Virtual Marchine) cho phép các ứng dụng Java chạy trên bất cứ hệ điều hành nào. Mô hình lập trình thuần hướng đối tượng của Java giúp các lập trình viên tùy ý sử dụng lại và mở rộng các đối tượng có sẵn. Các nhà cung cấp công cụ lập trình dựa vào đây đểø gắn vào các môi trường phát triển ứng dụng bằng Java của mình đủ các thư viện lập trình nhằm hỗ trợ các lập trình viên.

Sức mạnh của Java dường như quá lớn đến nỗi Microsoft từng phải chống trả bằng cách loại bỏ Java Virtual Marchine khỏi các phiên bản hệ điều hành Windows mới của mình như Windows XP. Tuy nhiên, Microsoft thừa hiểu rằng dù không cung cấp JVM, Sun cũng có thể tự cung cấp các JVM package cho những người dùng Windows. Đó là lý do tại sao nhà khổng lồ quyết định bắt tay xây dựng lại từ đầu một nền tảng phát triển ứng dụng mới: Microsoft.NET Framework.

Vì ra đời khá muộn so với Java, .Net bị coi là khá giống với bậc "tiền bối" của nó. .NET sử dụng kỹ thuật lập trình thuần hướng đối tượng như Java và cũng thi hành trên một máy ảo là CLR (Common Language Runtime).

Bộ thư viện của .NET Framework bao gồm hơn 5000 lớp đối tượng đủ sức hỗ trợ hầu hết các yêu cầu từ phía lập trình viên. Công nghệ mã nguồn mở được đưa vào .NET thay cho COM và DCOM đang được các lập trình viên của Microsoft sử dụng. Với COM, những thành phần (COMponent) đã được xây dựng như các lớp thư viện hay các control chỉ có thể sử dụng lại. Bạn không thể mở rộng chúng hay viết lại cho thích hợp với ứng dụng của mình. Trong .NET, mọi thành phần đều có thể kế thừa và mở rộng, một kỹ thuật mới được đưa ra thay cho COM là Assembly. Distributed Component hay DCOM là kỹ thuật dùng để phối hợp các thành phần trên nhiều máy tính giờ đây được thay thế trong .NET bởi chuẩn công nghệ mới là SOAP và XML Web Service.

Cùng với SOAP (Simple Objects Access Protocol), XML Web Service mở rộng khả năng của DCOM từ chỗ chỉ phối hợp các máy trong Intranet, nằm sau Firewall ra Internet. Các công ty .com giờ đây mặc sức xây dựng các phần mềm độc lập của mình những vẫn có thể phối hợp với nhau để đem tới khách

Page 13: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 13/187

hàng các dịch vụ e-commerce đa dạng nhưng thống nhất.

XML (eXtended Markup Language) - chuẩn lưu trữ và trao đổi dữ liệu mới nhất, hiệu quả nhất hiện nay cũng được .NET hỗ trợ khá đầy đủ. Chỉ cần một công cụ chuyển đổi đơn giản mà thậm chí bạn cũng có thể tự viết (đương nhiên khi bạn đã biết về XML), các dữ liệu trước kia của bạn dù ở bất cứ dạng lưu trữ nào cũng có thể chuyển về dạng XML để sử dụng trong các ứng dụng mới hay trao đổi với hệ thống ứng dụng khác. .NET giờ đây cũng sử dụng kỹ thuật truy cập cơ sở dữ liệu mới là ADO.NET để bổ sung cho kỹ thuật ADO - trước kia vốn là thành phần mạnh nhất trong MDAC (Microsoft Data Access Component gồm có 3 phần DB-Lib, OLEDB và ADO)- khả năng làm việc với dữ liệu XML. Bạn cũng nên biết rằng kể từ SQL Server 2000, XML đã được hỗ trợ trong phần mềm quản trị cơ sở dữ liệu nổi tiếng nhất của Microsoft và phiên bản SQL Server sắp tới chắc chắn không xem nhẹ XML chút nào. Cùng với XML, SOAP và Web service đang là những vũ khí mạnh nhất mà Microsoft sử dụng để qua mặt Java.

Cũng không thể quên CLR, máy ảo của các ứng dụng viết bằng .NET. Common Language Runtime (CLR) được sử dụng để thực hiện các đoạn chương trình ở dạng mã IL (Immediate Language). Điều này có nghĩa là dầu bạn lập trình bằng ngôn ngữ nào bạn thích, một khi có thể biên dịch sang mã IL, bạn sẽ yên tâm rằng CLR sẽ thi hành nó một cách suôn sẽ. Giống như JVM của Java, CLR bao gồm trong nó nhiều thành phần quản lý ứng dụng khi thi hành như JIT (Just In Time compiler) để biên dịch ngay tại thời điểm thi hành những đoạn lệnh IL cần thiết hay Garbage Collector giữ vai trò thu gom "rác rưởi" mà ứng dụng để sót lại nhằm sử dụng hiệu quả bộ nhớ. Ngoài ra, CLR không quên hỗ trợ việc quản lý các ứng dụng trước đây viết trên kỹ thuật COM. Nó đảm bảo cho bạn không phải bỏ đi những gì đã "dày công xây đắp" trước đây mà vẫn có thể phối hợp nó với các ứng dụng mới viết trên .NET.

Một điểm nữa không thể bỏ qua khi giới thiệu về .NET Framework, đó là thành phần Common Language Specification. Vai trò của thành phần này là đảm bảo sự tương tác giữa các đối tượng bất chấp chúng được xây dựng trong ngôn ngữ nào, miễn là chúng cung cấp được những thành phần chung của các ngôn ngữ muốn tương tác. Thành phần Common Language Runtime được xây dựng với mục đích mô tả các yêu cầu cần thiết của một ngôn ngữ để có thể sử dụng trong lập trình và biên dịch thành mã IL. Một khi đã ở dạng mã IL, ứng dụng đã có thể chạy trên CLR và như thế bạn đã có khả năng dùng ngôn ngữ lập trình mà mình yêu thích để tận dụng các khả năng mạnh mẽ của .NET.

Trước đây, các lập trình viên đã quen dùng Visual C++ hay Visual Basic 6 hay Visual InterDEV mỗi khi cần xây dựng một loại ứng dụng khác phải chuyển qua lại giữa các môi trường lập trình khác nhau của Visual Studio 98 và chợt nhận ra rằng VB 6 không có điểm mạnh này của C++ hoặc C++ không làm nhanh được chức năng kia của VB 6,… sẽ cảm thấy nhẹ nhõm vì với .NET giờ đây, mọi sức mạnh của các ngôn ngữ lập trình đều như nhau. .NET Framework hỗ trợ một bộ thư viện lập trình đồ sộ hơn 5000 lớp đối tượng để bạn đủ khả năng xây dựng các loại ứng dụng từ kiểu console (ứng dụng dòng lệnh), ứng dụng trên Windows cho tới các ứng dụng Web, các service của hệ điều hành và các Web service trên Internet.

Trước khi chấm dứt phần giới giới thiệu, cũng cần phải đề cập đến bộ control đồ sộ và mới mẻ của .NET. Rất nhiều điều khiển mới được thêm vào .NET Framework để hỗ trợ cho các ứng dụng có giao diện đồ họa trên Windows và trên Web một "vẻ mặt" mới. Những công cụ này không chỉ hỗ trợ chuẩn font chữ Unicode nhưng còn kết hợp với khả năng xây dựng ứng dụng mang tính "quốc tế" khi người lập trình phải đáp ứng nhiều ngôn ngữ, nhiều định dạng ngày giờ hay tiền tệ khác nhau.

Microsoft không quên đem lại một môi trường phát triển ứng dụng sử dụng giao diện đồ hoạ, tích hợp nhiều chức năng, tiện ích khác nhau để hỗ trợ tối đa cho các lập trình viên, đó chính là Visual

Page 14: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 14/187

Studio.NET.

.NET Framework là thành phần quan trọng nhất trong kỹ thuật phát triển ứng dụng dựa trên .NET. Visual Studio sẽ giúp người lập trình nắm bắt và tận dụng tốt hơn những chức năng của .NET Framework. Phần dưới đây giới thiệu những kiến thức cơ bản nhất về .NET Framework trước khi chúng ta thực sự bắt tay vào làm việc với Visual Studio.NET và VB.NET.

II. Cấu trúc .Net Framework Trong phần này, chúng ta tìm hiểu các thành phần bên trong .NET Framework.

Cấu trúc .NET FrameworkN

II.1. Hệ điều hành .NET Framework cần được cài đặt và sử dụng trên một hệ điều hành. Hiện tại, .NET Framework chỉ có khả năng làm việc trên các hệ điều hành Microsoft Win32 và Win64 mà thôi. Trong thời gian tới, Microsoft sẽ đưa hệ thống này lên Windows CE cho các thiết bị cầm tay và có thể mở rộng cho các hệ điều hành khác như Unix.

II.2. Cung cấp các chức năng xây dựng ứng dụng Với vai trò quản lý việc xây dựng và thi hành ứng dụng, .NET Framework cung cấp các lớp đối tượng (Class) để bạn có thể gọi thi hành các chức năng mà đối tượng đó cung cấp. Tuy nhiên, lời kêu gọi của bạn có được "hưởng ứng" hay không còn tùy thuộc vào khả năng của hệ điều hành đang chạy ứng dụng của bạn.

Các chức năng đơn giản như hiển thị một hộp thông báo (Messagebox) sẽ được .NET Framework sử dụng các hàm API của Windows. Chức năng phức tạp hơn như sử dụng các COMponent sẽ yêu cầu Windows phải cài đặt Microsoft Transaction Server (MTS) hay các chức năng trên Web cần Windows phải cài đặt Internet Information Server (IIS).

Như vậy, bạn cần biết rằng lựa chọn một hệ điều hành để cài đặt và sử dụng .NET Framework cũng không kém phần quan trọng. Cài đặt .NET Framework trên các hệ điều hành Windows 2000, 2000

OOppeerraattiinngg SSyysstteemm

CCoommmmoonn LLaanngguuaaggee RRuunnttiimmee

BB aass ee CC llaass ss LL iibb rraa rryy

AADDOO ..NNEETT aanndd XXMMLL

AASSPP ..NNEETT WWeebb FFoorrmmss WWeebb SSeerrvviicceess

MMoobbiillee IInntteerrnneett TToooollkkiitt

WWiinnddoowwss FFoorrmmss

CCoommmmoonn LLaanngguuaaggee SSppeecciiffiiccaattiioonn

VVBB CC++++ CC## JJ## ……

Page 15: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 15/187

Server, XP, XP.NET, 2003 Server sẽ đơn giản và tiện dụng hơn trong khi lập trình.

II.3. Common Language Runtime Là thành phần "kết nối" giữa các phần khác trong .NET Framework với hệ điều hành. Common Language Runtime (CLR) giữ vai trò quản lý việc thi hành các ứng dụng viết bằng .NET trên Windows. CLR sẽ thông dịch các lời gọi từ chương trình cho Windows thi hành, đảm bảo ứng dụng không chiếm dụng và sử dụng tràn lan tài nguyên của hệ thống. Nó cũng không cho phép các lệnh "nguy hiểm" được thi hành. Các chức năng này được thực thi bởi các thành phần bên trong CLR như Class loader, Just In Time compiler, Garbage collector, Exception handler, COM marshaller, Security engine,…

Trong các phiên bản hệ điều hành Windows mới như XP.NET và Windows 2003, CLR được gắn kèm với hệ điều hành. Điều này đảm bảo ứng dụng viết ra trên máy tính của chúng ta sẽ chạy trên máy tính khác mà không cần cài đặt, các bước thực hiện chỉ đơn giản là một lệnh copy của DOS!

II.4. Bộ thư viện các lớp đối tượng Nếu phải giải nghĩa từ "Framework" trong thuật ngữ .NET Framework thì đây là lúc thích hợp nhất. Framework chính là một tập hợp hay thư viện các lớp đối tượng hỗ trợ người lập trình khi xây dựng ứng dụng. Có thể một số người trong chúng ta đã nghe qua về MFC và JFC. Microsoft Foundation Class là bộ thư viện mà lập trình viên Visual C++ sử dụng trong khi Java Foundation Class là bộ thư viện dành cho các lập trình viên Java. Giờ đây, có thể coi .NET Framework là bộ thư viện dành cho các lập trình viên .NET

Với hơn 5000 lớp đối tượng để gọi thực hiện đủ các loại dịch vụ từ hệ điều hành, chúng ta có thể bắt đầu xây dựng ứng dụng bằng Notepad.exe!!!… Nhiều người lầm tưởng rằng các môi trường phát triển phần mềm như Visual Studio 98 hay Visual Studio.NET là tất cả những gì cần để viết chương trình. Thực ra, chúng là những phần mềm dùng làm "vỏ bọc" bên ngoài. Với chúng, chúng ta sẽ viết được các đoạn lệnh đủ các màu xanh, đỏ; lỗi cú pháp báo ngay khi đang gõ lệnh; thuộc tính của các đối tượng được đặt ngay trên cửa sổ properties, giao diện được thiết kế theo phong cách trực quan… Như vậy, chúng ta có thể hình dung được tầm quan trọng của .NET Framework. Nếu không có cái cốt lõi .NET Framework, Visual Studio.NET cũng chỉ là cái vỏ bọc! Nhưng nếu không có Visual Studio.NET, công việc của lập trình viên .NET cũng lắm bước gian nan!

II.4.1. Base class library – thư viện các lớp cơ sở

Đây là thư viện các lớp cơ bản nhất, được dùng trong khi lập trình hay bản thân những người xây dựng .NET Framework cũng phải dùng nó để xây dựng các lớp cao hơn. Ví dụ các lớp trong thư viện này là String, Integer, Exception,…

II.4.2. ADO.NET và XML

Bộ thư viện này gồm các lớp dùng để xử lý dữ liệu. ADO.NET thay thế ADO để trong việc thao tác với các dữ liệu thông thường. Các lớp đối tượng XML được cung cấp để bạn xử lý các dữ liệu theo định dạng mới: XML. Các ví dụ cho bộ thư viện này là SqlDataAdapter, SqlCommand, DataSet, XMLReader, XMLWriter,…

II.4.3. ASP.NET

Bộ thư viện các lớp đối tượng dùng trong việc xây dựng các ứng dụng Web. ASP.NET không phải là phiên bản mới của ASP 3.0. Ứng dụng web xây dựng bằng ASP.NET tận dụng được toàn bộ khả năng

Page 16: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 16/187

của .NET Framework. Bên cạnh đó là một "phong cách" lập trình mới mà Microsoft đặt cho nó một tên gọi rất kêu : code behind. Đây là cách mà lập trình viên xây dựng các ứng dụng Windows based thường sử dụng – giao diện và lệnh được tách riêng. Tuy nhiên, nếu bạn đã từng quen với việc lập trình ứng dụng web, đây đúng là một sự "đổi đời" vì bạn đã được giải phóng khỏi mớ lệnh HTML lộn xộn tới hoa cả mắt.

Sự xuất hiện của ASP.NET làm cân xứng giữa quá trình xây dựng ứng dụng trên Windows và Web. ASP.NET cung cấp một bộ các Server Control để lập trình viên bắt sự kiện và xử lý dữ liệu của ứng dụng như đang làm việc với ứng dụng Windows. Nó cũng cho phép chúng ta chuyển một ứng dụng trước đây viết chỉ để chạy trên Windows thành một ứng dụng Web khá dễ dàng. Ví dụ cho các lớp trong thư viện này là WebControl, HTMLControl, …

II.4.4. Web services

Web services có thể hiểu khá sát nghĩa là các dịch vụ được cung cấp qua Web (hay Internet). Dịch vụ được coi là Web service không nhằm vào người dùng mà nhằm vào người xây dựng phần mềm. Web service có thể dùng để cung cấp các dữ liệu hay một chức năng tính toán.

Ví dụ, công ty du lịch của bạn đang sử dụng một hệ thống phần mềm để ghi nhận thông tin về khách du lịch đăng ký đi các tour. Để thực hiện việc đặt phòng khách sạn tại địa điểm du lịch, công ty cần biết thông tin về phòng trống tại các khách sạn. Khách sạn có thể cung cấp một Web service để cho biết thông tin về các phòng trống tại một thời điểm. Dựa vào đó, phần mềm của bạn sẽ biết rằng liệu có đủ chỗ để đặt phòng cho khách du lịch không? Nếu đủ, phần mềm lại có thể dùng một Web service khác cung cấp chức năng đặt phòng để thuê khách sạn. Điểm lợi của Web service ở đây là bạn không cần một người làm việc liên lạc với khách sạn để hỏi thông tin phòng, sau đó, với đủ các thông tin về nhiều loại phòng người đó sẽ xác định loại phòng nào cần đặt, số lượng đặt bao nhiêu, đủ hay không đủ rồi lại liên lạc lại với khách sạn để đặt phòng. Đừng quên là khách sạn lúc này cũng cần có người để làm việc với nhân viên của bạn và chưa chắc họ có thể liên lạc thành công.

Web service được cung cấp dựa vào ASP.NET và sự hỗ trợ từ phía hệ điều hành của Internet Information Server.

II.4.5. Window form

Bộ thư viện về Window form gồm các lớp đối tượng dành cho việc xây dựng các ứng dụng Windows based. Việc xây dựng ứng dụng loại này vẫn được hỗ trợ tốt từ trước tới nay bởi các công cụ và ngôn ngữ lập trình của Microsoft. Giờ đây, ứng dụng chỉ chạy trên Windows sẽ có thể làm việc với ứng dụng Web dựa vào Web service. Ví dụ về các lớp trong thư viện này là: Form, UserControl,…

II.5. Phân nhóm các lớp đối tượng theo loại Một khái niệm không được thể hiện trong hình vẽ trên nhưng cần đề cập đến là Namespace. Đây là tên gọi một nhóm các lớp đối tượng phục vụ cho một mục đích nào đó. Chẳng hạn, các lớp đối tượng xử lý dữ liệu sẽ đặt trong một namespace tên là Data. Các lớp đối tượng dành cho việc vẽ hay hiển thị chữ đặt trong namespace tên là Drawing.

Một namespace có thể là con của một namespace lớn hơn. Namespace lớn nhất trong .NET Framework là System.

Lợi điểm của Namespace là phân nhóm các lớp đối tượng, giúp người dùng dễ nhận biết và sử dụng. Ngoài ra, Namespace tránh việc các lớp đối tượng có tên trùng với nhau không sử dụng được. .NET Framework cho phép chúng ta tạo ra các lớp đối tượng và các Namespace của riêng mình. Với hơn

Page 17: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 17/187

5000 tên có sẵn, việc đặt trùng tên lớp của mình với một lớp đối tượng đã có là điều khó tránh khỏi. Namespace cho phép việc này xảy ra bằng cách sử dụng một tên đầy đủ để nói đến một lớp đối tượng. Ví dụ, nếu muốn dùng lớp WebControls, chúng ta có thể dùng tên tắt của nó là WebControls hay tên đầy đủ là System.Web.UI.WebControls.

Hệ thống không gian tên (Namespace)

Đặc điểm của bộ thư viện các đối tượng .NET Framework là sự trải rộng để hỗ trợ tất cả các ngôn ngữ lập trình .NET như chúng ta thấy ở hình vẽ trên. Điều này sẽ giúp những người mới bắt đầu ít bận tâm hơn trong việc lựa chọn ngôn ngữ lập trình cho mình vì tất cả các ngôn ngữ đều mạnh ngang nhau. Cũng bằng cách sử dụng các lớp đối tượng để xây dựng ứng dụng, .NET Framework buộc người lập trình phải sử dụng kỹ thuật lập trình hướng đối tượng (sẽ được nói tới trong các chương sau).

III. Ứng dụng đầu tiên

III.1. Môi trường lập trình VS .NET Chúng ta sẽ bắt đầu bằng việc làm quen với môi trường phát triển ứng dụng (IDE) của Visual Studio.NET. VS.NET có nhiều thay đổi so với VS 98.

Hình dưới là màn hình khởi đầu của VS.NET 2003. Vùng làm việc chính giữa đang hiển thị trang "Start page" với 3 mục chính: Projects, Online Resource và My Profile.

My Profile ghi nhớ thông tin về người sử dụng VS.NET. Các thông tin chủ yếu liên quan đến cách chúng ta sẽ sử dụng VS.NET như thế nào. Chẳng hạn như cách hiển thị các cửa sổ, các phím tắt, cách VS.NET hiển thị màn hình giúp đỡ,…

Online Resource cần một kết nối với Internet để download các thông tin từ website của Microsoft về máy tính của chúng ta.

Projects liệt kê các project mà chúng ta đã làm việc trong thời gian gần đây. Trên mục này, chúng ta cũng có thể tạo mới một project bằng cách nhấn vào nút New Project.

Các cửa sổ phụ nhìn thấy trên màn hình gồm có:

SSyysstteemm

SSyysstteemm..DDaattaa SSyysstteemm..XXmmll

SSyysstteemm..WWeebb

GGlloobbaalliizzaattiioonn DDiiaaggnnoossttiiccss CCoonnffiigguurraattiioonn CCoolllleeccttiioonnss

RReessoouurrcceess RReefflleeccttiioonn NNeett IIOO

TThhrreeaaddiinngg TTeexxtt SSeerrvviicceePPrroocceessSSeeccuurriittyy

CCoommmmoonn OOlleeDDbb

SSQQLLTTyyppeess SSqqllCClliieenntt

XXPPaatthh XXSSLLTT

RRuunnttiimmee IInntteerrooppSSeerrvviicceess

RReemmoottiinngg

SSeerriiaalliizzaattiioonn

SSeerriiaalliizzaattiioonn

CCoonnffiigguurraattiioonn SSeessssiioonnSSttaattee CCaacchhiinngg SSeeccuurriittyy

SSeerrvviicceess DDeessccrriippttiioonn

DDiissccoovveerryy

PPrroottooccoollss

UUII HHttmmllCCoonnttrroollss

WWeebbCCoonnttrroollss

SSyysstteemm..DDrraawwiinngg

IImmaaggiinngg DDrraawwiinngg22DD

TTeexxtt PPrriinnttiinngg

SSyysstteemm..WWiinnddoowwss..FFoorrmmss

DDeessiiggnn

Page 18: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 18/187

Màn hình khởi đầu của VS.NET 2003 với Tab My Profile hiện hành

Solution Explorer quản lý một hay nhiều project được nhóm với nhau để tạo thành một solution (giải pháp hay một hệ thống ứng dụng hoàn chỉnh). Nếu chuyển qua tab Class (Clas…), cửa sổ này liệt kê các lớp đối tượng trong ứng dụng đang làm việc. Tab Content (Cont…) sẽ hiện thị mục lục của phần giúp đỡ của VS.NET.

Dynamic help là cửa sổ giúp đỡ thông minh mới có trong VS.NET. Trong khi lập trình, chúng ta chỉ cần đưa chuột tới một từ khoá như Class, For,… Dynamic help sẽ tự động tìm ra những mục giúp đỡ liên quan đế từ khoá đó. Nếu chúng ta đang mở một project, phần cửa sổ dành cho Dynamic help còn dùng để hiển thị cửa số Property giống như của VB 6.

Toolbox liệt kê các control dành cho việc thiết kế giao diện. Một tiện lợi của VS.NET cho các màn hình độ phân giải thấp là chúng ta có thể thu gọn các cửa sổ kiểu như Solution Explorer và Dynamic help thành tab nằm dọc theo màn hình như cửa sổ Toolbox chúng ta thấy trong hình. Nếu có nhiều tab, biểu tượng của tab đó sẽ được hiển thị. Trong hình vẽ một tab khác có tên là Server Explorer được hiển thị với biểu tượng 2 chiếc máy tính phía trên tab Toolbox.

III.2. Tạo mới một project Có 2 cách tạo mới một project: chọn menu File | New | Project hay nhấn nút New Project trên tab Projects của trang khởi động. Hình dưới minh họa cửa sổ New Project hiện ra khi bạn chọn chức năng tạo mới.

Mục Project Type liệt kê tất cả các loại project có thể tạo bằng VS.NET. Máy tính của chúng tôi chỉ cài một ngôn ngữ VB.NET thay vì 4 ngôn ngữ là VB.NET, C#, C++ và J# nên hình dưới chỉ cho thấy loại Visual Basic Project mà không thấy có C# project hay C++ project…

Chỉ riêng với loại VB.Net project, chúng ta đã thấy mục Templates liệt kê rất nhiều kiểu ứng dụng khác nhau. Một template là một mẫu ứng dụng cụ thể mà VS.NET sẽ phát sinh trước một số đoạn lệnh nhất

Page 19: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 19/187

định. Ví dụ, loại template Windows Application sẽ được VS.NET tạo sẵn một form và phát sinh lệnh cần thiết để chúng ta có thể chạy ứng dụng ngay sau khi vừa tạo mới!

Hãy bắt đầu bằng ứng dụng phổ biến nhất : Windows Application.

Đặt lại tên cho project trong phần Name là “Hello” và định lại đường dẫn cho thư mục lưu trữ ứng dụng trong phần Location (tuỳ ý và nếu cần thiết). Cuối cùng, nhấn OK để VS.NET phát sinh project mới

Cửa sổ tạo một project

III.3. Ứng dụng Hello

Môi trường phát triển ứng dụng VS.Net

Page 20: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 20/187

Trong ứng dụng này, chúng ta sẽ thực hiện các chức năng sau:

Thiết kế giao diện để làm quen với control mới và thuộc tính mới của các control

Thiết kế hệ thống thực đơn (menu)

Tìm hiểu cấu trúc của một ứng dụng Windows Application về mặt mã lệnh

Viết lệnh và làm quen với giao diện mới của cửa sổ code editor

Biên dịch, chạy thử ứng dụng

Tìm hiểu danh sách các file của project

Trước hết, nhấn đúp trên form để xem cửa sổ code editor với các đoạn lệnh của form Form1.

Cửa sổ viết lệnh của Form (Code editor)

Chúng ta sẽ thấy các dòng lệnh nằm trong một mục được khai báo là Class Form1. Class là một lớp đối tượng và điều này cho thấy ngay bản chất lập trình hướng đối tượng (HĐT) của .NET. Tiếp theo dòng khai báo là đoạn lệnh:

Ví dụ:

Inherits System.Windows.Forms.Form

Inherits có nghĩa là "kế thừa". Trong lập trình HĐT, điều này có nghĩa là Class được khai báo có đặc điểm giống hoàn toàn với class mà nó thừa kế. Ở đây, class mà Form1 thừa kế là System.Windows.Forms.Form. Như vậy, Form1 sẽ có đặc điểm chung giống với bất kỳ form nào trong các ứng dụng Windows: Một vùng hình chữ nhật, có thanh tiêu đề, các hộp Maximize, Minimize, X; có thể thay đổi kích thước,…

Tạm bỏ qua phần Windows Form designer generated code để xem phần thủ tục Form1_Load:

Ví dụ: Thủ tục Form1_Load

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As _

System.EventArgs) Handles MyBase.Load

End Sub

Như đã từng quen với VB 6, chúng ta biết rằng đây chính là thủ tục bẫy sự kiện Load của form xảy ra khi chương trình vừa được thi hành. Hãy chú ý đoạn Handles MyBase.Load ở cuối phần khai báo. Với mỗi thủ tục xử lý sự kiện, giờ đây, VB.NET dùng từ khoá Handles để mô tả sự kiện sẽ xử lý. Viết đoạn lệnh sau đây để hiển thị một hộp thông báo trong thủ tục Form1_Load:

MsgBox("Form load!!!")

Nhấn F5 để chạy thử chương trình, một hộp thông báo hiển thị câu "Form load!!!" trước khi form được hiện ra. Bây giờ, chúng ta hãy bỏ phần Handles MyBase.Load và chạy lại : hộp thông báo không còn hiện ra được nữa – nghĩa là không có dòng lệnh nào cho xử lý sự kiện Load của form.

Page 21: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 21/187

III.4. Windows Form Designer Trên VB 6, các chi tiết thiết kế giao diện trên một form sẽ được dấu đi trong cửa sổ lệnh mặc dù vẫn được ghi vào tập tin .frm. Trên VB.NET, mọi chi tiết thiết kế giao diện đều sử dụng lệnh. Windows Form Designer cho phép chúng ta thiết kế giao diện bình thường và sẽ tự phát sinh những đoạn lệnh này.

Hãy thiết kế form để có giao diện như sau:

Một chú ý nhỏ là Label control không còn sử dụng thuộc tính Caption nữa và cả đối tượng form cũng vậy. Các đối tượng control trên .NET đều thống nhất sử dụng thuộc tính Text để hiển thị chuỗi ký tự. Bây giờ, chúng ta hãy quay trở lại cửa sổ Code editor và nhấn chuột vào dấu + trong phần Windows Form Designer.

Chức năng mới của Code editor là thu hẹp các đoạn lệnh thành một dòng ghi chú để toàn bộ phần mã lệnh trở nên ngắn hơn. Để làm việc này, bạn sử dụng từ khoá #Region "ghi chú…" và #End Region.

Các đoạn lệnh nằm giữa #Region và #End Region sẽ được thu lại chỉ còn một dòng với nội dung là phần ghi chú và dấu + ở phía trước. Windows Form Designer đã sử dụng chức năng này để phát sinh đoạn lệnh thiết kế giao diện cho form.

Giao diện form cần thiết kế

Page 22: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 22/187

Chúng ta sẽ đi vào xem xét chi tiết đoạn lệnh được phát sinh trên đây để hiểu rõ thêm một vài điểm trong lập trình hướng đối tượng.

Trong lập trình HĐT, mỗi một đối tượng (object) đều phải có một lớp đối tượng (class) định nghĩa nó. Lớp đối tượng chỉ là một khái niệm chẳng hạn như Máy tính, còn đối tượng là một cái máy tính cụ thể chúng ta đang dùng. Một lớp được định nghĩa trong VB.NET bằng từ khoá Class như trong chương trình, chúng ta có một lớp là Form1. Từ đây, chúng ta dùng từ class thay cho cụm từ "lớp đối tượng" để ngắn gọn hơn.

Một class cần định nghĩa cách đối tượng của nó được tạo ra và huỷ đi. Điều này giống như việc Toyota tạo ra một model xe hơi mới có tên là VIOS sẽ định nghĩa quy trình sản xuất ra một chiếc VIOS cụ thể như thế nào. Thủ tục mô tả cách tạo ra một đối tượng của class phải đặt tên là New. Trong đoạn lệnh, bạn thấy class Form1 cũng có một thủ tục New. Thủ tục định nghĩa cách huỷ đi một đối tượng gọi là Dispose.

Sau khi các chiếc xe VIOS được đưa vào sử dụng, Toyota nhận được phản hồi từ khách hàng và quyết định đưa ra một phiên bản VIOS mới hơn là VIOS Pro. VIOS Pro chính là một model mới dựa trên model VIOS trước đó với một số chức năng cải tiến và vài thiết bị gắn thêm. Trong lập trình HĐT, ta gọi đây là sự kế thừa. Trở lại phần khai báo Class Form1, bạn sẽ thấy phần Inherits System.Windows.Forms.Form. Điều này có nghĩa là class Form1 kế thừa đặc điểm của class Form. Dĩ nhiên các kỹ sư của Toyota sẽ không bỏ thời gian định nghĩa lại cách tạo ra một chiếc VIOS Pro, thay vào đó họ sẽ mô tả rằng "một chiếc VIOS Pro được tạo ra giống như một chiếc VIOS cộng thêm một số thay đổi …" Lập trình HĐT cũng dùng cách này, chúng ta thấy trong Sub New() có đoạn lệnh MyBase.New(). Từ khoá MyBase dùng để nói đến lớp cha của Form1 tức Form. Như thế, Form1 sẽ được tạo ra giống như một Form bình thường cộng với một vài thay đổi. Những thay đổi này được liệt kê trong phần InitializeComponent().

Form1 là một Form bình thường mà chúng ta đã gắn thêm một label và một textbox. Thủ tục InitializeComponent() mô tả cách chúng ta gắn thêm label và textbox đó.

Ví dụ: Nội dung thủ tục InitializeComponent()

Friend WithEvents Label1 As System.Windows.Forms.Label

Friend WithEvents txtTen As System.Windows.Forms.TextBox

<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

Me.Label1 = New System.Windows.Forms.Label

Me.txtTen = New System.Windows.Forms.TextBox

Me.SuspendLayout()

'Label1

Me.Label1.AutoSize = True

Me.Label1.Location = New System.Drawing.Point(16, 32)

Me.Label1.Name = "Label1"

Me.Label1.Size = New System.Drawing.Size(67,16)

Me.Label1.TabIndex = 0

Me.Label1.Text = "Tên của bạn"

Page 23: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 23/187

'txtTen

Me.txtTen.Location = New System.Drawing.Point(88,24)

Me.txtTen.Name = "txtTen"

Me.txtTen.TabIndex = 1

Me.txtTen.Text = ""

'Form1

Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)

Me.ClientSize = New System.Drawing.Size(296,69)

Me.Controls.Add(Me.txtTen)

Me.Controls.Add(Me.Label1)

Me.Name = "Form1"

Me.Text = "Form1"

Me.ResumeLayout(False)

End Sub

Windows Form Designer khai báo hai biến Label1 và txtTen bằng từ khoá Friend (Các từ khoá Public, Private, Friend,… sẽ được chúng tôi trình bày trong chương 3.) Biến Label1 được khai báo là một đối tượng của class Label trong khi txtTen là đối tượng của class TextBox. Khai báo một đối tượng không có nghĩa là chúng ta đã có thể sử dụng đối tượng. Điều này giống như việc đặt hãng Toyota một chiếc VIOS và phải đợi họ giao hàng trước khi sử dụng. Trong lập trình HĐT, biến kiểu đối tượng sau khi khai báo cần được "tạo mới". Đây là lý do có hai dòng lệnh:

Me.Label1 = New System.Windows.Forms.Label

Me.txtTen = New System.Windows.Forms.TextBox

Từ khoá Me cũng như các đoạn lệnh còn lại không xa lạ với chúng ta. Ở đây, Designer đang khởi gán các thuộc tính cho Label1 và txtTen. Một chú ý nhỏ là để đặt vị trí của Label hay TextBox trên Form1, designer sử dụng một điểm để canh góc trên bên trái. Điểm cũng là một đối tượng của class Point và được tạo ra bằng lệnh New System.Drawing.Point(x,y).

Hai dòng lệnh Controls.Add(…) làm công việc "bắt vít" hai điều khiển của chúng ta vào Form1.

III.5. Thử nghiệm Chúng ta sẽ kiểm chứng lại những gì vừa phân tích ở trên bằng việc thêm một control mới vào Form1 nhưng dùng lệnh thay vì thiết kế bằng tay. Thêm dòng khai báo sau dưới mục khai báo txtTen:

Friend WithEvents LinkLbl As System.Windows.Forms.LinkLabel

Và tạo mới:

Me.LinkLbl = New System.Windows.Forms.LinkLabel

Trước mục ghi chú ‘Form1, thêm đoạn lệnh để đặt thuộc tính cho LinkLabel:

Ví dụ: Thủ tục Form1_Load

'LinkLbl

Me.LinkLbl.Location = New System.Drawing.Point(112, 48)

Page 24: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 24/187

Me.LinkLbl.Name = "LinkLbl"

Me.LinkLbl.Size = New System.Drawing.Size(64, 16)

Me.LinkLbl.TabIndex = 2

Me.LinkLbl.TabStop = True

Me.LinkLbl.Text = "Giúp đỡ"

Me.LinkLbl.TextAlign = System.Drawing.ContentAlignment.MiddleCenter

Cuối cùng, chúng ta cũng "bắt vít" LinkLabel vừa tạo vào Form1 bằng lệnh:

Me.Controls.Add(Me.LinkLbl)

Thêm các điều khiển vào form

Bây giờ, chuyển sang cửa sổ thiết kế giao diện để xem LinkLabel của chúng ta được đặt ở đâu. Tiếp tục thiết kế giao diện cho Form1 theo hình dưới đây:

Thực đơn của form

Menu của form là một điều khiển có tên là MainMenu. Khi được đưa vào form, điều khiển này sẽ nằm trong phần đáy màn hình như trên hình trên. Mục Type Here hiện ra tại vị trí của menu để chúng ta thiết kế các mục trong menu. Hãy xem hình để biết cấu trúc của menu cần thiết kế.

Thêm các đoạn lệnh xử lý sự kiện sau vào chương trình:

Ví dụ:

Private Sub cmdHello_Click(ByVal sender As System.Object, ByVal e As _

System.EventArgs) Handles cmdHello.Click

Dim ten As String

ten = txtTen.Text

MsgBox("Hello, " & ten)

End Sub

Private Sub mnuGioiThieu_Click(ByVal sender As System.Object, ByVal e _

Page 25: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 25/187

As System.EventArgs) Handles mnuGioiThieu.Click

MsgBox("Chương trình VB.NET đầu tiên.")

End Sub

Private Sub mnuThoat_Click(ByVal sender As System.Object, ByVal e As _

System.EventArgs) Handles mnuThoat.Click

Me.Close()

End Sub

Private Sub LinkLbl_LinkClicked(ByVal sender As System.Object, ByVal e _

As System.Windows.Forms.LinkLabelLinkClickedEventArgs) Handles _

LinkLbl.LinkClicked

Dim P As System.Diagnostics.Process

P.Start("http://ncmlt.hcmuns.edu.vn")

End Sub

Private Sub mnuGiupDo_Click(ByVal sender As System.Object, ByVal e As _

System.EventArgs) Handles mnuGiupDo.Click

Dim P As System.Diagnostics.Process

P.Start("http://ncmlt.hcmuns.edu.vn")

End Sub

Bây giờ, chúng ta có thể biên dịch và chạy thử chương trình bằng cách nhấn phím F5. Các chức năng khá đơn giản, ngoài việc chúng ta đã dùng một điều khiển LinkLabel mới có trong .NET để mở website http://ncmlt.hcmuns.edu.vn trong Internet Explorer. Trong đoạn lệnh dành cho chức năng này, chúng ta dùng một đối tượng P của class Process. Đây là một đối tượng "hệ thống" chưa từng có trong VB 6. Đối tượng này có thể khởi động hay tắt các ứng dụng có trên máy một cách đơn giản như chúng ta được thấy.

III.6. Kỹ thuật lập trình hướng đối tượng Chúng ta sẽ tìm hiểu thêm về cấu trúc của chương trình Hello để nắm vững cách VS.NET tổ chức một project và hiểu thêm về kỹ thuật lập trình HĐT. Hãy xem hình cửa ổ Solution Explorer bên dưới. Chúng ta đang ở tab Solution (Soluti…) và VS.NET trình bày cấu trúc của project dạng cây:

Page 26: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 26/187

Cửa sổ Solution Explorer hiển thị các tham chiếu

Form1.vb là đối tượng đại diện cho Form1 trong chương trình. Đây cũng là một file cùng tên lưu trong thư mục của project Hello.

Reference là một mục liệt kê tất cả các lớp thư viện mà chương trình của chúng ta đang "tham khảo". Mỗi mục trong Reference là một namespace hay một thư viện nhiều class. Trong chương trình, chúng ta chỉ có quyền khai báo biến đối tượng là một đối tượng của các class có trong namespace đã liệt kê trong phần References.

Cửa sổ Class View

Có một số namespace chúng ta không sử dụng tới nhưng mặc định được VS.Net tham khảo tới khi tạo project mới. Đó là System.XML. Mặc dù đây là namespace rất cơ bản nhưng vì không dùng tới trong Hello, chúng ta có thể bỏ đi. Nhắp chuột phải trên namespace và chọn mục Remove để xoá. Bây giờ có thể nhấn F5 và chương trình vẫn chạy bình thường!

Page 27: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 27/187

Kỹ thuật lập trình HĐT bao gồm hai điểm quan trọng: Xây dựng các lớp đối tượng (Component) và sử dụng lại những đối tượng có sẵn. Một ứng dụng đơn giản có thể chỉ cần ghép nối những đối tượng có sẵn mà thành như trong ứng dụng Hello. Reference chính là nơi khai báo những thành phần cần thiết để ghép nối thành một ứng dụng và chúng ta không cần phải khai báo những thành phần thừa như System.XML.

Với những ứng dụng phức tạp hơn, chúng ta sẽ cần tự mình tạo ra những đối tượng mới. Trong ví dụ này, chúng ta sẽ tạo ra lớp đối tượng có tên là SayHi để nói lời chào tuỳ theo buổi sáng, trưa hay tối. Trước hết, hãy chuyển qua tab Class trên cửa sổ Solution Explorer để xem cấu trúc của class Form1 (hình trên)

III.7. Xây dựng lớp đối tượng Bây giờ, chúng ta sẽ bắt tay vào xây dựng lớp đối tượng đầu tiên: SayHi.

Chọn menu Projects | Add Class… Cửa sổ Add new item sẽ hiện ra với đối tượng được thêm mới vào là một Class. Bạn gõ vào phần Name chuỗi SayHi.vb và VS.NET sẽ tạo ra một class có tên là SayHi.

Nội dung của SayHi hiện giờ chỉ là một khung khai báo lớp đối tượng:

Class vừa tạo xuất hiện trên Solution Explorer

Nếu bạn xem trên cửa sổ Solution Explorer thì lúc này sẽ thấy có hai class như hình trên bên trái. Bạn hãy viết đoạn lệnh sau cho class SayHi:

Ví dụ:

Public Class SayHi

Dim mTen As String

Sub New(ByVal Ten As String)

mTen = Ten

End Sub

Property Ten() As String

Get

Return mTen

End Get

Set(ByVal Value As String)

mTen = Value

End Set

End Property

Function Say() As String

Dim gio = Date.Now.Hour

Page 28: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 28/187

If gio >= 5 And gio <= 12 Then

Say = "Good morning, " + mTen

ElseIf gio <= 18 Then

Say = "Good afternoon, " + mTen

Else

Say = "Good evening, " + mTen

End If

End Function

End Class

Tạm thời không cần quan tâm nhiều đến cú pháp vì chúng ta sẽ tìm hiểu trong phần lập trình hướng đối tượng. Sau khi đã viết đoạn lệnh, xem trong cửa sổ Class viewer bạn sẽ thấy các thành phần của class SayHi được liệt kê bao gồm một thuộc tính có tên là Ten, hai phương thức là New và Say cùng với một biến cục bộ là mTen. Thuộc tính của một class cho biết đặc điểm mà một đối tượng của nó sẽ có. Phương thức của một class cho biết khả năng mà đối tượng của nó có thể thực hiện.

Cửa sổ Class viewer có thêm class SayHi và các thành phần của nó

Chúng ta sẽ sửa lại đoạn lệnh trong nút cmdHello để xem cách dùng một đối tượng:

Ví dụ:

Private Sub cmdHello_Click(ByVal sender As System.Object, ByVal e As _

System.EventArgs) Handles cmdHello.Click

Dim sh As SayHi, LoiChao As String

sh = New SayHi(txtTen.Text)

LoiChao = sh.Say

MsgBox(LoiChao)

End Sub

Chúng ta thấy, sử dụng class SayHi cũng giống như sử dụng class TextBox hay Label trong phần InitializeComponent.

III.8. Sử dụng lại thành phần có sẵn Chúng ta đã vừa tạo ra một COMponent – class SayHi. Một khi đã được tạo ra, component có thể được sử dụng lại ở bất kỳ đâu. Chúng ta sẽ đóng gói SayHi thành một file.DLL để sử dụng trong một project khác.

Chọn menu File | Add project | New Project … Trong cửa sổ hiện ra, gõ tên của project là SayHi và chọn nút OK. Một project mới được đưa vào Solution cùng với một class có sẵn là Class1.

Vì chúng ta dùng project này để đóng gói class SayHi đã tạo trước đó nên hãy xoá bỏ Class1.vb bằng

Page 29: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 29/187

cách nhắp chuột phải và chọn mục Delete. Sau đó, đưa SayHi.vb vào project bằng cách nhắp chuột phải trên project SayHi và chọn mục Add | Add existing item… Tìm SayHi.vb trong thư mục Hello của project Hello và chọn Open.

Project SayHi được đưa vào Solution Explorer

Trước khi thực hiện bước đóng gói, kiểm tra lại thuộc tính của project SayHi bằng cách chọn menu Project | Properties …

Cửa sổ Project Property Pages

Trong cửa sổ hiện ra, chúng ta sẽ thấy một số thông tin: Assembly name: SayHi, loại kết xuất (output type): Class library. Root namespace: SayHi. Phần Information ở dưới ghi tên file kết xuất là SayHi.dll. Đóng cửa sổ lại và biên dịch project này bằng cách chọn menu Build | Build SayHi.

Lúc này, chúng ta đã có file SayHi.dll và sẵn sàng sử dụng nó trong các ứng dụng khác. Hình dưới hiển thị một phần cửa sổ Windows Explorer để xác định vị trí của file SayHi.dll

Kết quả biên dịch được lưu giữ trong thư mục Bin của ứng dụng

Tiếp theo đây, chúng ta sẽ xây dựng một ứng dụng console (giao diện dòng lệnh như của DOS) để sử dụng class SayHi đã tạo ra. Chọn mục File | Close Solution để đóng solution hiện có.

Page 30: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 30/187

Tạo ứng dụng console

Chọn File | New project với template là Console Application. Gõ tên của project là HelloConsole và click vào OK để tạo mới. Một project rất đơn giản được tạo ra với một file là Module1.vb. File này có nội dung như sau:

Ví dụ:

Module Module1

Sub Main()

End Sub

End Module

Nếu lúc này chạy thử chương trình, một cửa sổ DOS sẽ nháy lên rồi biến mất. Ứng dụng chỉ chạy trong "nháy mắt"! Chúng ta hãy thêm dòng lệnh sau trước khi nhấn lại phím F5

System.Console.ReadLine()

Khi chương trình chạy, chúng ta thấy một cửa sổ "đen ngòm" của DOS hiện ra với cursor nhấp nháy tại góc trên bên trái. Dấu nhắc này có nghĩa ứng dụng đang chờ chúng ta nhấn phím Enter để kết thúc. Bây giờ, hãy thực hiện bước "ghép nối" các thành phần có sẵn trong đó, thành phần ghép nối chính là SayHi. Trong cửa sổ Solution Explorer, nhắp chuột phải trên mục Reference và chọn mục Add reference. Chọn nút Browse và tìm file SayHi.dll. Sau khi chọn Open, chúng ta sẽ thấy mục Selected Components liệt kê file SayHi.dll. Chọn nút OK để tham chiếu.

Page 31: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 31/187

Chọn tham chiếu cho ứng dụng

Lúc này, trong mục Reference liệt kê namepace SayHi:

Reference sau khi tham chiếu tập tin SayHi.dll

Cuối cùng, chúng ta "bắt vít" cho SayHi vào ứng dụng của mình:

Ví dụ:

Sub Main()

Dim sh As SayHi.SayHi

sh = New SayHi.SayHi("Nguyen Thai Hung")

System.Console.WriteLine(sh.Say)

System.Console.ReadLine()

End Sub

Khi chạy chương trình, bạn sẽ thấy cửa sổ hiện ra như bên dưới:

Cửa sổ chạy của ứng dụng console

Page 32: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 32/187

III.9. Assembly - một loại DLL mới DLL (Dynamic Link Library) là một loại file thực thi trên hệ điều hành Windows dùng để chứa các thư viện lớp đối tượng hay nói chung hơn là các Component. Một component có thể gồm 1 hay nhiều DLL. Trong ví dụ của chúng ta, SayHi chỉ có một file DLL là SayHi.dll mà thôi.

Bằng cách tạo các component và đóng gói chúng thành các DLL, lập trình viên có thể tạo ra các thành phần có sẵn và sử dụng lại chúng ở nhiều project khác nhau. Đơn cử một thành phần sử dụng lại "không ai không biết" của Windows là comdlg32.dll. Đây chính là thư viện các hộp thoại dùng chung như Open, Save, Print, Color,…

Viễn cảnh lập trình "lắp ráp" các thành phần khá tươi đẹp này có thể sẽ biến các lập trình viên thành các "tay ghiền" đồ chơi của Lego. Tuy nhiên sử dụng những "đồ chơi" này chẳng dễ như chúng ta tưởng. Vấn để bắt đầu ở chỗ một DLL do ai đó viết ra (chẳng hạn chính Microsoft) được nhiều phần mềm sử dụng. Hai phần mềm A, B cài lên máy tính của chúng ta đều sử dụng DLL tên là X. Một ngày nọ, chúng ta không dùng A nữa và gỡ bỏ (Uninstall) nó khỏi máy. Đương nhiên khi gỡ bỏ A, phần mềm sẽ hỏi chúng ta có muốn xoá X khỏi hệ thống hay không. Thế nhưng khổ nỗi chúng ta không biết X dùng để làm gì và có phần mềm nào khác dùng X nữa hay không. Và nếu như gỡ bỏ X, ứng dụng B cũng hết sử dụng được.

Bây giờ giả sử rằng dung lượng ổ cứng rất nhiều và chúng ta không gỡ bỏ các DLL khỏi máy tính làm gì. Nay chúng ta lại muốn cài đặt thêm một ứng dụng C khác nữa vào máy. C là một phần mềm mới và nó lại sử dụng một phiên bản X mới hơn vừa cập nhật. Khi cài đặt vào máy, X mới được thay thế cho X cũ và thế là cả A và B đều chằng hiểu gì về thành phần X mới này nên không chạy được nữa.

Câu chuyện trên không phải hiếm hoi, các lập trình viên gọi nó là “DLL Hell” hay “địa ngục DLL”. Khi muốn bán phần mềm cho chúng ta, chính họ phải lo giải quyết vấn đề này, không chỉ với riêng những DLL do họ viết ra và nâng cấp mới mà có khi cả những DLL của người khác nữa.

Với kỹ thuật .NET, giờ đây Microsoft đưa ra một định nghĩa mới cho DLL và cũng thay tên đổi họ cho nó thành Assembly – thành phần lắp ráp. DLL cũ không có khả năng tự mô tả nó với hệ điều hành. Điều này dẫn đến việc mỗi phần mềm đều phải cài đặt (install hay setup) vào hệ điều hành. Trong quá trình này, hầu hết các DLL sẽ được copy vào thư mục của Windows nên dẫn đến việc cái này ghi đè lên cái kia hay Windows có đủ thứ DLL trong đó. Chưa hết, các class trong DLL sẽ phải đăng ký mã số của mình (ClassID) vào một mục để Windows quản lý gọi là Registry. Nếu trong registry bị mất một ClassID nào đó thì Windows cũng đành chịu thua, không thể quản lý và thi hành class tương ứng được nữa.

Các Assembly xây dựng bởi .NET cũng có phần mở rộng của tập tin là .dll nhưng có khả năng tự mô tả chính bản thân mình thông qua một thành phần chứa ngay trong tập tin .dll là Metadata. Bao lâu còn tập tin .dll trên máy, Windows còn có khả năng đọc Metadata và thi hành các đoạn lệnh trong assembly.

Cũng với khả năng tự mô tả chính mình, các assembly không cần phải đăng ký vào hệ thống. Điều này nghĩa là chúng không cần phải được cài đặt bằng cách setup hay install và lưu trong thư mục Windows. Thay vào đó, mỗi ứng dụng tự quản lý thư mục của riêng mình và lưu tập tin assembly trong đó. Việc cài đặt ứng dụng lúc này chẳng qua là lệnh copy thư mục của DOS và nếu bạn muốn xoá ứng dụng chỉ cần xoá thư mục của nó mà thôi.

Vì mỗi ứng dụng nằm riêng một chỗ, tự quản lý các assembly của mình nên DLL hell khó lòng xảy ra được nữa.

Assembly được chia làm hai loại:

Page 33: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 33/187

Private assembly là những assembly như mô tả ở trên nghĩa là của ứng dụng nào thì chỉ ứng dụng đó dùng được.

Public assembly là những assembly đem dùng chung cho nhiều ứng dụng.

Hãy xét tới trường hợp một công ty phần mềm không phải chỉ có một ứng dụng nhưng một họ các ứng dụng cung cấp cho người dùng. Nhiều ứng dụng trong đó đều sử dụng chung một assembly. Công ty có thể chọn hai giải pháp: dùng private assembly để mỗi ứng dụng quản lý assembly của riêng mình hoặc, dùng public assembly để nhiều ứng dụng chỉ dùng chung một assembly mà thôi. Cách thứ hai sẽ tiện lợi hơn cho người dùng mỗi khi họ muốn nâng cấp lên phiên bản mới của công ty.

Các assembly dùng chung được quản lý bởi Global Assembly Cache (GAC). Đây là thư mục nằm trong thư mục Windows\Assembly\GAC. GAC quản lý các assembly này thông qua tên gọi riêng là Strong name. Strong name được phát sinh thông qua công cụ sn.exe của .NET Framework.

Page 34: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 34/187

Bài 2

NGÔN NGỮ VISUAL BASIC .NET

Tóm tắt Lý thuyết 3 tiết - Thực hành 5 tiết

Mục tiêu Các mục chính Bài tập

Đưa ra những điểm mới và những điểm thay đổi (so với VB) trong Visual Basic .Net

1. Các kiểu dữ liệu và đặc điểm

2. Biến – Tính chất, khai báo và khởi tạo

3. Mảng, Structure

4. Các toán tử

5. Cấu trúc điều khiển

6. Xử lý lỗi

7. Những thay đổi trong VB.NET

1.1, 1.2, 1.3

Page 35: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 35/187

I. Các kiểu dữ liệu và đặc điểm

I.1. Các kiểu dữ liệu Các kiểu dữ liệu của .Net được mô tả chi tiết trong một cấu trúc gọi là Common Type System (CTS). CTS định nghĩa các kiểu dữ liệu, cách thức sử dụng, cách thức được quản lý lúc thực thi và cùng với Common Language Specification đóng một vai trò quan trọng trong việc trao đổi giữa các ngôn ngữ lập trình trong .Net.

Common Type System có chức năng:

Thiết lập một nền tảng cho phép tương tác giữa các ngôn ngữ lập trình, bảo toàn giá trị của dữ liệu khi có sự trao đổi dữ liệu giữa các ngôn ngữ và bảo đảm việc thực hiện câu lệnh được tối ưu

Cung cấp một mô hình hướng đối tượng cho các ngôn ngữ lập trình.

Đưa ra những quy tắc để các ngôn ngữ lập trình phải tuân thủ nhằm bảo đảm các thành phần viết trên các ngôn ngữ khác nhau có thể tương tác với nhau.

Các kiểu dữ liệu trong VB.NET đã có một số biến đổi cho phù hợp với các quy tắc của CTS. Dưới đây là hệ thống các kiểu dữ liệu chính tương ứng trong Common Language Runtime:

System.Object System.Array System.String System.ValueType System.Boolean System.Byte System.DateTime System.Decimal System.Char System.Double System.Int16 System.Int32 System.Int64 System.Single System.UInt16 System.UInt32 System.UInt64

Các kiểu dữ liệu nội tại của VB.NET

Kiểu VB.Net Kiểu CLR System.x

Vùng nhớ (Byte)

Type Code

Miền giá trị

Boolean Boolean 2 3 True hoặc False.

Byte Byte 1 6 0 đến 255 (không dấu).

Char Char 2 4 0 đến 65535 (không dấu).

DateTime DateTime 8 16 0:00:00 ngày 01 tháng Giêng 0001 đến 23:59:59 ngày 31 tháng Mười Hai 9999.

Decimal Decimal 16 15 0 đến +/-79,228,162,514,264, 337,593,543,950,335 nếu không có số lẻ;0 đến +/-7.9228162514264337 593543950335 với 28 số lẻ; số nhỏ nhất

Page 36: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 36/187

khác không là +/- 0.0000000000000000000000000001 (+/-1E-28).

Double

Double 8 14 -1.79769313486231570E+308 đến -4.94065645841246544E -324 đối với số âm; 4.94065645841246544E-324 đến 1.79769313486231570E +308 với số dương.

Integer Int32 4 9 -2,147,483,648 đến 2,147,483,647.

Long

Int64 8 11 -9,223,372,036,854,775,808 đến 9,223,372,036,854,775,807.

Object Object (Class)

4 Bất kỳ kiểu dữ liệu nào có thể chứa trong biến kiểu Object.

Short Int16 2 7 -32,768 đến 32,767.

Single

Single 4 13 -3.4028235E+38 đến -1.401298E-45 với số âm; 1.401298E-45 đến 3.4028235E+38 với số dương.

String String (Class)

8 0 đến khoảng 2 tỷ ký tự Unicode

User-Defined Type

(kế thừa từ ValueType)

Mỗi thành phần của Structure có miền giá trị theo kiểu dữ liệu của thành phần.

Khi khai báo một kiểu dữ liệu cơ bản, không hẳn biến sẽ sử dụng vùng nhớ như yêu cầu lưu trữ. Ví dụ, mảng cần thêm vùng nhớ cho chính bản thân mảng cũng như cho mỗi chiều (dimension). Mỗi biến Object tham chiếu đến một thành phần hoặc một kiểu hỗn hợp sử dụng 4 byte vùng nhớ ngoài số vùng nhớ cần dùng cho kiểu dữ liệu chứa trong nó.

I.2. Đặc điểm của các kiểu dữ liệu Các kiểu dữ liệu mặc nhiên phát sinh từ lớp SysTem.Object.

Ngoài các phương thức kế thừa từ lớp SysTem.Oject, các biến kiểu dữ liệu còn có các phương thức và thuộc tính đặc thù.

Các phương thức chung kế thừa từ SysTem.Object

Equals: Hổ trợ việc so sánh giữa hai object.

Finalize: Thực hiện các thao tác xóa bỏ trước khi object được tự động xóa bỏ.

GetHashCode: Phát sinh một số tương ứng với giá trị của object.

GetType: Trả về kiểu của object.

ToString: Tạo ra chuỗi chứa nội dung mô tả một thể hiện của lớp.

Dưới đây là các bảng liệt kê những phương thức và thuộc tính đặc thù của các kiểu dữ liệu. Do các phương thức có nhiều cách sử dụng khác nhau, nên trong các phần nói về phương thức chỉ mô tả công dụng. Cần tham khảo thêm trong MSDN để hiểu rõ cách dùng.

Page 37: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 37/187

I.2.1. Kiểu String

Thuộc tính

Tên Mô tả

Chars(i) Trả về ký tự tại vị trí chỉ ra trong biến. Thuộc tính có tính chỉ đọc

Length Trả về số ký tự trong biến.

Phương thức

Tên Mô tả

Clone Trả về một tham chiếu của biến.

Compare Phương thức so sánh hai tham số kiểu String dựa vào thứ tự các ký tự theo ngôn ngữ qui định trong Regional Settings của từng ký tự và trả về:

-1 khi chuỗi thứ 1 nhỏ hơn chuỗi thứ 2

0 khi chuỗi thứ 1 bằng chuỗi thứ 1

1 khi chuỗi thứ 1 lớn hơn chuỗi thứ 2

Ngoài ra có thể có tham số qui định có phân biệt chữ Hoa chữ thường, v.v…

CompareOrdinal So sánh hai tham số kiểu String dựa theo bảng mã các ký tự của các tham số. Hàm trả về hiệu của mã tham số thứ nhất và mã tham số thứ hai.

Concat Nối các tham số lại với nhau và trả về chuỗi nối.

Copy Tạo một thể hiện mới kiểu String có giá trị như tham số chuỗi truyền vào.

CopyTo Sao chép một số ký tự chỉ ra từ một vị trí trên biến vào một vị trí chỉ ra trên mảng ký tự với số lượng ký tự truyền vào.

EndsWith Trả về True/False cho biết các ký tự cuối của biến có khớp với chuỗi chỉ ra không.

Format Thay thế phần biểu thức định dạng trong chuỗi bằng các các giá trị tương ứng đã được định dạng theo biểu thức.

IndexOf Trả về vị trí đầu tiên tìm thấy chuỗi hoặc ký tự truyền vào trên biến, ; có thể sử dụng thêm vị trí bắt đầu tìm, trả về vị trí lần tìm thấy thứ mấy.

IndexOfAny Trả về vị trí tìm thấy đầu tiên trên biến bất kỳ ký tự nào trong mảng ký tự truyền vào; có thể sử dụng thêm vị trí bắt đầu tìm, trả về vị trí lần tìm thấy thứ mấy.

Insert Chèn vào một giá trị String truyền vào tại vị trí chỉ định trên biến.

Join Nối các phần tử của mảng String truyền vào thành một chuỗi duy nhất với dấu nối là chuỗi dấu ngăn cách chỉ ra (separator)

LastIndexOf Trả về vị trí tìm thấy cuối cùng trên biến, chuỗi hoặc ký tự truyền vào; có thể sử dụng thêm vị trí bắt đầu tìm, trả về vị trí lần tìm thấy thứ mấy.

LastIndexOfAny Trả về vị trí tìm thấy cuối cùng trên biến bất kỳ ký tự nào trong mảng ký tự truyền vào; có thể sử dụng thêm vị trí bắt đầu tìm, trả về vị trí lần tìm thấy thứ mấy.

PadLeft Nối thêm bên trái ký tự truyền vào với số lần sao cho độ dài tổng cộng bằng độ dài chỉ ra. Nếu độ dài tổng cộng chỉ ra nhỏ hơn độ dài của biến, không ký tự nào được thêm vào.

PadRight Nối thêm bên phải ký tự truyền vào với số lần sao cho độ dài tổng cộng bằng độ dài chỉ ra. Nếu độ dài tổng cộng chỉ ra nhỏ hơn độ dài của biến, không ký tự nào được thêm vào.

Remove Xóa bỏ một số ký tự chỉ ra khỏi biến từ vị trí truyền vào.

Page 38: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 38/187

Replace Thay thế tất cả ký tự hay chuỗi tìm thấy trên biến bằng ký tự hay chuỗi truyền vào.

Split Trả về một mảng String với các phần tử chứa các chuỗi con được ngắt ra từ biến tùy theo ký tự ngăn cách truyền vào.

StartsWith Cho biết trị bắt đầu của biến có khớp với chuỗi truyền vào.

Substring Trả về một chuỗi con từ biến.

ToLower Trả về bản sao của biến với các ký tự in thường.

ToUpper Trả về bản sao của biến với các ký tự in HOA.

Trim Trả về biến đã loại bỏ tất cả các ký tự từ đầu đến cuối của biến khớp với mảng ký tự truyền vào.

TrimEnd Trả về biến đã loại bỏ tất cả các ký tự từ vị trí cuối của biến khớp với mảng ký tự truyền vào.

TrimStart Trả về biến đã loại bỏ tất cả các ký tự từ vị trí đầu của biến khớp với mảng ký tự truyền vào.

I.2.2. Kiểu DateTime

Field

Tên Mô tả

MaxValue Hiển thị giá trị lớn nhất của kiểu DateTime (chỉ đọc).

MinValue Hiển thị giá trị nhỏ nhất của kiểu DateTime (chỉ đọc).

Thuộc tính

Tên Mô tả

Date Trả về giá trị ngày tháng năm của biến.

Day Trả về giá trị ngày trong tháng của biến.

DayOfWeek Trả về giá trị ngày trong tuần của biến, với ngày đầu tiên là Chủ nhật có giá trị là 0.

DayOfYear Trả về giá trị ngày trong năm của biến.

Hour Trả về giá trị giờ của biến.

Millisecond Trả về giá trị phần ngàn giây của biến.

Minute Trả về giá trị phút của biến.

Month Trả về tháng của biến.

Now Trả về giá trị ngày giờ hiện hành của hệ thống.

Second Trả về giá trị giây của biến.

TimeOfDay Trả về giá trị giờ phút giây của biến.

Today Trả về ngày hiện hành.

Year Trả về năm của biến.

Page 39: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 39/187

Phương thức

Tên Mô tả

AddDays Thêm số ngày truyền vào cho giá trị của biến.

AddHours Thêm số giờ truyền vào cho giá trị của biến.

AddMilliseconds Thêm số phần ngàn giây truyền vào cho giá trị của biến.

AddMinutes Thêm số phút truyền vào cho giá trị của biến.

AddMonths Thêm số tháng truyền vào cho giá trị của biến.

AddSeconds Thêm số giây truyền vào cho giá trị của biến.

AddYears Thêm số năm truyền vào cho giá trị của biến.

Compare So sánh hai biến ngày giờ và cho biết biến nào lớn hơn.

CompareTo So sánh biến với một tham số Object.

DaysInMonth Cho biết số ngày trong tháng theo tham số tháng, năm truyền vào.

IsLeapYear Cho biết giá trị năm truyền vào (dạng yyyy) có phải là năm nhuận hay không.

Subtract Trừ một giá trị thời gian khỏi biến.

ToLongDateString Chuyển giá trị biến ra định dạng Long Date.

ToLongTimeString Chuyển giá trị biến ra định dạng Long Time.

ToShortDateString Chuyển giá trị biến ra định dạng Short Date.

ToShortTimeString Chuyển giá trị biến ra định dạng Short Time.

ToString Trả về chuỗi trị của biến theo định dạng truyền vào

I.2.3. Kiểu Number:

Phần này nói chung cho các kiểu số Byte, Short, Integer, Long, Single, Double, Decimal

Field

Tên Mô tả

MaxValue Hiển thị giá trị lớn nhất của kiểu (chỉ đọc).

MinValue Hiển thị giá trị nhỏ nhất của kiểu (chỉ đọc).

Ngoại trừ kiểu String, các kiểu khác khi muốn chuyển sang kiểu chuỗi đều có thể dùng phương thức ToString (kế thừa từ lớp Object) để chuyển đổi và định dạng cùng lúc.

Cú pháp sử dụng:

ToString()

ToString(<biểu thức định dạng>)

Dưới đây là bảng biểu thức định dạng

Biểu thức định dạng

Biểu thức Ý nghĩa Ví dụ

c, C Định dạng tiền tệ 12345.67 ToString(“C”) hiển thị $ 12,345.67

e, E Định dạng số khoa học. 12345.67 ToString(“E”) hiển thị 1.234567E+0004

f, F Định dạng cố định 12345.67 ToString(“F”) hiển thị 12345.67 (với 2 số lẻ)

Page 40: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 40/187

g, G Định dạng tổng quát 12345.67 ToString(“G”) hiển thị 12345.67 tùy theo gía trị có thể hiện thị dưới dạng E hoặc F

n, N Định dạng số 12345.67 ToString(“N”) hiển thị 12,345.67

p, P Định dạng phần trăm 0.45 ToString(“P”) hiển thị 45 %

x, X Định dạng Thập lục phân 250 ToString(“X”) hiển thị FA

Ngoài ra chúng ta cũng có thể sử dụng các ký tự sau đây để lập biểu thức định dạng

Biểu thức định dạng tự định nghĩa

Biểu thức Ý nghĩa Ví dụ

0 Số không giữ chỗ 123 ToString(“0000”) hiển thị 0123

# Số bất kỳ giữ chỗ 123 ToString(“####”) hiển thị 123

. Dấu phần lẻ 123 ToString(“####.00”) hiển thị 123.00

, Dấu chia cụm ba số 12345 ToString(“#,###”) hiển thị 12,345

% Dấu phần trăm 0.45 ToString(“# %”) hiển thị 45 %

E+0,E-0,e+0, e-0

Dấu hiển thị số khoa học 12345678 ToString(“#.#######E+000”) hiển thị 1.2345678E+007

\ Ký tự literal 123456 ToString(“\# #,###”) hiển thị # 123,456

; Ký tự ngăn cách vùng

Ký tự ngăn cách vùng Với ToString(“dương #,###;âm #,###; số không”) -123456 hiển thị âm 123,456 0 hiển thị số không

II. Biến – Tính chất, khai báo và khởi tạo

II.1. Tính chất Biến là một thực thể với 6 tính chất sau:

Name: Tên của biến

Address: Địa chỉ vùng nhớ nơi lưu giữ giá trị của biến. Trong chu kỳ trình sống, địa chỉ của biến có thể thay đổi.

Type: Kiểu của biến, còn gọi là kiểu dữ liệu

Value: Giá trị của biến

Scope: Phạm vi sử dụng của biến.

Mỗi biến có một phạm vi sử dụng là phạm vi trong chương trình nơi biến được nhìn nhận đối với câu lệnh.

Phạm vi khối lệnh và phạm vi thủ tục

Khối lệnh là tập hợp các dòng lệnh được kết thúc bằng End, Else, Loop hoặc Next như trong cấu trúc For … Next, If...Then...Else...End If . Biến khai báo trong khối lệnh có phạm vi sử dụng chỉ trong khối lệnh

Ví dụ:

If x <> 0 then

Page 41: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 41/187

Dim a as Integer

a = 1/x

End If

MsgBox CStr(a))

Đoạn lệnh trên sẽ gây lỗi tại dòng MsgBox CStr(a)) vì biến a chỉ có phạm vi sử dụng trong khối lệnh If … End If

Khi biến được khai báo trong một thủ tục nhưng không trong một khối lệnh, biến sẽ có phạm vi sử dụng trong toàn thủ tục. Đây là trường hợp đặc biệt của phạm vi khối lệnh với khối lệnh là toàn bộ thủ tục.

Biến có phạm vi khối lệnh và phạm vi thủ tục là biến cục bộ.

Phạm vi module và phạm vi project

Có những khác biệt trong phạm vi sử dụng đối với các biến khai báo chung trong Module chuẩn (Standard module) và Lớp (Class module). Trước tiên, chúng ta cần lưu ý rằng bản thân Module chuẩn được khai báo với một trong ba từ khóa sau: Public, Friend và Private (mặc định)

Tùy theo từ khóa mà phạm vi sử dụng của các thành phần trong module bị giới hạn. Ví dụ một biến Public khai báo trong một module Friend sẽ có phạm vi sử dụng Friend

+ Truy xuất Private

Nếu biến được khai báo trên phần Declaration của module với từ khóa Private sẽ chỉ có phạm vi sử dụng trong module.

+ Truy xuất Friend

Nếu biến được khai báo trên phần Declaration của module với từ khóa Friend sẽ có phạm vi sử dụng trong toàn project. Các project khác không thể sử dụng biến này.

+ Truy xuất Public

Nếu biến được khai báo trên phần Declaration của module với từ khóa Public sẽ có phạm vi sử dụng trong toàn project và trong bất kỳ project nào bên ngoài có một tham chiếu (reference) đến project đó.

LifeTime: Thời gian tồn tại của biến.

Trong khi phạm vi sử dụng của biến xác định nơi chốn biến được phép sử dụng, thì thời gian tồn tại của biến xác định khoảng thời gian biến có thể lưu giữ giá trị.

Biến có phạm vi Module có thời gian tồn tại là thời gian ứng dụng đang thực hiện.

Biến có phạm vi khối lệnh, thủ tục chỉ tồn tại trong khi thủ tục đang thực hiện. Biến này sẽ được khởi tạo theo giá trị mặc định của kiểu dữ liệu khi thủ tục bắt đầu thực hiện và chấm dứt khi thủ tục kết thúc.

II.2. Khai báo và khởi tạo Lệnh khai báo biến là cú pháp kết hợp tên biến và kiểu dữ liệu. Tự thân lệnh này không hàm ý tạo biến. Tuy nhiên, với các biến không phải kiểu đối tượng, lệnh khai báo biến cũng chính là lệnh tạo biến

Cú pháp:

Dim x as Integer

Để nhấn mạnh vai trò của hàm tạo (constructor), chúng ta có thể viết:

Page 42: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 42/187

Dim x as Integer = New Integer()

Khi khai báo nhiều biến trên cùng dòng và không chỉ ra kiểu của biến, biến sẽ lấy kiểu dữ liệu của biến khai báo dữ liệu tường minh tiếp sau đó

Dim x as Integer, a, b, c as Long

Các biến a, b, c đều cùng có kiểu Long

Có thể khai báo và khởi tạo giá trị cho biến cùng lúc:

Dim x as Integer = 100, y as Integer = 200

Trong cách này, phải khai báo tường minh kiểu dữ liệu cho từng biến.

Với các biến kiểu đối tượng, cách khai báo cũng như thế

Dim objA as MyClass

Lệnh trên chưa tạo ra biến đối tượng và sau dòng lệnh, objA vẫn là Nothing

Những cách sau đây sẽ khai báo và tạo biến đối tượng:

Dim objA as New MyClass()

Hoặc

Dim objA as MyClass = New MyClass()

Hoặc

Dim objA as MyClass

objA = New MyClass()

Các từ khóa để khai báo biến

Từ khóa khai báo

Từ khóa Ý nghĩa

Public Sử dụng toàn cục

Private Sử dụng cục bộ trong phạm vi khai báo như Dim

Friend Sử dụng trong phạm vi của project

Protected Sử dụng trong phạm vi của lớp và các lớp con

Protected Friend Sử dụng trong phạm vi của Proctected và Friend

II.3. Kiểu trị và tham chiếu (Value Type và Reference Type) Các kiểu được định nghĩa trong Common Type System thuộc ba loại sau:

Kiểu trị (Value Type)

Kiểu tham chiếu (Reference Type)

Kiểu con trỏ (Pointer Type)

VB.Net không có kiểu con trỏ nên chúng ta chỉ xem xét kiểu trị và kiểu tham chiếu.

Khi một biến kiểu trị được khai báo, một vùng nhớ được dành riêng để chứa giá trị thực của biến. Ngược lại, khi một biến kiểu tham chiếu được khai báo, trình biên dịch sẽ tạo đối tượng trên vùng nhớ,

Page 43: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 43/187

nhưng sẽ gán cho biến bốn byte chứa địa chỉ của đối tượng. Tóm lại, biến kiểu trị chứa giá trị của biến còn biến kiểu tham chiếu chỉ đến nơi chứa giá trị.

Sự khác biệt này dẫn đến nhiều hệ quả mà phép gán là một. Để minh họa chúng ta xem Class sau với một thuộc tính:

Ví dụ:

Public Class Nguoi

Public tuoi as Short

End Class

Và kiểu Structure cũng có một thuộc tính:

Structure ConNguoi

Public tuoi as Short

End Structure

Class là kiểu tham chiếu trong khi Structure là kiểu trị.

Hãy xem xét đoạn lệnh sau:

Dim Ng1, Ng2 as Nguoi

Dim CNg1, CNg2 as ConNguoi

Ng1 = New Nguoi()

Ng1.tuoi = 30

Ng2 = Ng1

Ng2.tuoi = 20

Debug.WriteLine(Ng1.tuoi) ' xuất ra 20

Debug.WriteLine(Ng2.tuoi) ' xuất ra 20

CNg1 = New ConNguoi()

CNg1.tuoi = 30

CNg2 = CNg1

CNg2.tuoi = 20

Debug.WriteLine(CNg1.tuoi)' xuất ra 30

Debug.WriteLine(CNg2.tuoi)' xuất ra 20

Khi được gán cho nhau, hai biến tham chiếu Ng1, Ng2 cùng chứa địa chỉ trỏ đến một đối tượng. Vì vậy thay đối giá trị của thuộc tính tuoi trên biến này, thay đổi cũng phản ánh trên biến kia.

Ngược lại, khi được gán cho nhau, biến tham trị sẽ tạo nên một vùng nhớ chứa trị mới, hai biến trị CNg1, CNg2 cùng chứa trị như nhau nhưng trên hai vùng nhớ khác nhau. Do đó, giá trị của thuộc tính tuoi của hai biến được chứa trên hai vùng nhớ và độc lập nhau.

Chú ý: Kiểu String cũng là kiểu tham chiếu nhưng có một số đặc tính của kiểu trị.

Chúng ta xét đoạn lệnh sau:

Dim ch1, ch2 as String

ch1 = "Chuỗi 1"

ch2 = ch1

Page 44: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 44/187

ch2 = "Chuỗi 2"

MsgBox(ch1) ' xuất ra Chuỗi 1

Chúng ta nghĩ rằng ch1 chứa "Chuỗi 2", nhưng ch1 lại chứa "Chuỗi 1". Lý do như sau: khi biến kiểu String đã được tạo ra, giá trị của chúng không thể sửa đổi. Sửa đổi trị của biến String là tạo ra một thể hiện mới chứa nội dung sửa đổi. Do vậy:

Khi gán ch2 = ch1, ch2 trỏ đến cùng một chuỗi như ch1

Nhưng khi gán ch2 = "Chuỗi 2" do không thể thay đổi giá trị nên ch2 trỏ đến một thể hiện mới khác với ch1

Bảng sau đây cho biết kiểu dữ liệu thuộc kiểu trị hay kiểu tham chiếu:

Phân loại

Value Type Reference Type

Các kiểu dữ liệu số

Kiểu Boolean, Char, Date

Kiểu Structure, ngay cả khi các thành phần trong Structure là kiểu tham chiếu.

Kiểu String

Mảng

Kiểu lớp đối tượng

II.4. Kiểu Enum (Enumeration) Kiểu Enum là sự liên kết một tập hợp các trị hằng với các tên gợi nhớ. Các trị này mặc nhiên có kiểu Integer và chỉ có thể là kiểu Byte, Short, Long hoặc Integer.

Kiểu Enum chỉ được tạo trong các Class hoặc Module

Cú pháp:

[Public | Protected | Friend | Protected Friend |

Private] [ Shadows ] Enum <tên> [ As <Kiểu DL>]

<tên thành phần thứ 1> [ = trị hằng 1]

<tên thành phần thứ 2> [ = trị hằng 2]

...

<tên thành phần thứ 3> [ = trị hằng 3]

End Enum

Ví dụ:

Public Enum DoTuoi as Integer

Nhidong = 0

Thieunien = 1

Thanhnien = 2

Trungnien = 3

End Enum

Khi không chỉ ra trị hằng, VB.NET sẽ gán trị cho thành phần đầu tiên là 0 và tăng dần cho các thành phần kế tiếp:

Page 45: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 45/187

Ví dụ:

Public Enum DoTuoi as Integer

Nhidong ' mặc nhiên có trị 0

Thieunien ' mặc nhiên có trị 1

Thanhnien ' mặc nhiên có trị 2

Trungnien ' mặc nhiên có trị 3

End Enum

Nếu chỉ gán trị hằng cho thành phần đầu tiên, các thành phần kế tiếp sẽ nhận giá trị tăng dần:

Public Enum DoTuoi as Integer

Nhidong = 100

Thieunien ' mặc nhiên có trị 101

Thanhnien ' mặc nhiên có trị 102

Trungnien ' mặc nhiên có trị 103

End Enum

Sau khi khai báo kiểu Enum, chúng ta có thể khai báo biến kiểu Enum cũng như sử dụng các thành phần của kiểu này thay cho các trị hằng.

Dim a As DoTuoi

a =

III. Mảng – Structure

III.1. Mảng Mảng là tập hợp các biến có cùng kiểu dữ liệu, cùng tên nhưng có chỉ số khác nhau. Trong VB.Net, mảng có chỉ số bắt đầu là 0 và luôn luôn là mảng động. Không như trong VB6, với VB.Net chúng ta không được dùng từ khóa Redim để khai báo mảng nhưng chỉ được dùng để định lại kích thước mảng. Chúng ta có các cách khai báo mảng như sau

Cú pháp:

Khai báo không khởi tạo kích thước và giá trị

Dim a() as Integer

Hoặc

Dim a as Integer()

Khai báo có khởi tạo kích thước nhưng không khởi tạo giá trị ban đầu:

Dim a(6) as Integer

Khai báo có khởi tạo kích thước và khởi tạo giá trị ban đầu:

Dim a() as Integer = {1,2,3,4,5,6,7}

Page 46: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 46/187

Hoặc

Dim a() as Integer = New Integer(6){1,2,3,4,5,6,7}

Hoặc

Dim a() as Integer = New Integer(6){}

Chú ý: Khi dấu { } rỗng, các phần tử có giá trị khởi tạo là giá trị mặc định của kiểu dữ liệu.

Mảng có kiểu tham chiếu nên khi gán hai biến mảng cho nhau, biến được gán sẽ là một tham chiếu đến mảng bên phải toán tử =, khác với trong VB6, là tạo ra một mảng mới có số phần tử mang trị giống nhau.

Mảng thuộc lớp System.Array nên có các thuộc tính và phương thức của lớp này. Sau đây là một số thuộc tính và phương thức đáng chú ý:

Thuộc tính

Tên Mô tả

Length Số phần tử của mảng

Rank Số chiều của mảng

Phương thức

Tên Mô tả

BinarySearch Tìm kiếm trên mảng một chiều đã được sắp xếp giá trị truyền vào, sử dụng thuật giải tìm kiếm nhị phân.

Clear Gán các phần tử trong dãy chỉ ra bằng giá trị mặc định của kiểu dữ liệu các phần tử

Clone Trả về bản sao cạn (shallow copy) của mảng. Bản sao này chỉ sao chép kiểu trị và kiểu tham chiếu nhưng không sao chép các đối tượng được tham chiếu đến.

Copy Sao chép một phần của mảng vào mảng khác và thực hiện chuyển đổi kiểu nếu cần.

CopyTo Sao chép toàn bộ các phần tử của mảng một chiều vào mảng một chiều được truyền vào bắt đầu từ vị trí chỉ ra.

GetLength Trả về số phần tử của một chiều được chỉ ra trên mảng

GetLowerBound Trả về chỉ số nhỏ nhất của một chiều được chỉ ra trên mảng

GetUpperBound Trả về chỉ số lớn nhất của một chiều được chỉ ra trên mảng

GetValue Trả về trị của một phần tử chỉ ra trên mảng

IndexOf Trả về chỉ số của phần tử đầu tiên trên mảng một chiều (hoặc trên một vùng của mảng) trùng với giá trị truyền vào

LastIndexOf Trả về chỉ số của phần tử cuối cùng trên mảng một chiều (hoặc trên một vùng của mảng) trùng với giá trị truyền vào

Reverse Đảo ngược thứ tự các phần tử trên mảng một chiều hoặc trên một phần của mảng

SetValue Gán trị cho một phần tử chỉ ra trên mảng

Sort Sắp xếp các phần tử trong mảng một chiều

Page 47: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 47/187

III.2. Structure Khác với mảng, Structure, kiểu do người dùng định nghĩa (UDT: User Defined Type), là một cấu trúc gồm một hoặc nhiều thành phần có kiểu dữ liệu khác nhau. Tuy chúng ta có thể truy xuất riêng lẻ các thành phần nhưng Structure được xem như là một thực thể duy nhất. Trong phiên bản trước, UDT được khai báo với từ khóa Type … End Type. Trong VB.NET, cú pháp khai báo Structure như sau:

Cú pháp:

[Public|Private|Protected] Structure <tên strucure>

{Dim|Public|Private|Friend}<tên thành phần> As <kiểu dữ liệu>

...

{Dim|Public|Private|Friend}<tên thành phần N> As <kiểu dữ liệu>

End Structure

Với Structure, chúng ta được phép khai báo các phương thức.

Sau đây là các đặc điểm của Structure:

Có các thành phần, kể cả bộ khởi tạo, phương thức, thuộc tính, hằng, sự kiện.

Có thể cài đặt các lớp giao tiếp (Interface).

Có thể có các bộ khởi tạo chung, có hoặc không có tham số.

Structure là kiểu trị.

Tất cả các thành phần của Structure mặc định là Public.

Các thành phần của Structure không được khai báo với từ khóa Protected.

Structure không thể kế thừa.

Mỗi Structure có một bộ khởi tạo mặc nhiên không tham số ban đầu. Bộ khởi tạo này sẽ khởi tạo mọi thành phần dữ liệu của Structure với giá trị mặc định của chúng. Chúng ta không thể định nghĩa lại chức năng này.

Vì Structure là kiểu trị (Value Type), nên mỗi biến Structure luôn luôn gắn liền với một thể hiện Structure.

IV. Các toán tử Toán tử là ký hiệu chỉ ra phép toán nào được thực hiện trên các toán hạng (có thể là một hoặc hai toán hạng)

IV.1. Toán tử toán học Bảng toán tử toán học

Ký hiệu Mô tả

+ (cộng)

- (trừ)

* (nhân)

/ (chia)

Page 48: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 48/187

\ (chia lấy phần nguyên)

Mod chia lấy phần dư của số nguyên

^ (lũy thừa)

IV.2. Toán tử nối chuỗi Toán tử chỉ dành cho toán hạng kiểu String với hai toán tử là & (ampersand) và + (cộng). Kết quả là một trị String gồm các ký tự của toán hạng thứ nhất tiếp theo sau là các ký tự của toán hạng thứ hai

IV.3. Toán tử gán Bảng toán tử gán

Ký hiệu Mô tả

= Gán toán hạng thứ hai cho toán hạng thứ nhất

+= Cộng hoặc nối chuỗi toán hạng sau vào toán hạng đầu và gán kết quả cho toán hạng đầu

-= Trừ toán hạng sau khỏi toán hạng đầu và gán hiệu cho toán hạng đầu

*= Nhân hai toán hạng với nhau và gán tích cho toán hạng đầu

/= Chia toán hạng đầu cho toán hạng sau và gán thương cho toán hạng đầu

\= Thực hiện phép toán \ giữa toán hạng đầu và toán hạng sau và gán kết quả cho toán hạng đầu

^= Tính lũy thừa toán hạng đầu với số mũ là toán hạng sau và gán kết quả cho toán hạng đầu

&= Nối chuỗi toán hạng sau vào toán hạng đầu và gán kết quả cho toán hạng đầu

IV.4. Toán tử so sánh Bảng toán tử so sánh

Ký hiệu Mô tả

= Bằng

>= Lớn hơn hoặc bằng

<= Nhỏ hơn hoặc bằng

> Lớn hơn

< Nhỏ hơn

<> Khác

TypeOf … Is … So sánh kiểu của biến kiểu tham chiếu thứ nhất có trùng kiểu trên toán hạng thứ hai, nếu trùng trả về True, ngược lại False

Is Toán tử dành cho toán hạng kiểu tham chiếu, trả về True nếu hai toán hạng cùng tham chiếu đến một đối tượng, ngược lại là False)

Like Toán tử dành cho toán hạng kiểu String, trả về True nếu toán hạng thứ nhất trùng với mẫu (pattern) của toán hạng thứ hai, ngược lại là False. Ví dụ:

Page 49: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 49/187

Dim kiem_tra As Boolean kiem_tra = "F" Like "F" True. kiem_tra = "F" Like "f" False. kiem_tra = "F" Like "FFF" False. kiem_tra = "aBBBa" Like "a*a" ( True. (bắt đầu và kết thúc chuỗi là ký tự a, ở giữa là số ký tự bất kỳ) kiem_tra = "F" Like "[A-Z]" ( True. (giá trị trong dãy từ A đến Z) kiem_tra = "F" Like "[!A-Z]" False. kiem_tra = "a2a" Like "a#a" ( True. (bắt đầu và kết thúc chuỗi là ký tự a, ở giữa là một ký số) kiem_tra = "aM5b" Like "a[L-P]#[!c-e]" True. kiem_tra = "BAT123khg" Like "B?T*" True. kiem_tra = "CAT123khg" Like "B?T*" False.

IV.5. Toán tử luận lý và Bitwise Toán tử luận lý trả về giá trị True/False

Bảng toán tử gán

Ký hiệu Mô tả

Not Trả về giá trị ngược lại của toán hạng

And Trả về True (1) khi và chỉ khi hai toán hạng cùng là True (1)

AndAlso Trả về giá trị như And nhưng khi toán hạng thứ nhất là False (0) sẽ không kiểm tra toán hạng thứ hai và trả về False

Or Trả về False (0) khi và chỉ khi hai toán hạng cùng là False (0)

OrElse Trả về giá trị như Or nhưng khi toán hạng thứ nhất là True (1) sẽ không kiểm tra toán hạng thứ hai và trả về True (1)

Xor Trả về True (1) khi và chỉ khi có 1 toán hạng là True (1)

Not Trả về giá trị ngược lại của toán hạng

V. Cấu trúc điều khiển

V.1. Cấu trúc chọn

V.1.1. If … Then … Else

Trước tiên, chúng ta làm quen với cấu trúc If … Then … End If

Cú pháp:

If <điều kiện> Then

' Các câu lệnh

End if

Sử dụng cú pháp này, người lập trình muốn khai báo với trình biên dịch rằng các câu lệnh trong vùng If … End If chỉ được thực hiện nếu như <điều kiện> là đúng.

Page 50: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 50/187

<điều kiện> có thể là biểu thức trả về giá trị True/False hoặc là một giá trị số. Giá trị số <> 0 tương ứng với True, ngược lại là False.

Cấu trúc If … Then … End If còn thiếu sót vì đôi khi chúng ta muốn thực hiện các câu lệnh khác khi điều kiện không đúng. Lúc này, chúng ta sử dụng cấu trúc sau:

Cú pháp:

If <điều kiện> Then

' Các lệnh sẽ thực hiện nếu điều kiện đúng

End If

If Not <điều kiện> Then

' Các lệnh sẽ thực hiện nếu điều kiện sai

End If

Để thay thế cách viết trên, chúng ta có cấu trúc sau:

If <điều kiện> Then

' Các câu lệnh khi điều kiện đúng

Else

' Các câu lệnh khi điều kiện sai

End if

Trong trường hợp nhiều điều kiện, chúng ta sử dụng cấu trúc:

If <điều kiện 1> Then

...

ElseIf <điều kiện 2> Then

...

ElseIf <điều kiện n> Then

...

Else

...

End If

Ghi chú: Các mệnh đề If … Then … Else có thể lồng nhau.

V.1.2. Select … Case

Khi có nhiều trường hợp cần xét, có thể sử dụng cấu trúc chọn Select … Case với cú pháp

Cú pháp:

Select Case <biểu thức>

Case <giá trị 1>

' Các lệnh thực hiện khi <biểu thức> = <giá trị 1>

Case <giá trị 2>

' Các lệnh thực hiện khi <biểu thức> = <giá trị 2>

Case Else

Page 51: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 51/187

' Các lệnh thực hiện khi <biểu thức> không bằng giá trị nào ở trên

End Select

Khối lệnh Case Else có thể không cần viết. Tuy nhiên, người lập trình được khuyến khích dùng khối lệnh này trong cấu trúc để giảm bớt các lỗi logic.

Các giá trị dùng để so sánh có thể gồm nhiều giá trị phân biệt bởi dấu phẩy (,) hoặc là một phần của biểu thức so sánh.

V.2. Cấu trúc lặp Cấu trúc lặp cho phép thực hiện nhiều lần một khối lệnh của chương trình. Các cấu trúc lặp thường được sử dụng trong Visual Basic.NET gồm:

V.2.1. For … Next

Cú pháp:

For <biến đếm> = <giá trị đầu> To <giá trị cuối> [Step <bước>]

' Các câu lệnh

Next [biến đếm]

Các câu lệnh trong vùng For … Next chỉ được thực hiện nếu <biến đếm> có giá trị trong đoạn [<giá trị đầu>, <giá trị cuối>]

Sau mỗi lần thực hiện, <biến đếm> sẽ được tăng thêm <bước>. Nếu không chỉ định, <bước> có giá trị là 1.

Nếu <bước> có trị > 0, cấu trúc chỉ thực hiện khi <giá trị đầu> <= <giá trị cuối>

Nếu <bước> có trị < 0, cấu trúc chỉ thực hiện khi <giá trị đầu> >= <giá trị cuối>

V.2.2. For Each … Next

Cú pháp:

For Each <phần tử> In <tập hợp>

' Các câu lệnh

Next [phần tử]

Với cú pháp này, chương trình sẽ duyệt qua từng phần tử trong tập hợp đang duyệt.

Cần khai báo biến <phần tử> là kiểu của phần tử trong tập hợp đang duyệt. Chúng ta có thể chấm dứt lặp khi đang giữa vòng lặp bằng lệnh Exit For

V.2.3. Do While … Loop

Cú pháp:

Do While <biểu thức logic>

' Các câu lệnh

Loop

Với cú pháp này, các câu lệnh đặt trong vùng Do While … Loop chỉ thực hiện bao lâu <biểu thức logic> có giá trị True.

Sau mỗi lần thực hiện các câu lệnh trong vùng Do While...Loop, <biểu thức logic> sẽ được kiểm tra lại:

Page 52: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 52/187

Nếu trị True, thực hiện lại vòng lặp

Nếu trị False, chấm dứt vòng lặp.

Cấu trúc này kiểm tra <biểu thức logic> trước khi thực hiện các lệnh nên sẽ không thực hiện lần nào nếu ngay lần đầu tiên <biểu thức logic> có trị False.

V.2.4. Do … Loop While

Cú pháp:

Do

' Các câu lệnh

Loop While <biểu thức logic>

Tương tự Do While … Loop, các câu lệnh chỉ tiếp tục thực hiện khi <biểu thức logic> có giá trị True và sẽ kiểm tra lại <biểu thức logic> sau mỗi lần thực hiện.

Do kiểm tra sau khi thực hiện nên nếu ngay lần đầu <biểu thức logic> có trị False, các lệnh cũng được thực hiện một lần.

Chúng ta có thể chấm dứt giữa chừng vòng lặp với lệnh Exit Do

V.2.5. Do Until … Loop

Cú pháp:

Do Untile <biểu thức logic>

' Các câu lệnh

Loop

V.2.6. Do … Loop Until

Cú pháp:

Do

' Các câu lệnh

Loop Until <biểu thức logic>

Hai cú pháp nầy tương tự hai cú pháp trên (Do While … Loop, Do … Loop While), với một khác biệt là chỉ thực hiện hoặc tiếp tục thực hiện khi <biểu thức logic> là False.

V.2.7. While … End While

Cú pháp khác so với trong các phiên bản trước (While … Wend), cách sử dụng như Do While … Loop

VI. Những thay đổi trong VB.NET

VI.1. Thay đổi trong thủ tục và hàm Tham số là tham trị

Tham số truyền cho hàm hoặc thủ tục mặc định là tham trị ByVal chứ không phải ByRef như trong VB6.

Trong VB6, tham số ParamArray vốn được truyền theo kiểu tham chiếu ByRef và không thể thay đổi thành ByVal nhưng trong VB.NET là tham trị ByVal và không thể thay đổi thành ByRef.

Page 53: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 53/187

Tham số tùy chọn

Tham số tùy chọn Optional phải khai báo giá trị mặc nhiên, khi không truyền tham số.

Ví dụ:

Sub TEST(ByVal a As Integer,Optional ByVal c As Boolean = False)

' Các câu lệnh

End Sub

Cách hàm trả về giá trị

Giá trị của hàm có thể trả về qua dòng lệnh Return.

Function TESTFUNCTION(ByVal a As Short, ByVal c As Short) As Integer

' Các câu lệnh

Return <giá trị trả về>

End Function

Cho phép nhiều hàm, thủ tục trùng tênị

Có thể có nhiều hàm và thủ tục trùng tên nhau (Overloaded) miễn là số tham số hoặc kiểu dữ liệu tham số khác nhau.

Ví dụ:

Function BinhPhuong(ByVal so As Integer) As Integer

Return Convert.ToInt32(so^2)

End Function

Function BinhPhuong(ByVal so As Double) As Double

Return so^2

End Function

Trong VB6, nếu tham số truyền vào là thuộc tính của một đối tượng cho thủ tục kiểu ByRef, những thay đổi trên tham số đó trong thủ tục không phản ánh trên thuộc tính. Ngược lại, trong VB.NET, các thay đổi như vậy đều thể hiện trên thuộc tính của đối tượng.

VI.2. Khai báo Option Strict Khai báo Option Strict On|Off là một lệnh mới không cho phép các chuyển đổi kiểu làm mất dữ liệu. Nhưng chúng ta có thể thực hiện các chuyển đổi mở rộng như chuyển biến kiểu Integer sang kiểu Long. Khai báo này (khi bật On) sẽ không cho phép tự động chuyển đổi kiểu chuỗi sang kiểu số hay ngược lại.

Ví dụ:

Option Strict On

--------------------------

Dim x As String, y As Integer

' x = y sẽ gây lỗi cú pháp

' nhưng phải dùng

x = CStr(y)

Page 54: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 54/187

' hoặc

x = y.ToString

VI.3. Kiểu chuỗi có độ dài cố định Kiểu chuỗi có độ dài cố định trong VB6 không còn được hỗ trợ trong VB.NET

VI.4. Chỉ thị #Region … #End Region Chỉ thị #Region … #End Region được dùng để đánh dấu một khối lệnh có thể thu gọn, giản ra trên cửa sổ viết lệnh.

Cú pháp:

#Region <chuỗi định danh>

' khối lệnh

#End Region

<chuỗi định danh>: bắt buộc, có giá trị kiểu String, là tiêu đề của khối lệnh

Ví dụ:

#Region "Các khai báo"

' Đưa vào các dòng lệnh khai báo.

#End Region

Khi thu lại:

+ Các khai báo

VI.5. Imports không gian tên (Namespace) Mục đích của lệnh Imports là để đưa không gian tên vào trong Module cho việc khai báo và tạo các lớp trong không gian tên ngắn gọn hơn.

Cú pháp:

Imports [<bí danh> = ]<không gian tên> [.<thành phần>]

<bí danh>: tùy chọn, kiểu String, là tên tắt của <Namespace> được sử dụng trong tham chiếu trên Module, Class. Nếu lệnh Imports không có phần bí danh, các thành phần định nghĩa trong không gian tên có thể được truy cập mà không cần chỉ rõ. Nếu có bí danh, bí danh phải được sử dụng trong phần truy cập.

<không gian tên>: bắt buộc, không gian tên sử dụng trong Module, Class

<thành phần>: tùy chọn, tên của một thành phần đã được khai báo trong không gian tên. Nó có thể là định danh, structure, class…

Chú ý

Mỗi lệnh Imports chỉ được sử dụng với một không gian tên.

Mỗi Module có thể có nhiều dòng Imports

Các lệnh Imports phải được đặt trước tất cả các khai báo, kể cả lệnh khai báo Module hoặc Class.

Sau lệnh Imports, các thành phần được tham chiếu không cần phải chỉ ra nội dung phần Imports

Page 55: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 55/187

Không được phép định nghĩa một thành phần ở cấp Module cùng tên với bí danh đã đặt

Ví dụ:

Imports Str = Microsoft.VisualBasic.String

Class lopVidu

Sub Chao()

MessageBox.Show(Str.Left("Chào bạn", 5))

End Sub

End Class

VII. Xử lý lỗi

VII.1. Phân loại lỗi Trong VB.NET, chúng ta có thể gặp các loại lỗi sau:

VII.1.1. Syntax error

Lỗi cú pháp, còn gọi là lỗi trong lúc thiết kế. Những lỗi này dễ chỉnh sửa vì VB.NET sẽ kiểm tra cú pháp khi ta đang nhập từ bàn phím nên sẽ báo lỗi tức thời khi ta gõ sai hoặc dùng một từ không thích hợp.

VII.1.2. Run-time error

Lỗi thực thi xảy ra khi chương trình đang thực thi. Đây là những lỗi khó xác định hơn lỗi cú pháp. Lỗi thực thi có thể từ các lý do khác nhau như:

Mở một tập tin không tồn tại

Truy xuất một thư mục nhưng không có quyền trên đó

Truy xuất dữ liệu một bảng không tồn tại trong CSDL

Chia cho số 0

Nhập chuỗi cho nơi cần nhập số hoặc ngược lại, v.v…

VII.1.3. Logic error

Lỗi luận lý cũng xảy ra khi chương trình đang thực thi và được thể hiện dưới những hình thức hay những kết quả không mong đợi. Loại lỗi này thường do sai lầm trong thuật giải.

VII.2. Xử lý lỗi Một lỗi xảy ra khi chương trình đang chạy gọi là một Exception. Trong CLR, Exception là một đối tượng từ lớp System.Exception. Chúng ta cần lưu ý một lỗi xảy ra trong lúc thực thi không làm treo chương trình, nhưng nếu không được xử lý sẽ làm treo chương trình. CLR chỉ ra tình trạng lỗi qua lệnh Throw. Lệnh này sẽ đưa ra một đối tượng kiểu System.Exception chứa thông tin về lỗi đang xảy ra.

Trước đây, chúng ta thường sử dụng cú pháp On Error Goto <nhãn lỗi> để xử lý lỗi. Đây là một loại xử lý không cấu trúc vì kể từ dòng lệnh On Error Goto <nhãn lỗi> đến cuối thủ tục hay hàm, nếu dòng lệnh nào gây lỗi chương trình đều nhường quyền xử lý cho đoạn lệnh của <nhãn lỗi>. Với VB.NET, chúng ta phát hiện và xử lý lỗi một cách chặt chẽ với cú pháp

Page 56: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 56/187

Cú pháp:

Try

' các lệnh có khả năng gây lỗi

Catch

' các lệnh xử lý khi lỗi xảy ra

[Finally]

' các lệnh thực hiện sau cùng

End Try

Cấu trúc này cho phép chúng ta thử (Try) thực hiện một khối lệnh xem có gây lỗi không; nếu có sẽ bẫy và xử lý (Catch) lỗi.

Cấu trúc này chia làm các khối sau:

Khối Try:

Chứa các câu lệnh có khả năng gây lỗi

Khối Catch:

Các dòng lệnh để bẫy và xử lý lỗi phát sinh trên khối Try. Khối này gồm một loạt các lệnh bắt đầu với từ khóa Catch, biến kiểu Exception ứng với một kiểu Exception muốn bẫy và các lệnh xử lý. Dĩ nhiên, chúng ta có thể dùng một lệnh Catch cho các System.Exception, nhưng như thế sẽ không cung cấp thông tin đầy đủ cho người dùng về lỗi đang xảy ra cũng như hướng dẫn cách xử lý cụ thể cho mỗi tình huống. Ngoài những lỗi đã xử lý, có thể xảy ra những lỗi ngoài dự kiến, để xử lý các lỗi này, chúng ta nên đưa thêm một lệnh Catch để bẫy tất cả các trường hợp còn lại và xuất thông tin về lỗi xảy ra.

Khối Finally:

Khối tùy chọn, sau khi chạy qua các khối Try và Catch nếu không có chỉ định nào khác, khối Finally sẽ được thực hiện bất kể có xảy ra lỗi hay không.

Cuối cùng, cấu trúc bẫy và xử lý lỗi chấm dứt với từ khóa End Try.

Cú pháp chung cho một cấu trúc xử lý lỗi như sau

Try

' khối lệnh có thể gây lỗi

Catch <biến1> As <Kiểu Exception> [When <biểu thức>]

' khối lệnh bẫy và xử lý lỗi

Catch <biến2> As <Kiểu Exception> [When <biểu thức>]

' khối lệnh bẫy và xử lý lỗi

Finally

' khối lệnh kết thúc

End Try

Ví dụ:

Dim d as Double, i as Integer

Try

i = CInt(InputBox(“Xin nhập một số nguyên”))

d = 42 \ i

Page 57: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 57/187

Catch ex As DivideByZeroException

Messagebox.Show(“Không thể chia cho số không”)

Catch ex As InvalidCastException

Messagebox.Show(“Xin nhập số nguyên !”)

End Try

Câu lệnh Catch có thể có nhiều cách sử dụng:

VII.2.1. Bẫy không có điều kiện

Dim d as Double, i as Integer

Try

i = CInt(InputBox(“Xin nhập một số nguyên”))

d = 42 \ i

Catch

Messagebox.Show(“Không thể chia")

End Try

VII.2.2. Bẫy với kiểu lỗi chung Exception

Dim d As Double, i As Integer

Try

i = InputBox("Xin nhập một số nguyên")

d = 42 \ i

Catch ex As Exception

MessageBox.Show("Không thể chia")

End Try

VII.2.3. Bẫy với những kiểu Exception đặc biệt

Các kiểu Exception đặc biệt thường gặp

Bảng liệt kê các Exception

Tên Mô tả

ArgumentException Tham số truyền không hợp lệ

DivideByZeroException Chương trình thực hiện phép chia một số cho số không

OverFlowException Kết quả của một phép toán hoặc của một phép chuyển đổi kiểu lớn hơn khả năng lưu giữ của biến

FieldAccessException Chương trình truy xuất một field Private hoặc Protected của lớp

InvalidCastException Chương trình đang cố thực hiện một chuyển đổi không hợp lệ

InvalidOperationException Chương trình đang cố gọi một thủ tục không hợp lệ

MemberAccessException Truy xuất một thành phần của một lớp bị thất bại

MethodAccessException Chương trình đang cố gọi thủ tục Private hoặc Protected của lớp

NullReferenceException Chương trình đang cố truy xuất một đối tượng không tồn tại

TypeUnloadException Chương trình truy xuất một lớp chưa được tải lên vùng nhớ

Page 58: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 58/187

VII.2.4. Bẫy với điều kiện When

Dim d As Double, i As Integer

Try

i = InputBox("Xin nhập một số nguyên")

d = 42 \ i

Catch ex As Exception When i = 0

MessageBox.Show("Không thể chia cho số không")

End Try

Page 59: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 59/187

Bài 3

LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG TRONG VISUAL BASIC .NET

Tóm tắt Lý thuyết 6 tiết - Thực hành 10 tiết

Mục tiêu Các mục chính Bài tập

Giới thiệu về Lập trình hướng đối tượng và cách xây dựng lớp đối tượng trong Visual Basic .Net

1. Lập trình hướng đối tượng

2. Lập trình hướng đối tượng trong VB.NET

2.1, 2.2, 2.3, 2.4, 2.5

Page 60: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 60/187

I. Lập trình hướng đối tượng Tư tưởng chính của lập trình hướng đối tượng là xây dựng một chương trình dựa trên sự phối hợp hoạt động của các đối tượng. Một đối tượng bao gồm hai thành phần chính là thông tin lưu trữ và các thao tác xử lý. Trong thế giới thực, đối tượng là thực thể tồn tại như con người, xe, máy tính, v.v…Trong ngôn ngữ lập trình, đối tượng có thể là màn hình, điều khiển v.v…

Lập trình hướng đối tượng là kiểu lập trình nhằm vào sự tương tác giữa các đối tượng. Mỗi đối tượng có những thuộc tính (thông tin lưu trữ), những phương thức xác định các chức năng của đối tượng. Bên cạnh đó, đối tượng cũng có khả năng phát sinh các sự kiện khi thay đổi thông tin, thực hiện một chức năng hay khi đối tượng khác tác động vào. Tất cả những thuộc tính, phương thức và sự kiện tạo nên cấu trúc của đối tượng. Có bốn ý niệm trong Lập trình hướng đối tượng:

Abstraction: Tính trừu tượng

Encapsulation: Tính bao bọc

Inheritance: Tính kế thừa

Polymorphism: Tính đa hình

Mỗi ý niệm đều có vai trò quan trọng trong lập trình hướng đối tượng.

I.1. Tính trừu tượng Chúng ta thường lẫn lộn giữa lớp (Class) và đối tượng (Object). Cần phân biệt lớp là một ý niệm trừu tượng, còn đối tượng là một thể hiện của lớp.

Ví dụ:

Class ConNgười là một ý niệm trừu tượng, nhưng NguyễnVănA là một đối tượng cụ thể.

Từ những đối tượng giống nhau, chúng ta có thể trừu tượng hóa thành một lớp đối tượng.

Tính trừu tượng cho phép chúng ta loại bỏ tính chất phức tạp của đối tượng bằng cách chỉ đưa ra các thuộc tính và phương thức cần thiết của đối tượng trong lập trình.

I.2. Tính bao bọc Mỗi Class được xây dựng để thực hiện một nhóm chức năng đặc trưng của riêng Class, trong trường hợp một đối tượng thuộc Class cần thực hiện một chức năng không nằm trong khả năng vì chức năng đó thuộc về một đối tượng thuộc Class khác, nó sẽ yêu cầu đối tượng đó đảm nhận thực hiện công việc. Một điểm quan trọng trong cách giao tiếp giữa các đối tượng là một đối tượng sẽ không được truy xuất trực tiếp vào thành phần dữ liệu của đối tượng khác cũng như không đưa thành phần dữ liệu của mình cho đối tượng khác một cách trực tiếp. Tất cả mọi thao tác truy xuất vào thành phần dữ liệu từ đối tượng này qua đối tượng khác phải được thực hiện bởi các phương thức (method) của chính đối tượng chứa dữ liệu. Đây cũng chính là một tính chất quan trọng trong lập trình hướng đối tượng gọi là tính bao bọc (encapsulation) dữ liệu.

Tính bao bọc cho phép dấu thông tin của đối tượng bằng cách kết hợp thông tin vớiø các phương thức liên quan đến thông tin trong đối tượng.

Ví dụ:

Xe hơi có các chức năng (phương thức phô diễn bên ngoài) như Ngừng, Chạy tới, Chạy lùi. Đây là

Page 61: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 61/187

những gì cần thiết cho Tài xế khi tương tác với Xe hơi. Xe hơi có thể có một đối tượng Động cơ nhưng Tài xế không cần phải quan tâm. Tất cả những gì cần quan tâm là những chức năng để có thể vận hành xe. Do đó, khi thay một Động cơ khác, Tài xế vẫn sử dụng các chức năng cũ để vận hành Xe hơi bao lâu các phương thức phô diễn bên ngoài (Interface) không bị thay đổi.

I.3. Tính kế thừa Tính kế thừa là khả năng cho phép ta xây dựng một lớp mới dựa trên các định nghĩa của một lớp đã có. Lớp đã có gọi là lớp Cha, lớp mới phát sinh gọi là lớp Con và đương nhiên kế thừa tất cả các thành phần của lớp Cha, có thể mở rộng công năng các thành phần kế thừa cũng như bổ sung thêm các thành phần mới

Chúng ta phân biệt hai loại quan hệ:

I.3.1. Là-một

Biểu thị tính kế thừa. Trong quan hệ "là-một", một đối tượng của lớp Con được xem như là một đối tượng của lớp Cha.

Ví dụ:

Từ lớp Xe ta tạo nên lớp Xe hơi mở rộng, lớp này mặc nhiên kế thừa tất cả các thành phần của lớp xe. Ta có thể nói: một xe hơi là một chiếc xe.

I.3.2. Có-một

Quan hệ này mang ý nghĩa gồm có. Trong quan hệ "có-một", một đối tượng có thể có một hoặc nhiều thành phần tham chiếu đến các đối tượng khác.

Ví dụ:

Khi lập mô hình loại xe hơi, bạn muốn diễn tả ý tưởng chiếc xe "có-một" tay lái. Chúng ta không thể phát sinh lớp Xe hơi từ một Tay lái hay ngược lại (một Xe hơi "là-một" Tay lái !!!). Thay vì vậy, chúng ta phải có hai lớp độc lập làm việc với nhau trong đó, lớp phía ngoài (lớp Xe hơi) sẽ tạo và phô diễn công năng của lớp phía trong (lớp Tay lái).

I.4. Tính đa hình Tính đa hình là khả năng một ngôn ngữ xử lý các đối tượng hữu quan theo cùng một cách.

Tính đa hình thể hiện dưới nhiều hình thức:

I.4.1. Kết nối trễ - Late Binding

Đây là khả năng cho phép người lập trình gọi trước một phương thức của đối tượng, tuy chưa xác định được đối tượng. Đến khi thực hiện, chương trình mới xác định được đối tượng và gọi phương thức tương ứng của đối tượng đó. Kết nối trễ giúp chương trình được uyển chuyển chỉ yêu cầu đối tượng cung cấp đúng phương thức cần thiết là đủ.

Ví dụ:

Xe

Xe hơi

Page 62: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 62/187

Chúng ta có lớp Xe với phương thức Chạy và các lớp Xe đạp, Xe hơi, Xe đẩy cùng phát sinh từ lớp Xe. Chúng ta chưa biết sẽ sử dụng xe gì để di chuyển vì tùy thuộc tình hình có sẵn xe nào nên gọi trước phương thức Chạy. Khi chương trình thực thi, tùy theo đối tượng của lớp nào được đưa ra mà phương thức Chạy của đối tượng đó được gọi.

I.4.2. Nạp chồng - Overloading

Khả năng cho phép một lớp có nhiều thuộc tính, phương thức cùng tên nhưng với các tham số khác nhau về loại cũng như về số lượng. Khi được gọi, dựa vào tham số truyền vào, thuộc tính hay phương thức tương ứng sẽ được thực hiện.

I.4.3. Ghi chồng - Overriding

Hình thức này áp dụng cho lớp Con đối với lớp Cha. Lớp Con được phép có một phương thức cùng tên, cùng số tham số có kiểu dữ liệu như phương thức của lớp Cha hoặc những lớp trước đó nữa (lớp phát sinh ra lớp Cha …) với cài đặt khác đi. Lúc thực thi, nếu lớp Con không có phương thức riêng, phương thức của lớp Cha sẽ được gọi, ngược lại nếu có, phương thức của lớp Con được gọi.

II. Lập trình hướng đối tượng trong VB.NET

II.1. Tạo một Class Chúng ta tạo một Class mới trong VB.NET bằng cách dùng thực đơn Project | Add Class. Hộp thoại Add New Item sẽ hiện ra, chọn Class trên khung bên phải và nhập tên vào ô Name bên dưới

Mã lệnh của Class nầy sẽ được chứa trong một tập tin có phần mở rộng là vb. Trong VB.NET tất cả các tập tin nguồn của các đối tượng form, class, module …đều có phần mở rộng là vb. Hệ thống sẽ nhận diện ra loại nào tùy theo nội dung của chúng chứ không dựa vào phần mở rộng.

Nhấn OK, để xác nhận tạo tập tin, tập tin sẽ được tạo và đưa vào Project. Lúc này trên cửa sổ mã lệnh của Class chứa các dòng sau:

Public Class <tên Class>

End Class

Page 63: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 63/187

Chúng ta có thể khai báo một lớp với cú pháp sau

Cú pháp:

[<Từ khoá>] Class <tên Class>

End Class

Mọi thuộc tính, phương thức hoặc sự kiện của Class được tạo ra phải nằm trong hai dòng lệnh trên.

Từ khóa có thể là một trong các giá trị ở bảng sau:

Các từ khóa khai báo Class

Tên Mô tả

Public Các thực thể khai báo với từ khóa này có thể sử dụng ở mọi nơi.

Private Cho biết thực thể khai báo chỉ được sử dụng trong phạm vi khai báo.

Protected Cho biết thực thể khai báo chỉ được sử dụng trong phạm vi Class và SubClass (lớp và lớp con).

Friend Cho biết thực thể khai báo chỉ được sử dụng trong phạm vi Project. Nếu không có từ khóa, Class mặc nhiên là khai báo Friend.

Protected Friend Cho biết thực thể khai báo có phạm vi sử dụng của Protected và Friend.

Shadows Cho biết lớp này đang che mờ một thành phần trong lớp cơ sở. Thành phần bị che mờ không thể sử dụng trong lớp này.

MustInherit Cho biết các thành phần non-shared của lớp chỉ có thể truy xuất thông qua các lớp kế thừa. Các thể hiện của lớp khai báo kiểu này không thể khởi tạo.

NotInheritable Cho biết lớp này không cho phép kế thừa.

II.2. Tạo một NameSpace mới Trong một tập tin như trên có thể chứa nhiều Class khác nhau.

Chúng ta có thể tổ chức các Class cùng loại, cùng nhóm vào chung một không gian tên (NameSpace) do chúng ta tạo ra.

Ví dụ:

Namespace Dong_vat

Public Class An_co

End Class

Public Class An_thit

End Class

End Namespace

Để tham chiếu đến một Class được khai báo trong Namespace, chúng ta phải thông qua tên Namespace.

Ví dụ:

Private conbo as Dongvat.Anco

Page 64: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 64/187

Một không gian tên có thể xuất hiện trong nhiều tập tin Class khác nhau trong một Project.

Ví dụ ta có tập tin thứ hai với nội dung:

Namespace Dong_vat

Public Class An_tap

End Class

End Namespace

Và cùng có chung cách tham chiếu thông qua không gian tên:

Private conbo as Dongvat.

II.3. Tạo một Class kế thừa Khi tạo một Class kế thừa, chúng ta sẽ có một Class mới kế thừa tất cả các thành phần đã được khai báo với từ khóa Public, Friend và Protected của Class được kế thừa. Cú pháp tạo Class kế thừa như sau:

Cú pháp:

Public Class <tên Class con>

Inherits <tên Class cha>

End Class

Chú ý: Lệnh Inherits phải là dòng đầu tiên sau dòng lệnh khai báo Class.

II.4. Khai báo phương thức (Method) Phương thức là chức năng mà đối tượng có thể thực hiện, nó có thể là một thủ tục (Sub) hoặc một hàm (Function). Với hàm, phải có giá trị trả về.

Cú pháp:

[<từ khóa>] Sub <tên thủ tục>([<các tham số>])

End Sub

Hoặc

[<từ khóa>] Function <tên hàm>([<các tham số>])

Return <giá trị>

End Function

Từ khóa có thể là một trong các giá trị ở bảng sau:

Các từ khóa khai báo phương thức

Tên Mô tả

Public Cho biết phương thức được gọi ở mọi nơi.

Protected Cho biết phương thức chỉ được gọi trong phạm vi của Class khai báo và các lớp

Page 65: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 65/187

Con (Subclass)

Friend Cho biết phương thức chỉ được gọi trong phạm vi của Project

Protected Friend Cho biết phương thức chỉ được gọi trong phạm vi Proctected và Friend

Private Cho biết phương thức chỉ được gọi trong phạm vi của Class

Overloads Cho biết phương thức nạp chồng một hay nhiều phương thức có cùng tên với phương thức trong lớp cơ sở. Danh sách tham số trong phương thức này phải khác với danh sách tham số của mỗi phương thức nạp chồng khác về số lượng, hoặc về các kiểu dữ liệu hoặc cả hai. Chúng ta không cần phải dùng từ khóa Overloads khi tạo các phương thức nạp chồng trong một lớp. Nhưng nếu đã khai báo cho một thì phải khai báo cho tất cả. Không được phép sử dụng cả hai từ khóa Overloads và Shadows trong cùng một phương thức. Ví dụ chúng ta có các lớp Tinh và Toan như sau:

Public Class Tinh

Function BP(ByVal so As Short) As Integer

Return so ^ 2

End Function

Function BP(ByVal so As Integer) As Long

Return so ^ 2

End Function

End Class

Public Class Toan

Inherits Tinh

Overloads Function BP(ByVal so As Double) As Double

Return so ^ 2

End Function

End Class

Các hàm BP trong lớp Tinh có thể có hoặc không có từ OverLoads Một thể hiện của lớp Toan có thể sử dụng tất cả các hàm Overloads

Overrides Cho biết phương thức ghi chồng một phương thức cùng tên của lớp cơ sở. Số lượng tham số, kiểu dữ liệu của tham số cũng như kiểu giá trị trả về phải khớp với của lớp cơ sở.

Overridable Cho biết phương thức này cho phép ghi chồng bằng một phương thức cùng tên trong lớp Con. Phương thức với từ khóa Overrides mặc nhiên là được phép ghi chồng.

NotOverridable Cho biết phương thức không được phép ghi chồng trong lớp Con.

MustOverride Cho biết phương thức không được cài đặt trong lớp khai báo nhưng phải cài đặt trong lớp Con.

Shadows Cho biết phương thức che lấp một thành phần có tên tương tự, hoặc một tập hợp các thành phần nạp chồng của lớp cơ sở. Tham số và giá trị trả về không nhất thiết phải như trong thành phần bị che. Thành phần bị che không còn giá trị trong lớp che nó. Không được phép sử dụng cả hai từ khóa Overloads và Shadows trong cùng

Page 66: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 66/187

một phương thức. Ví dụ: Chúng ta có lớp ClassCha với thuộc tính Cao:

Public Class ClassCha

Private h As Single

Property Cao() As Single

Get

Return h

End Get

Set(ByVal Value As Single)

h = Value

End Set

End Property

End Class

Và lớp ClassCon kế thừa từ lớp ClassCha và che mờ thuộc tính Cao bằng thủ tục Cao như sau:

Public Class ClassCon

Inherits ClassCha

Public Shadows Sub Cao()

MessageBox.Show("Tôi sẽ còn cao hơn nữa", _

"Class Con")

End Sub

End Class

Shared

Cho biết phương thức được dùng chung - nghĩa là phương thức này không liên kết với một thể hiện nào của lớp. Chúng ta có thể gọi phương thức dùng chung thông qua tên của lớp hoặc tên biến của một thể hiện cụ thể. Ví dụ chúng ta có lớp TEST với một hàm Shared như sau:

Class TEST

Shared Function Cong(ByVal a As Integer, _

ByVal b As Integer) As Integer

Return a + b

End Function

End Class

Khi sử dụng, chúng ta có thể viết:

Dim y As TEST

Console.WriteLine(y.Cong(12, 9))

hoặc:

Console.WriteLine(TEST.Cong(12, 9))

Page 67: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 67/187

II.5. Khai báo thuộc tính (Property) Thuộc tính là thành phần lưu giữ các tính chất, đặc điểm của đối tượng. Ứng với mỗi thuộc tính, chúng ta cần khai báo một biến Private tương ứng để lưu giữ giá trị. Trong VB.NET, chúng ta dùng một cú pháp chung cho truy xuất và gán trị của thuộc tính như sau:

Cú pháp:

' Khai báo biến lưu giữ giá trị của thuộc tính

Private mthuoctinh As <Kiểu dữ liệu>

[<Từ khoá>] Property Thuoc_tinh() As <Kiểu dữ liệu>

' Truy xuất giá trị của thuộc tính tức truy xuất đến giá trị của biến

Get

Return mthuoctinh

End Get

' Gán trị cho thuộc tính tức gán trị cho biến

Set (ByVal Value As <Kiểu dữ liệu>)

mthuoctinh = Value

End Set

End Property

Chúng ta có thể sử dụng các từ khai báo sau:

II.5.1. Default

Khai báo thuộc tính mặc định. Các thuộc tính này phải có tham số và có thể gán và truy xuất không cần chỉ ra tên thuộc tính.

Một thuộc tính chỉ có thể là thuộc tính mặc định nếu thỏa các điều kiện:

Mỗi Class chỉ được có một thuộc tính mặc định, phải kể đến cả các thuộc tính kế thừa.

Thuộc tính mặc định không được là Shared hay Private

Nếu một thuộc tính nạp chồng (Overloaded) là mặc định thì tất cả các thuộc tính cùng tên cũng phải khai báo mặc định.

Thuộc tính mặc định phải có ít nhất một tham số

Cú pháp:

Private mthuoctinh As <Kiểu dữ liệu>

Default Public Property Thuoc_tinh(Index as Integer) As <Kiểu dữ liệu>

Get

Return mthuoctinh

End Get

Set (ByVal Value As <Kiểu dữ liệu>)

mthuoctinh = Value

End Set

Page 68: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 68/187

End Property

II.5.2. ReadOnly

Cho biết thuộc tính chỉ được phép đọc không cho phép gán.

Cú pháp:

Private mthuoctinh As <Kiểu dữ liệu>

Public ReadOnly Property Thuoc_tinh() As <Kiểu dữ liệu>

Get

Return mthuoctinh

End Get

End Property

II.5.3. WriteOnly

Cho biết thuộc tính chỉ được phép gán không cho phép đọc.

Cú pháp:

Private mthuoctinh As <Kiểu dữ liệu>

Public WriteOnly Property Thuoctinh() As String

Set (ByVal Value As String)

mthuoctinh = Value

End Set

End Property

II.5.4. Overloads

Cho biết thuộc tính này nạp chồng một hoặc nhiều thuộc tính có cùng tên được định nghĩa trên lớp cơ sở. Danh sách tham số trong thuộc tính này phải khác với danh sách tham số của mỗi thuộc tính nạp chồng khác về số lượng, hoặc về các kiểu dữ liệu hoặc cả hai.

Chúng ta không cần phải dùng từ khóa Overloads khi tạo các thuộc tính nạp chồng trong một lớp. Nhưng nếu đã khai báo cho một thì phải khai báo cho tất cả.

Không được phép sử dụng cả hai từ khóa sau một lượt: Overloads và Shadows trong cùng một thuộc tính.

II.5.5. Overrides

Cho biết thuộc tính ghi chồng một thuộc tính cùng tên của lớp cơ sở. Số lượng tham số, kiểu dữ liệu của tham số cũng như kiểu giá trị trả về phải khớp với của lớp cơ sở.

II.5.6. Overridable

Cho biết thuộc tính này được phép ghi chồng trong lớp Con.

II.5.7. NotOverridable

Cho biết thuộc tính không được phép ghi chồng trong lớp Con. Mặc nhiên, các thuộc tính là không được phép ghi chồng.

Page 69: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 69/187

II.5.8. MustOverride

Cho biết thuộc tính không được cài đặt trong lớp và phải được cài đặt ở lớp Con.

II.5.9. Shadows

Cho biết thuộc tính che lấp một thuộc tính có tên tương tự, hoặc một tập hợp các thuộc tính Nạp chồng của lớp cơ sở. Tham số và giá trị trả về không nhất thiết phải như trong thuộc tính bị che. Thuộc tính bị che không còn giá trị trong lớp che nó.

II.5.10. Shared

Cho biết thuộc tính được chia sẻ - nghĩa là thuộc tính không gắn chặt với một thể hiện nào của lớp nhưng được sử dụng chung giữa các thể hiện của một lớp.

II.6. Khai báo sự kiện (Event) Sự kiện là thông điệp do một đối tượng phát sinh cho biết một hành động đang xảy ra. Hành động có thể do sự tương tác của người dùng, do chương trình khác kích hoạt…Đối tượng kích hoạt biến cố được gọi là đối tượng gửi biến cố. Đối tượng bắt sự kiện và đáp ứng lại gọi là đối tượng nhận sự kiện. Đối tượng gửi không biết đối tượng nhận sự kiện do nó kích hoạt, nhưng giữa đối tượng gửi và đối tượng nhận có một đối tượng trung gian. Trong .NET Framework có một kiểu đặc biệt thích hợp cho chức năng của vai trò trung gian này là Delegate (ủy quyền).

Chức năng của sự kiện được xác định từ ba yếu tố liên quan: một đối tượng cung cấp dữ liệu sự kiện (event data), một event delegate và một đối tượng kích hoạt sự kiện (sender). .NET Framework có một qui ước về việc đặt tên các lớp và các phương thức liên quan đến sự kiện như sau:

II.6.1. Phát sinh sự kiện

Để một class phát sinh sự kiện EventName cần có các yếu tố sau:

Một tham số sự kiện chứa các dữ liệu có tên EventNameEventArgs phát sinh từ lớp System.EventArgs

Một thành phần xử lý sự kiện có tên EventNameEventHandler. Đây là một thủ tục sẽ được gọi khi sự kiện xảy ra. Chúng ta có thể sử dụng bất kỳ thủ tục hợp lệ nào làm thành phần xử lý sự kiện nhưng không được là một hàm.

Một đối tượng phát sinh sự kiện. Đối tượng này phải cung cấp :

Một khai báo sự kiện

[<Từ khoá>] Event EventName As EventNameEventHandler

Một phương thức tên OnEventName phát sinh sự kiện

Các đối tượng event delegate và đối tượng dữ liệu sự kiện (EventArgs) có thể phát sinh từ những lớp tương ứng có sẵn trong .NET.

Các từ khoá khai báo sự kiện có thể là:

Các từ khóa khai báo sự kiện

Tên Mô tả

Public Sử dụng được ở mọi nơi. Sự kiện không có từ khóa mặc nhiên là Public.

Private Chỉ truy xuất trong phạm vi khai báo.

Protected Chỉ truy xuất trong phạm vi Class và SubClass.

Page 70: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 70/187

Friend Chỉ truy xuất trong phạm vi Project.

Protected Friend Chỉ truy xuất trong phạm vi của Protected và Friend

Shadows Cho biết sự kiện che mờ một thành phần có tên tương tự trong lớp cơ sở. Chúng ta có thể che mờ một thành phần loại này bằng một thành phần loại khác. Thành phần bị che mờ sẽ không còn tác dụng trong lớp kế thừa che mờ nó.

Các sự kiện trong VB.NET không hỗ trợ đúng nguyên tắc kế thừa. Một sự kiện khai báo trong Class nào chỉ được phép gọi phát sinh sự kiện (RaiseEvent) chỉ trong lớp đó mà thôi, không được gọi phát sinh kể cả trong các lớp kế thừa.

Cú pháp để gọi phát sinh sự kiện như sau

Cú pháp:

RaiseEvent <tên sự kiện>()

Ví dụ chúng ta có lớp Con_Nguoi và thuộc tính Chieu_Cao, khi chiều cao thay đổi sẽ phát sinh sự kiện Chieu_Cao_Thay_doi như sau

Ví dụ:

Public Class Con_Nguoi

Private Cao As Single

Public Event Chieu_Cao_Thay_doi()

Public Property Chieu_Cao() As Single

Get

Return Cao

End Get

Set(ByVal Value As Single)

Cao = Value

RaiseEvent Chieu_Cao_Thay_doi()

End Set

End Property

End Class

Để sử dụng các sự kiện trên một biến, chúng ta sử dụng cú pháp sau khi khai báo biến:

Private WithEvents <tên biến> As <tên Class>

II.6.2. Kết hợp sự kiện với xử lý sự kiện

Chúng ta kết hợp sự kiện với xử lý sự kiện bằng các lệnh: Handles hoặc AddHandler.

Từ khóa WithEvents và Handles cung cấp cách khai báo các xử lý sự kiện. Các sự kiện do một đối tượng phát sinh với từ khóa WithEvents có thể được xử lý bằng bất kỳ thủ tục nào được chỉ ra trong mệnh đề Handles của sự kiện. Tuy mệnh đề Handles là cách thức chuẩn để kết hợp một sự kiện với một xử lý sự kiện, nhưng lại giới hạn số các biến cố kết hợp với cùng xử lý sự kiện khi biên dịch.

Các lệnh AddHandler và RemoveHandler uyển chuyển hơn trong việc kết hợp sự kiện với xử lý sự kiện. Chúng cho phép chúng ta linh hoạt kết hợp và ngắt rời các sự kiện với các xử lý sự kiện lúc thực thi và

Page 71: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 71/187

chúng không đòi hỏi chúng ta phải khai báo biến với từ khóa WithEvents.

Với các sự kiện kết hợp với các form, control, Visual Basic .NET tự động phát sinh một xử lý sự kiện rỗng và kết hợp với sự kiện.

Ví dụ khi chúng ta nhấp đúp vào một nút lệnh trên màn hình ở chế độ thiết kế, Visual Basic .NET tạo một xử lý sự kiện kết hợp với sự kiện Click của nút lệnh như sau:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As _

System.EventArgs) Handles Button1.Click

End Sub

Hoặc chúng ta kết hợp các biến cố Click của các nút lệnh Button1, Button2 cho cùng một xử lý sự kiện như sau:

AddHandler Button1.Click, AddressOf Nhannut

AddHandler Button2.Click, AddressOf Nhannut

Private Sub Nhannut(ByVal sender As _

System.Object, ByVal e As System.EventArgs)

End Sub

II.7. Từ khóa Me, Mybase, MyClass

II.7.1. Me

Từ khóa Me được dùng khi chúng ta chỉ rõ muốn dùng các thành phần của chính thể hiện Class nơi viết lệnh chứ không phải thành phần nào khác.

Ví dụ:

Public Class Con_nguoi

Private ten as String

Public Sub Lam_viec()

Dim ten as String

' biến cục bộ của Sub được sử dụng

ten = "Hùng"

' biến cấp Class được dùng

Me.ten = "Hùng"

End Sub

End Class

II.7.2. Mybase

Từ khóa Mybase được dùng trong Class kế thừa, khi chúng ta muốn dùng các phương thức của chính Class cơ sở.

Ví dụ:

Lớp lopCha với thủ tục Gioi_thieu và tạo tiếp Class lopCon kế thừa từ lopCha

Page 72: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 72/187

Public Class lopCha

Public Overridable Sub Gioi_thieu()

MessageBox.Show(“Tôi là thể hiện của lopCha”)

End Sub

End Class

Public Class lopCon

Inherits lopCha

Public Overrides Sub Gioi_thieu()

MessageBox.Show("Tôi là thể hiện của lopCon")

Mybase.Gioi_thieu()

End Sub

End Class

Khi gọi phương thức Gioi_thieu của lopCon, chúng ta sẽ có hai thông báo: một của chính lopCon và một của lopCha

Chú ý: Từ khóa Mybase

Chỉ được dùng để tham chiếu đến Class trung gian và các thành phần được kế thừa của nó.

Không phải là một đối tượng, nên thông thể gán trị, dùng làm tham số hoặc dùng trong toán tử Is

Không được sử dụng trong các Standard Module.

II.7.3. MyClass

Từ khóa MyClass cho phép chúng ta gọi các phương thức Overridable của Class, dẫu các Class kế thừa đã có các phương thức Overrides tương ứng.

Ví dụ:

Lớp lopCha với thủ tục Gioi_thieu và tạo tiếp Class lopCon kế thừa từ lopCha

Public Class lopCha

Public Sub Chao()

Gioithieu()

End Sub

Public Overridable Sub Gioi_thieu()

MessageBox.Show("Tôi là thể hiện của lopCha")

End Sub

End Class

Và một Class lopCon kế thừa từ lopCha có thủ tục Gioithieu ghi đè, và kế thừa thủ tục Chao của lopCha

Public Class lopCon

Inherits lopCha

Public Overrides Sub Gioi_thieu()

MessageBox.Show(“Tôi là thể hiện của lopCon”)

End Sub

Page 73: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 73/187

End Class

Với đoạn lệnh sau:

Dim a as New lopCon()

a.Chao() ‘ Tôi là thể hiện của lopCon

Nhưng nếu thủ tục Chao của lopCha như sau:

Public Sub Chao()

MyClass.Gioi_thieu()

End Sub

Thì :

a.Chao() ' Tôi là thể hiện của lopCha

II.8. Khởi tạo thể hiện Để tạo đối tượng cho một Class, trình biên dịch gọi một hàm đặc biệt được gọi là bộ khởi tạo (Constructor). Chúng ta có thể định nghĩa bộ khởi tạo trong Class. Nhưng nếu chúng ta không định nghĩa, VB sẽ sử dụng bộ khởi tạo mặc định. Để định nghĩa bộ khởi tạo, chúng ta chỉ cần định nghĩa một thủ tục New bên trong Class. Do tính chất nạp chồng (Overloading), nên Class có thể định nghĩa nhiều bộ khởi tạo.

II.9. Abstract Base Class

II.9.1. Từ khoá MustInherit

Khi chúng ta muốn tạo một lớp chỉ dùng để thừa kế, phải khai báo với từ khóa MustInherit.

Lớp này không cho phép khởi tạo thể hiện, nhưng phải tạo lớp con kế thừa từ lớp này và khởi tạo thể hiện từ lớp kế thừa:

Cú pháp:

Public MustInherit Class <tên lớp>

II.9.2. Từ khoá MustOverride

Tương tự với ý niệm MustInherit trong Class, ta cũng có từ khóa MustOverride cho một phương thức. Trong lớp cơ sở ta khai báo một phương thức, nhưng yêu cầu phải được cài đặt trong lớp kế thừa, ta sẽ khai báo phương thức đó như sau:

Cú pháp:

MustOverride Sub <tên thủ tục>

Thủ tục này không được có gì khác ngoài dòng khai báo. Thủ tục này được gọi là abstract method hay pure virtual function, vì nó chỉ có phần khai báo không có phần định nghĩa. Trong các lớp kế thừa, các thủ tục này buộc phải được cài đặt (Override) để sử dụng.

Kết hợp hai ý niệm MustInherit và MustOverride, chúng ta sẽ có Abstract Base Class. Đây là một Class chỉ có khai báo không có phần cài đặt. Muốn dùng phải tạo class kế thừa, từ đó mới sử dụng được.

Ví dụ:

Page 74: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 74/187

Public MustInherit Class Con_nguoi

Public MustOverride Sub Chao()

Public MustOverride Sub Hoi_tham()

End Class

Lớp Abstract Base Class rất thích hợp để chúng ta tạo cái sườn hay bố cục của chương trình trong lúc thiết kế. Tất cả những lớp kế thừa lớp Abstract Base Class đều phải cài đặt các thành phần đã khai báo trong Abstract Base Class:

Ví dụ:

Public Class Nguoi_Viet

Inherits Con_nguoi

Public Override Sub Chao()

End Sub

Public Override Sub Hoi_tham()

End Sub

End Class

II.10. Giao tiếp (Interface) Tương tự Abstract Base Class, Interface có thể khai báo tập hợp các thuộc tính, phương thức và sự kiện, nhưng không có phần cài đặt chúng (Implementation). Các lớp tiếp nhận Interface đều phải cài cặt các thành phần của Interface như đã khai báo.

Chúng ta có cú pháp sau để khai báo Interface:

Cú pháp:

[<Từ khóa>] Interface <tên gọi>

[ Inherits <tên interface1>[,<ten interface2>]]

[ [ Default ] Property <thuộc tính> ]

[ Function <tên hàm>]

[ Sub <tên thủ tục>]

[ Event <tên sự kiện>]

End Interface

Các từ khóa có thể là Public, Friend, Protected, Protected Friend hoặc Private

Ví dụ:

Public Interface IChaohoi

Sub Chao()

Sub Hoi_tham()

End Interface

Class nào tiếp nhận giao tiếp IChaohoi đều phải định nghĩa thủ tục Chao và Hoi_tham.

Page 75: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 75/187

Public Class Nguoi_Phap

Implements IChaohoi

Public Sub Chao() Implements IChaohoi.Chao

End Sub

Public Sub Hoi_tham() As String Implements IChaohoi.Hoi_tham

End Sub

End Class

Một số yếu tố sau đây giúp xác định sử dụng Abstract Base Class hay Interface:

Nếu Class tạo ra, sẽ được kế thừa nhiều tầng sau đó, thì Abstract Class là giải pháp thích hợp. Vì trong trường hợp này, nếu nâng cấp lớp cơ sở (base class), toàn bộ các lớp kế thừa từ nó sẽ được tự động nâng cấp theo. Ngược lại, Interface không cho phép thay đổi sau khi đã tạo ra. Nếu có yêu cầu thay đổi, chúng ta buộc phải tạo Interface mới hoàn toàn.

Nếu muốn chức năng tạo ra sẽ áp dụng cho nhiều nhóm đối tượng (Class) khác nhau, Interface là thích hợp. Abstract Class chỉ áp dụng được cho một nhóm đối tượng liên quan mật thiết nhau, trong khi Interface là cách thức thích hợp nhất cho các Class không có gì liên quan nhau.

Để thiết kế một số ít chức năng nhỏ, ngắn gọn, sử dụng Interface. Nếu thiết kế một bộ các chức năng lớn, sử dụng Abstract Class.

Nếu muốn cung cấp một số chức năng đã được cài đặt sẵn cho các đối tượng, sử dụng Abstract Class, vì nó cho phép cài đặt sẵn trong Abstract Class trong khi Interface không cho phép cài đặt sẵn trên bất kỳ thành phần nào của nó.

II.11. Lớp lồng ghép Cài đặt lớp lồng ghép (có-một) là tạo và sử dụng các đối tượng trong một lớp nhưng không muốn cho bên ngoài truy cập và sử dụng. Trở lại với ví dụ lớp Xe hơi có một Tay lái, nếu trong ứng dụng không cần thiết phải có lớp Tay lái, chúng ta có thể xây dựng lớp Xe hơi có lồng ghép lớp Tay lái. Thông thường, những trường hợp này lớp lồng ghép được khai báo là Private. Tuy nhiên các lớp lồng ghép cũng khiến cho việc sử dụng và bảo trì thêm phần phức tạp. Dưới đây là một vài yếu tố giúp chúng ta quyết định việc sử dụng lớp lồng ghép:

Nếu lớp đó không hề có ý nghĩa gì bên ngoài lớp chứa nó. Ví dụ Tay lái chỉ có ý nghĩa với Xe hơi chứ không hề được quan tâm tại nơi nào khác trong ứng dụng.

Nếu các thành phần của lớp có nhu cầu truy xuất các thành phần khai báo Private của lớp chứa nó.

Ví dụ:

Public Class Xehoi

Private tlai As New Taylai()

Enum Huonglai

trai = -1

phai = 1

thang = 0

End Enum

Private Class Taylai

Sub Retrai()

Page 76: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 76/187

MsgBox("Xe tu tu re trai")

End Sub

Sub Rephai()

MsgBox("Xe tu tu re phai")

End Sub

Sub Dithang()

MsgBox("Xe tiep tuc di thang")

End Sub

End Class

Sub Laixe(ByVal huong As Huonglai)

Select Case huong

Case Huonglai.trai

tlai.Retrai()

Case Huonglai.thang

tlai.Dithang()

Case Huonglai.phai

tlai.Rephai()

End Select

End Sub

End Class

II.12. Từ khóa Delegate Từ khóa này được dùng để khai báo một thẻ ủy quyền. Đây là một đối tượng kiểu tham chiếu trỏ đến một phương thức khác trong ứng dụng.

Cú pháp:

[ Public | Private | Protected | Friend | Protected Friend ] _

[ Shadows ] Delegate Sub <tên thủ tục>([<các tham số>])

hoặc

[ Public | Private | Protected | Friend | Protected Friend ] _

[ Shadows ] Delegate Function <tên hàm> ([<các tham số>]) As _

<kiểu dữ liệu>

Lệnh Delegate định nghĩa các kiểu tham số và kiểu giá trị trả về của một lớp ủy quyền. Bất kỳ phương thức nào có kiểu các tham số và kiểu trị trả về phù hợp đều có thể là một thể hiện của lớp ủy quyền đó. Thủ tục sẽ được gọi thực hiện bằng cách gọi phương thức Invoke của lớp ủy quyền.

Mỗi lớp ủy quyền định nghĩa một bộ khởi tạo có tham số là một phương thức. Cách truyền thủ tục như một tham số cho phương thức theo cú pháp:

Cú pháp:

AddressOf <tên phương thức>

Ví dụ:

Page 77: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 77/187

Chúng ta có:

Một khai báo ủy quyền

Delegate Function Lon_Hon(ByVal so1 as Integer, ByVal so2 as Integer) as Integer

Một hàm cài đặt như sau:

Function Lay_so_lon(ByVal so1 As Integer, ByVal so2 As Integer) As Integer

Return IIf(so1 > so2, so1, so2)

End Function

Và hàm tìm số lớn nhất trong các số truyền vào như sau:

Function Lon_Nhat(ByRef Cacso() As Integer, ByVal sosanh As Lon_Hon) As Integer

Dim i As Integer

Dim soMax As Integer = Cacso(0)

For i = 1 To Cacso.GetUpperBound(0)

soMax = sosanh(Cacso(i), soMax)

Next

Return soMax

End Function

Và đoạn lệnh khi sử dụng:

Dim a() As Integer = New Integer() {107, 15, 9, 20, 34, 6, 100, 99, 10}

Console.Write("Số lớn nhất trong mảng là:" (0), _

Lon_Nhat(a, AddressOf Lay_so_lon))

Page 78: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 78/187

Bài 4

TỔNG QUAN VỀ ADO.NET

Tóm tắt Lý thuyết 1 tiết

Mục tiêu Các mục chính Bài tập

Bài học này sẽ cung cấp cho học viên các kiến thức cơ bản và giới thiệu các đối tượng trong ADO.NET.

1. Tổng quan

2. Kiến trúc ADO.NET

3. Các đặc điểm của ADO .Net

4. Content Component

5. Managed Provider Component

Page 79: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 79/187

I. Tổng quan Hầu như bất kỳ ứng dụng nào cũng cần đến dữ liệu. Dữ liệu từ người dùng nhập vào, dữ liệu được lưu trữ trong ứng dụng và dữ liệu từ các hệ thống khác,… tất cả đều là nguồn thông tin mà ứng dụng cần xử lý với chức năng chính là hỗ trợ tìm kiếm, tính toán, thống kê và ra quyết định.

Để thực hiện các chức năng xử lý dữ liệu, người lập trình cần phải có các công cụ lập trình chuyên dùng. Dữ liệu không đơn giản lưu trên các file văn bản hay file nhị phân với cấu trúc record do người lập trình định nghĩa. Thay vào đó, hầu hết các ứng dụng tổ chức dữ liệu logic dựa trên cấu trúc cơ sở dữ liệu quan hệ và lưu trữ vật lý dữ liệu dựa vào các hệ quản trị cơ sở dữ liệu quan hệ như Access, SQL Server, Oracle, DB2,…

Khi dữ liệu trở thành trung tâm của ứng dụng thì việc cung cấp các chức năng tới người dùng phụ thuộc vào khả năng xử lý và thao tác với dữ liệu. Vấn đề mà người thiết kế và xây dựng ứng dụng quan tâm khi làm việc với dữ liệu là:

Lưu trữ dữ liệu tập trung

Đảm bảo toàn vẹn dữ liệu

Đảm bảo khả năng truy xuất đồng thời của nhiều người dùng trên dữ liệu

Đảm bảo thời gian hồi đáp ngắn cho mỗi người dùng

Bảo mật dữ liệu

Trao đổi dữ liệu giữa các hệ thống khác nhau

Những vấn đề này được giải quyết nhờ vào khả năng của các hệ quản trị cơ sở dữ liệu (HQT CSDL) và cách phần mềm xử lý dữ liệu do hệ quản trị dữ liệu cung cấp. Với các database server sử dụng HQT CSDL như Oracle, SQL Server,… dữ liệu được đảm bảo lưu trữ tập trung, toàn vẹn và truy xuất đồng thời cũng như bảo mật. Tuy nhiên, thời gian hồi đáp người dùng và trao đổi dữ liệu phụ thuộc hoàn toàn vào các phần mềm. Với các công cụ lập trình xử lý dữ liệu như ADO (Active Data Object), Microsoft đem lại cho người lập trình một công cụ rất tự nhiên khi thực hiện các thao tác trên dữ liệu. ADO được cải tiến liên tục trong các phiên bản hệ điều hành Windows hay MS Office. Tuy nhiên, với sự ra đời của .NET, ADO không còn là thành phần Component độc lập nhưng gắn liền với .NET Framework để cung cấp các dịch vụ xử lý dữ liệu.

ADO.NET có nhiều đổi mới so với ADO nhằm hướng tới người dùng nhiều hơn là người lập trình. Cấu trúc mới của ADO.NET hơi gượng ép với người lập trình khi làm việc với dữ liệu nhưng lại nhằm cung cấp khả năng truy xuất và xử lý dữ liệu lớn, đồng thời trên hệ thống ứng dụng phân tán nhiều người dùng.

Đặc điểm chính của ADO.NET là làm việc với dữ liệu không kết nối. Dữ liệu được lưu trữ trong bộ nhớ như một CSDL thu nhỏ gọi là DataSet, nhằm tăng tốc độ tính toán, xử lý tối đa và hạn chế việc sử dụng tài nguyên trên Database Server. Đặc điểm quan trọng thứ hai là khả năng xử lý dữ liệu dạng chuẩn XML. Dữ liệu ở dạng XML có thể trao đổi giữa bất kỳ hệ thống nào nên ứng dụng của bạn sẽ có nhiều khả năng làm việc với nhiều ứng dụng khác.

Sau dây, chúng ta sẽ xem xét phần tổng quan kiến trúc của ADO.NET cùng với các kỹ thuật lập trình cơ bản.

Page 80: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 80/187

II. Kiến trúc ADO .Net

Kiến trúc ADO.NET có thể chia làm 2 phần chính:

Managed Provider Component: bao gồm các đối tượng như DataAdapter, DataReader,… giữ nhiệm vụ làm việc trực tiếp với dữ liệu như database, file,…

Content Component: bao gồm các đối tượng như DataSet, DataTable,… đại diện cho dữ liệu thực sự cần làm việc. DataReader là đối tượng mới, giúp truy cập dữ liệu nhanh chóng nhưng forward-only và read-only giống như ADO RecordSet sử dụng Server cursor, OpenFowardOnly và LockReadOnly. DataSet cũng là một đối tượng mới, không chỉ là dữ liệu, DataSet có thể coi là một bản sao gọn nhẹ của CSDL trong bộ nhớ với nhiều bảng và các mối quan hệ. DataAdapter là đối tượng kết nối giữa DataSet và CSDL, nó bao gồm 2 đối tượng Connection và Command để cung cấp dữ liệu cho DataSet cũng như cập nhật dữ liệu từ DataSet xuống CSDL.

Trong ví dụ sau, chúng ta sẽ sử dụng điều khiển DataGrid để hiển thị dữ liệu từ bảng DMCV trong C:\QL_NHAN_SU\CSDL\Qlns.mdb.

Ví dụ:

Chúng ta có:

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As _

System.EventArgs) Handles MyBase.Load

Dim Ket_noi As New System.Data.OleDb.OleDbConnection("Provider= " & _

Page 81: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 81/187

"Microsoft.Jet.OLEDB.4.0; Data Source=" & Application.StartupPath _

& "\..\CSDL\Qlns.mdb")

Dim bo_doc_ghi As New System.Data.OleDb.OleDbDataAdapter _

("Select * From DMCV", Ket_noi)

Dim ds As New DataSet

Bo_doc_ghi.Fill(ds, "CONG_VIEC")

Luoi_cong_viec.DataSource = ds.Tables("CONG_VIEC")

End Sub

Với đoạn lệnh trên, chúng ta thấy cách lập trình của ADO.NET tương đối giống với ADODB thông thường, đó là trước tiên cần kết nối với CSDL bằng một đối tượng Connection. Dữ liệu sẽ được quản lý bởi một đối tượng, đó là DataSet như bạn thấy trong sơ đồ cấu trúc của ADO.NET.

Cũng trong sơ đồ này, bạn thấy rằng một DataAdapter có một Connection và nhiều đối tượng Command. Trong ví dụ của chúng ta bạn thấy rõ điều này: bo_doc_ghi được tạo mới với một connection là Ket_noi và một Select Command.

Đối tượng DataSet không làm việc trực tiếp với CSDL mà thông qua DataAdapter. Do đó, để DataSet có dữ liệu, bạn phải dùng phương thức Fill của bo_doc_ghi lấy dữ liệu từ Qlns.mdb thông qua connection Ket_noi đổ vào một bảng trong DataSet ds. Cuối cùng, để hiển thị dữ liệu chúng ta thực hiện việc liên kết điều khiển với nguồn dữ liệu (Binding): kết nối Luoi_cong_viec với bảng "CONG_VIEC" trong ds.

III. Các đặc điểm của ADO.Net ADO.NET có nhiều thay đổi so với ADO trước đây dù vẫn giữ lại kiến trúc các đối tượng độc lập với nhau và cố gắng không thay đổi cách thức các lập trình viên đã sử dụng quen thuộc với ADO. ADO.NET có nhiều đặc điểm mới, nổi bật:

Interoperability

Scalability

Productivity

Performance

III.1. Interoperability – Tương tác giữa nhiều hệ thống khác nhau Trong các hệ thống phân tán, dữ liệu được chuyển ở dạng disconnected recordset giữa Data provider và Data consumer. Vì ở dạng RecordSet, cả provider và consumer cần phải sử dụng COM để trao đổi dữ liệu dẫn đến việc khó mở rộng hệ thống vì COM không làm việc qua Firewall và Network Address Translator (NAT).

ADO.NET giải quyết vấn đề này bằng cách thay đổi về bản chất của việc đóng gói dữ liệu trước khi truyền trên mạng:

Với ADO, Disconnected RecordSet được đóng gói ở dạng Network Data Representation (NDR) trước khi truyền trên mạng. NDR vẫn là dạng đối tượng mà ở tầng Application, data provider và data consumer phải sử dụng kỹ thuật COM để xử lý.

ADO.NET thay thế NDR bằng định dạng mới: XML. Với bản chất Text, XML hoàn toàn có thể sử dụng HTTP để trao đổi dữ liệu. Hơn nữa XML document dễ dàng được xử lý mà không cần đến kỹ thuật COM. XML là chuẩn để trao đổi dữ liệu mới nhất và đang được hỗ trợ rất rộng rãi.

Page 82: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 82/187

III.2. Scalability - Hỗ trợ nhiều người dùng ADO làm việc trên mô hình Client/Server, Client sẽ kết nối liên tục với Server trong suốt quá trình làm việc. Điều này làm cho Server trở nên Nạp chồng khi có quá nhiều Client kết nối.

ADO.NET sử dụng dữ liệu ở dạng disconnected data:

Client tạo kết nối với Server để lấy dữ liệu

Server gửi dữ liệu về cho Client

Client ngắt kết nối với Server

Khi cần cập nhật dữ liệu, kết nối giữa Client và Server được phục hồi

Với cơ chế disconnected data, thời gian kết nối giữa Client và Server không còn lâu dài như trước, Server có khả năng phục vụ nhiều Client hơn hẳn so với cơ chế của ADO trước đây.

Cơ chế disconnected data có hai điểm đáng chú ý:

Dữ liệu sẽ không phản ánh kịp thời những thay đổi dữ liệu trong một hệ thống Client/Server với nhiều người dùng?

Trên thực tế, người dùng khi làm việc với các hệ thống phân tán hiểu và chấp nhận dữ liệu có một độ trễ và sai lệch nhỏ, không đáng kể (tương tự như các ứng dụng Web).

ADO trước đây nếu sử dụng RecordSet ở dạng OpenStatic thì cũng không tốt hơn cơ chế disconnected data là bao.

Thời gian cho một lần tạo kết nối giữa Client và Server là khá lớn, việc ngắt kết nối sau đó tạo lại kết nối để cập nhật dữ liệu sẽ chậm?

Vấn đề này được ADO.NET giải quyết khá đơn giản bằng cơ chế connection pooling, thông tin về mối kết nối vẫn còn được lưu giữ ở Server trong khoảng thời gian nhất định và khi Server còn đủ tài nguyên, mỗi khi Client cần kết nối lại với Server, thông tin kết nối được lấy ra từ connection pool nên tốc độ không bị ảnh hưởng.

III.3. Productivity - Mở rộng khả năng làm việc với CSDL ADO.NET vẫn giữ nguyên hướng tiếp cận cũ của ADO nên người lập trình sẽ không mất nhiều thời gian để học cách sử dụng. ADO.NET vẫn giữ kiến trúc các đối tượng độc lập và về mặt ý nghĩa nói chung, các đối tượng trong ADO.NET và ADO cũng gần giống nhau, vẫn có Connection, Command và đối tượng đại diện cho dữ liệu cần xử lý. Điểm mạnh hơn của ADO.NET là DataSet tích hợp vào trong nó nhiều chức năng hơn hẳn những gì mà RecordSet làm được.

Với ADO.NET, có sự tập trung rõ ràng hơn về các chức năng của các đối tượng. Ví dụ, Connection không còn lo việc thi hành một câu lệnh SQL hay một Stored Procedure nữa, công việc này được giao hoàn toàn cho Command đảm nhận.

Đáng chú ý hơn, ADO.NET phát triển trên .NET là component có thể kế thừa được. Người lập trình hoàn toàn có khả năng kế thừa các đối tượng của ADO.NET để xây dựng các đối tượng mới tốt hơn và phù hợp với nhu cầu phát triển ứng dụng của mình.

Cuối cùng, Visual Studio .NET với Component Designer giúp người lập trình tạo ra các DataSet nhanh chóng với nội dung lệnh rõ ràng hơn những gì Data Form Wizard của Visual Studio 6 trước đây tạo ra.

III.4. Performance - Hiệu quả cao trong xử lý dữ liệu Với các thay đổi trong bản chất cơ chế thực hiện, hiệu quả của ứng dụng dùng ADO.NET sẽ cao hơn nhiều.

Page 83: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 83/187

Disconnected data đảm bảo ứng dụng trên Client ít gặp lỗi khi xử lý dữ liệu đồng thời giúp mở rộng ứng dụng tới nhiều người dùng hơn. Các managed provider component hỗ trợ tính năng thiết lập connection pooling ngầm định để giảm bớt thời gian tái kết nối.

Định dạng XML thay thế cho NDR trong trao đổi dữ liệu giữa Server và Client giúp cho dữ liệu có thể được xử lý bởi nhiều client hơn dù ứng dụng trên Client có hay không sử dụng COM. XML cũng giúp việc truyền thông nhanh hơn vì không cần đóng gói phức tạp như NDR hay chuyển qua chuyển lại giữa dữ liệu thô sang dữ liệu ở dạng đối tượng.

IV. Content Component Content component là các đối tượng đại diện cho dữ liệu cần xử lý. Trong ADO, RecordSet là content component. Dữ liệu trong RecordSet ở dạng bảng, bao gồm các Row và Column. Trong ADO.NET, dữ liệu được đại diện bởi DataSet nhưng dưới hình ảnh của một CSDL thu gọn, có nhiều table và các mối quan hệ. Các class chính giúp tạo nên content component bao gồm:

DataSet

DataTable

DataView

DataRow

DataColumn

DataRelation.

Content Component

IV.1. DataSet Với ADO, dữ liệu chứa trong RecordSet cho dù chúng được lấy từ một hay nhiều bảng. Vì ADO không có cách nào mô tả mối quan hệ giữa các bảng trong CSDL với nhau, cách duy nhất để lấy dữ liệu từ nhiều bảng là viết các câu truy vấn SQL kết giữa các bảng với nhau.

ADO.NET chứa dữ liệu trong DataSet cùng với mối quan hệ giữa các dữ liệu đó. DataSet giống như một hình ảnh về CSDL trong bộ nhớ, có thể có nhiều DataTable và các mối quan hệ giữa chúng đại diện bởi

DataSet

DataTableCollection

DataRelationCollection

DataTable

DataRowCollection

DataColumnCollection

«DataRow

DataColumn

DataView

DataRelation

Page 84: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 84/187

các DataRelation.

Vì DataSet dùng cơ chế disconnected data, cần có chức năng giúp kiểm soát các thay đổi về dữ liệu đã xảy ra và cập nhật những thay đổi đó xuống CSDL. Các chức năng được thực hiện qua các phương thức:

HasChanges()

HasErrors()

GetChanges()

AcceptChanges()

RejectChanges()

Người lập trình có thể sử dụng các phương thức (hoặc hàm) này để kiểm tra sự thay đổi trên DataSet, tập hợp những thay đổi đó vào một DataSet khác, tìm các lỗi và sau đó chấp nhận cập nhật hay bỏ qua những thay đổi.

Sơ đồ đối tượng trên đây minh hoạ các đối tượng trong tập hợp Content Component và sự liên quan giữa các đối tượng đó.

IV.2. DataTable Là một thành phần trong DataSet, DataTable chứa dữ liệu của một bảng trong DataSet và thuộc lớp DataTable. DataTable bao gồm:

Tập hợp Columns thuộc lớp DataColumnCollection trong đó mỗi cột là một đối tượng thuộc lớp DataColumn

Tập hợp Rows thuộc lớp DataRowCollection trong đó mỗi dòng là một đối tượng thuộc lớp DataRow.

IV.3. DataRelation DataSet bao gồm tập hợp các table đại diện bởi các đối tượng DataTable và quan hệ giữa các table đó đại diện bởi các đối tượng DataRelation.

Với DataRelation, người lập trình có thể:

Định nghĩa được mối quan hệ giữa các bảng

Duyệt dữ liệu trong các bảng theo kiểu Master – Detail

Một đối tượng kiểu DataRelation bao gồm các thông tin:

Tên của Parent table và Child table

Các column trong DataRelation đại diện cho Primary key trong Parent và Foreign key trong Child table

Với DataRelation, ADO.NET cung cấp cho người lập trình một cách thức mới để xử lý dữ liệu. Dữ liệu vẫn nằm trong các bảng thay vì bị gom từ nhiều bảng thành một RecordSet nhưng vẫn có thể truy cập dễ dàng và hiệu quả hơn.

IV.4. Ràng buộc trên quan hệ ADO.NET chỉ cho phép xác định hai loại ràng buộc:

UniqueConstraint: đảm bảo tính duy nhất về giá trị của một cột trong table

Page 85: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 85/187

ForeignKeyConstraint: chỉ ra cách ứng dụng sẽ thực hiện khi cập nhật hay xoá dữ liệu trên bảng có quan hệ với bảng khác. Các giá trị của ForeignKeyConstraint:

+ None: không làm gì cả

+ Cascade: phụ thuộc vào dòng trên parent table sẽ bị cập nhật hay xoá

+ SetDefault: giá trị của cột khoá ngoại trên detail table được đặt về giá trị mặc định khi dòng trên parent table bị xoá

+ SetNull: Giống SetDefault, giá trị được đặt là Null

IV.5. DataView DataView gần giống với khái niệm RecordSet của ADO. Trên một DataTable có thể tạo nhiều DataView với các điều kiện lọc, sắp xếp dữ liệu khác nhau. Trên DataView ta có thể xem hay thay đổi giá trị các mẩu tin.

DataView của ADO.NET còn giữ nhiệm vụ kết nối với các control của Window Form và Web Form.

V. Managed Provider Component Microsoft cung cấp hai bộ provider component trong phiên bản ADO.NET này là OLEDB và SQL. OLEDB managed provider bao gồm các đối tượng:

OleDBConnection

OleDBCommand

OleDBParemeter

OleDBDataReader

OleDBDataAdapter

Tương tự với OLEDB nhưng để tăng hiệu quả cho ứng dụng sử dụng Database trên SQL Server, SQL managed provider cũng có các đối tượng giống của OLEDB nhưng bắt đấu với tên SQL thay cho OLEDB.

Hình dưới đây cho thấy các đối tượng tương ứng trong OLEDB và SQL Provider implement hoặc kế thừa từ interface hay class nào.

IDBConnection

OleDBConnection SQLConnection

DataAdapter

OleDBDataAdapter SQLDataAdapter

IDataReader

OleDBDataReader SQLDataReader

IDBParameterCollection

OleDBParameterCollection SQLParameterCollection

IDBCommand

OleDBCommand SQLCommand

Page 86: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 86/187

V.1. Connection Cả OleDBConnection và SQLConnection đều có các thuộc tính và phương thức giống nhau như ConnectionString, State hay Open.

Nói chung Connection của ADO.NET và ADO đều có cách sử dụng tương tự nhau ngoại trừ:

Connection của ADO.NET không thể thực hiện các câu truy vấn hay các stored procedure vì không còn phương thức Execute nữa.

Connection của ADO.NET không còn hỗ trợ Transaction. Với ADO.NET, một transaction được quản lý bởi đối tượng OleDBTransaction hoặc SQLTransaction (cả hai đều implement IdbTransaction). Đối tượng Transaction hỗ trợ các phương thức như Commit và Rollbacks. SQLTransaction còn hỗ trợ các checkpoint trong quá trình rollback.

Các provider mà OLEDB và SQL có thể dùng để kết nối dữ liệu là:

SQLOLEDB: OLEDB Provider của Microsoft cho SQL Server

MSDAORA: OLEDB provider của Microsoft cho Oracle

JOLT: OLEDB provider cho Jet.

V.2. Command Đối tượng Command vẫn có cùng cách sử dụng như Command của ADO. Thuộc tính Connection của SQLCommand hoặc OleDBCommand chỉ ra kết nối với CSDL sẽ sử dụng. Command cũng có thể sử dụng các tham số để thi hành các stored procedure.

Sơ đồ ở hình trên cho thấy mối liên hệ giữa Command với Connection và DataReader. Command trong ADO.NET có các cách thức thực hiện lệnh là:

ExecuteReader(): dùng đề thực hiện các câu truy vấn trả về dữ liệu. Dữ liệu trả về sẽ là một đối tượng DataReader hoặc một đối tượng nào đó có implement IdbReader interface.

ExecuteNonQuery(): dùng để thực hiện các lệnh cập nhật dữ liệu.

ExecuteScalar(): dùng để thực hiện các lệnh tính toán và trả về một dòng, một cột chứa kết quả của lệnh tính toán.

V.3. DataReader DataReader thực sự là một đối tượng tương tự với RecordSet của ADO ngoại trừ khả năng giới hạn của nó là ReadOnly lock và ForwardOnly cursor. Một DataReader được tạo ra bằng cách thực hiện phương thức ExecuteReader của đối tượng Command.

DataReader hỗ trợ về mặt tốc độ khi truy cập dữ liệu, tuy nhiên nó sử dụng cursor ở phía Server và kết nối với Server trong suốt quá trình đọc dữ liệu. Việc này khác với cơ chế sử dụng Disconnect data của ADO.NET và giảm khả năng mở rộng của ứng dụng. Vì vậy khi đã có một đối tượng DataReader, cần phải tiến hành việc đọc dữ liệu càng nhanh càng tốt.

Sử dụng Connection kết hợp với Command và DataReader là một cách được coi là "low level" của ADO.NET để thao tác với dữ liệu. ADO.NET cung cấp DataAdapter là một kết hợp của Connection với các Command giúp kết nối DataSet với database trên Server.

V.4. DataAdapter DataAdapter được ADO.NET cung cấp như một công cụ giúp kết nối dữ liệu của một table trong

Page 87: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 87/187

DataSet với database trên Server.

DataAdapter

Hình trên mô tả mô hình phân cấp các class của DataAdapter, cả SQLDataAdapter và OleDBDataAdapter đều thừa kế từ class DbDataAdapter, DbDataAdapter lại thừa kết từ abstract class DataAdapter, đến lượt abstract class này lại implement IDataAdapter interface để hỗ trợ hai phương thức Fill và Update.

Để lấy dữ liệu cho một table trong DataSet, sử dụng phương thức Fill(), để cập nhật dữ liệu cho DataSet, sử dụng phương thức Update().

Để lấy dữ liệu, DataAdapter dùng SELECT query thông qua thuộc tính SelectCommand. Để cập nhật dữ liệu, DataAdapter dùng các câu query UPDATE, INSERT, DETETE thông qua các thuộc tính UpdateCommand, InsertCommand và DeleteCommand.

Ngoài Fill và Update, DataAdapter còn kế thừa thuộc tính TableMappings giúp cung cấp cho người dùng các tên table và tên column dễ đọc hơn các tên thực được sử dụng trong Database.

Trong các đối tượng Command của DataAdapter, chỉ có đối SelectCommand là bắt buộc, các đối tượng còn lại đều có thể tự động được phát sinh.

Hình dưới đây mô tả quan hệ giữa các đối tượng thuộc Managed Provider Components.

Command

Connection

ParameterCollection

Parameter

Exception

ErrorCollection

Error

DataAdapter

SelectCommand

DataColumnMappingCollection

DataColumnMapping

DataReader

InsertCommand

DeleteCommand

UpdateCommand

DataTableMappingCollection

DataTableMappingCollection

OleDBDataAdapter SQLDataAdapter

DataAdapter

DbDataAdapter

IDataAdapter

Page 88: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 88/187

Bài 5

CONNECTION, COMMAND, DATAADAPTER

Tóm tắt Lý thuyết 2 tiết - Thực hành 5 tiết

Mục tiêu Các mục chính Bài tập

Kết thúc bài học này, học viên có thể làm việc với dữ liệu thông qua các đối tượng ADO.NET

1. Connection

2. Command

3. DataAdapter

3.1, 3.2

Page 89: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 89/187

I. Connection Vai trò của Connection trong ADO.NET cũng như trong ADO là tạo kết nối giữa ứng dụng và nguồn dữ liệu. Điểm khác biệt chính là ADO.NET không còn hổ trợ các thao tác dữ liệu có kết nối. Mặt khác, Connection trong ADO.NET giờ đây chỉ đóng vai trò tạo kênh thông tin giữa ứng dụng và CSDL, không thực hiện các lệnh truy xuất, cập nhật CSDL như trong ADO.

ConnectionCSDL

I.1. Data Provider Các Data Provider có sẵn trong ADO.NET là:

SysTem.Data.OleDb

SysTem.Data.SqlClient

Ứng với mỗi không gian tên, chúng ta có một Connection tương ứng:

SysTem.Data.OleDb.OleDbConnection

SysTem.Data.SqlClient.SqlConnection

Chúng ta có thể sử dụng SysTem.Data.OleDb.OleDbConnection cho mọi nguồn dữ liệu. Nhưng để tận dụng các đặc điểm của những Data Provider khác nhau, chúng ta có thể chỉ rõ Data Provider muốn sử dụng. Ngoài SQL Server Provider, ADO.NET cũng hỗ trợ một số Data Provider khác như:

SysTem.Data.OracleClient qua tập tin System.Data.OracleClient.dll cho Oracle.

Microsoft.Data.Odbc qua tập tin Microsoft.Data.Odbc.dll cho ODBC

Microsoft.Data.SqlXml qua tập tin Microsoft.Data.SqlXml.dll cho Xml trên SQL Server

Với những Data Provider không cung cấp sẵn, khi sử dụng, chúng ta cần tham chiếu theo cách sau Project - Add Reference - <Data Provider>

Ví dụ:

Imports SysTem.Data.OleDb

Dim ket_noi As New OleDbConnection()

I.2. ConnectionString Trước khi thực hiện kết nối, cần khai báo các thông tin cần thiết cho Connection thông qua thuộc tính ConnectionString. Cách khai báo thay đổi tùy thuộc Data Provider. Với OLEDB Provider có thể gồm các thành phần

Provider: Khai báo Data Provider

Page 90: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 90/187

Data Source: Nguồn dữ liệu

User ID: Tên người dùng

Password: Mật khẩu

Ví dụ: Tạo Connection đến CSDL Access sử dụng OLeDbConnection

Imports SysTem.Data.OleDb

Dim chuoi_kn As String = "Provider=Microsoft.Jet.OLEDB.4.0; " & _

"Data Source =" & <đường dẫn>

Dim cnn As New OleDbConnection(chuoi_kn)

Ví dụ: Tạo Connection đến CSDL SQL Server sử dụng OLeDbConnection

Imports SysTem.Data.OleDb

Dim chuoi_kn As String = "Provider=SQLOLED;User ID=" & <người dùng> & _

";Password =" & <mật khẩu> & ";Data Source=" & <tên hoặc TCP/IP server> _

& ";Initial Catalog =" & <tên Database>

Dim cnn As New OleDbConnection(chuoi_kn)

Ví dụ: Tạo Connection đến CSDL Oracle sử dụng OLeDbConnection

Imports SysTem.Data.OleDb

Dim chuoi_kn As String = "Provider=MSDAORA.1;User ID=" & <người dùng> & _

";Password =" & <mật khẩu> & ";Data Source=" & <đường dẫn>

Dim cnn As New OleDbConnection(chuoi_kn)

SqlConnection chỉ cho phép kết nối đến dữ liệu SQL Server từ phiên bản 7.0 trở về sau. Cách khai báo khác hơn với các thành phần chính như sau:

Data Source: Tên máy nơi cài đặt SQL Server có nguồn dữ liệu muốn kết nối

Initial Catalog: Tên database muốn kết nối

Integrated Security : True(SSPI)/ False chỉ định dùng cơ chế bảo mật của Windows Login (True) hay cơ chế bảo mật của SQL Server (False)

User ID: Tên người dùng (phải khai báo khi Integrated Security = False)

PassWord: Mật khẩu (phải khai báo khi Integrated Security = False)

Việc sử dụng cơ chế bảo mật nào tùy thuộc SQL Server qui định.

Ví dụ: Tạo Connection đến CSDL SQL Server sử dụng SqlConnection

Imports SysTem.Data.SqlClient

Dim chuoi_kn As String = "Data Source=" & <địa chỉ TCP/IP hay tên máy> & _

"Initial Catalog=" & <tên database> & _

";User ID =" & <tên người dùng> & ";Password =" & <mật khẩu>

Dim cnn As New SqlConnection(chuoi_kn)

Hoặc

Imports SysTem.Data.SqlClient

Dim chuoi_kn As String = "Data Source=" & <địa chỉ TCP/IP hay tên máy> & _

"Initial Catalog=" & <tên database> & ";Integrated Security =SSPI"

Page 91: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 91/187

Dim cnn As New SqlConnection(chuoi_kn)

I.3. Các thuộc tính khác của Connection Các thuộc tính

Tên Mô tả

Database (Chỉ đọc) Tương ứng với Initial Catalog (SQL) hay tên database muốn làm việc (OLEDB)

DataSource (Chỉ đọc) Tương ứng với Data Source (OLEDB và SQL)

Provider (Chỉ đọc) Tương ứng với Provider (OLEDB)

State Tình trạng kết nối của Connection với các giá trị:

Broken: Kết nối với nguồn dữ liệu đã bị ngắt. Tình trạng này chỉ xảy ra sau khi đã kết nối.

Closed: Kết nối đã đóng.

Connecting: Đang kết nối với nguồn dữ liệu.

Executing: Kết nối đang thực hiện một lệnh.

Fetching: Kết nối đang truy xuất dữ liệu.

Open: Kết nối đang mở.

I.4. Các phương thức trên Connection Các phương thức

Tên Mô tả

BeginTransaction Bắt đầu một giao tác dữ liệu và trả về một đối tượng OleDbTransaction hoặc SQLTransaction tương ứng

ChangeDatabase Thay đổi database làm việc. ChangeDatabase(<tên database>)

Close Đóng kết nối với nguồn dữ liệu. Sử dụng phương thức này để đóng Connection đang mở.

CreateCommand Tạo và trả về một Command dựa vào Connection hiện hành. CreateCommand()

Dispose Xoá mọi tài nguyên liên quan đến Connection trên vùng nhớ

Open Thực hiện kết nối với các thông tin đã khai báo trong ConnectionString

I.5. Minh họa tạo Connection Sau đây là một ví dụ tạo Connection kết nối với tập tin CSDL Access C:\QlHanghoa.mdb bằng lệnh và bằng điều khiển OledbConnection.

Ví dụ:

Imports System.Data.Oledb

Dim chuoi_kn As String = "Provider =Microsoft.Jet.OLEDB.4.0; " & _

Page 92: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 92/187

"Data Source =C:\QlHanghoa.mdb"

Dim cnn As New OleDbConnection(chuoi_kn)

cnn.Open()

' các lệnh

cnn.Close()

II. Command Sau khi tạo kết nối với nguồn dữ liệu, mọi thao tác trên nguồn dữ liệu đó đều được thực hiện thông qua Command. Tùy theo loại Connection, đối tượng Command thuộc không gian tên như sau:

System.Data.OleDb.OleDbCommand

System.Data.SqlClient.SqlCommand

II.1. Tạo Command Chúng ta có thể tạo đối tượng Command qua các cách sau thông qua một đối tượng Connection:

Cú pháp:

Dim <biến Command> As New <loại>Command()

<biến Command>.Connection = <biến Connection>

<biến Command>.CommandText = <lệnh>

Hoặc

Dim <biến Command> As New <loại>Command(<lệnh>)

<biến Command>.Connection = <biến Connection>

Hoặc

Dim <biến Command> As _

New <loại>Command(<lệnh SQL>, <biến Connection>)

Hoặc

Dim <biến Command> As <loại>Command = <biến Connection>.CreateCommand()

<biến Command>.CommandText = <lệnh>

II.2. Các thuộc tính của Command Các thuộc tính

Tên Mô tả

CommandText Lệnh SQL,tên bảng hoặc tên stored procedure muốn thực hiện trên nguồn dữ liệu. (đọc ghi)

CommandType Giá trị cho biết nội dung CommandText là gì với các giá trị sau:

Text: (mặc định) một câu lệnh SQL

Storedprocedure: tên một thủ tục nội

TableDirect: tên của bảng. Khi CommandType có giá trị nầy,

Page 93: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 93/187

CommandText là tên của một bảng. Khi Command thực hiện sẽ trả về đủ các dòng và các cột (chỉ dùng cho OledbCommand)

Ví dụ:

Imports Systm.Data.Oledb

Dim chuoi As String ="Provider=SQLOLEDB; " & _

"Integrated Security = SSPI; " & _

"Initial Catalog=DAT_GIAO;Data Source=HUUTHIEN"

Dim cnn As New OleDbConnection(chuoi)

cnn.Open()

Dim lenh As New OleDbCommand("PHIEU_NHAP",cnn)

lenh.CommandType = CommandType.TableDirect

Connection Đối tượng Connection sử dụng cho Command

Parameters Tập hợp các tham số dùng trong Command (xem phần Parameter)

Transaction Giao tác mà trên đó Command đang thực hiện

II.3. Parameter Lệnh SQL trong CommandText có thể sử dụng các dấu hỏi (?) thay thế cho trị chưa xác định và khi thực hiện sẽ dùng đối tượng Parameter để truyền giá trị vào chỗ các dấu hỏi. Tùy theo Command, Parameter sẽ khai báo từ lớp OledbParameter hay SqlParameter.

Cú pháp:

Dim <tên parameter> As New OledbParameter|SqlParameter()

Dim <tên parameter> As New OledbParameter|SqlParameter(<tên>)

Dim <tên parameter> As New OledbParameter|SqlParameter(<tên>, <giá trị>)

II.3.1. Các thuộc tính của Parameter

Các thuộc tính

Tên Mô tả

Direction Giá trị cho biết loại tham số với các giá trị sau: (đọc ghi)

Input (mặc định): loại tham số đầu vào

InputOutput: loại tham số vào và ra

Output: loại tham số đầu ra

ReturnValue: loại tham số nhận giá trị trả về của một thủ tục nội, một hàm, hay một hàm do người dùng định nghĩa.

OleDbType SqlDbType

Kiểu dữ liệu OleDb hoặc SqlDb của tham số. (đọc ghi)

ParameterName Tên tham số. (đọc ghi)

Value Giá trị của tham số. (đọc ghi)

Page 94: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 94/187

Để đưa một tham số cho Command, chúng ta có thể sử dụng một trong các cách sau:

II.3.2. Tạo Parameter với CreateParameter của Command

Ví dụ: Khi sử dụng OleDbCommand

lenh.CommandText = "Select * from CTNHAP where sopn = ?"

Dim thamso As OleDbParameter = lenh.CreateParameter()

thamso.Value = "PN01"

lenh.Parameters.Add(thamso) Ví dụ: Khi sử dụng SqlCommand

lenh.CommandText = "Select * from CTNHAP where sopn = @sp"

Dim thamso As SqlParameter = lenh.CreateParameter()

thamso.ParameterName = "@sp"

thamso.Value = "PN01"

lenh.Parameters.Add(thamso)

II.3.3. Đưa tham số trực tiếp vào tập hợp Parameters

Ví dụ: Khi sử dụng OleDbCommand

lenh.CommandText = "Select * from CTNHAP where sopn = ? and mavtu = ?"

‘ thứ tự đưa tham số vào phải theo thứ tự trong lệnh SQL

Dim ts1 As OleDbParameter = lenh.Parameters.Add("phieu", _

OleDbType.Char, 4)

ts1.Value = "PN01"

Dim ts2 As OleDbParameter = lenh.Parameters.Add("vattu", _

OleDbType.Char, 4)

ts1.Value = "S001" Ví dụ: Khi sử dụng SqlCommand

lenh.CommandText = "Select * from CTNHAP where sopn = @sp and mavtu = @vt"

‘ thứ tự đưa tham số vào tùy ý vì phải chỉ đúng tên tham số trong lệnh SQL

Dim ts1 As SqlClient.SqlParameter = lenh.Parameters.Add("@vt", _

SqlDbType.Char, 4)

ts1.Value = "S001"

Dim ts2 As SqlClient.SqlParameter = lenh.Parameters.Add("@sp", _

SqlDbType.Char, 4)

ts2.Value = "PN01"

II.3.4. Tạo tham số và đưa vào tập hợp Parameters

Ví dụ: Thủ tục nội spSLGiao cần hai tham số đầu vào: @sodh, @mavtu và trả về số lượng đã giao của mặt hàng @mavtu cho đơn đặt hàng @sodh. Vì vậy chúng ta phải truyền vào 3 tham số: 1 tham số trả về và 2 tham số đầu vào. Tham số trả về phải được truyền cho Command trước tiên.

lenh.CommandText = "spSLGiao"

Page 95: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 95/187

lenh.CommandType = CommandType.StoredProcedure

Dim tv As New OleDbParameter()

tv.Direction = ParameterDirection.ReturnValue

tv.OleDbType = OleDb.OleDbType.Integer

lenh.Parameters.Add(tv)

Dim ts1 As OleDbParameter = lenh.Parameters.Add("@sodh", _

OleDbType.Char, 4)

ts1.Value = "D001"

Dim ts2 As OleDbParameter = lenh.Parameters.Add("@mavtu", _

OleDbType.Char, 4)

ts2.Value = "C001"

II.4. Thực hiện Command Command có nhiều phương thức thực hiện khác nhau như sau:

II.4.1. ExecuteNonquery

Để gọi thực hiện các câu truy vấn cập nhật INSERT, UPDATE, DELETE,... hay thủ tục nội không trả về dữ liệu hoặc khi chúng ta không quan tâm đến dữ liệu trả về. Tuy không trả về dữ liệu, nhưng các tham số đầu ra, trả về đều chứa dữ liệu (nếu có). Với các lệnh INSERT, UPDATE, DELETE, phương thức này trả về số dòng chịu tác động của Command, ngược lại phương thức trả về -1:

Ví dụ: Trong ví dụ trên, chúng ta nhận được số lượng mặt hàng "C001" đã giao cho đơn đặt hàng “D001” khi goi thực hiện như sau.

cmd.ExecuteNonQuery()

Console.WriteLine("Số lượng đã giao {0}", tv.Value)

II.4.2. ExecuteReader

Phương thức này trả về một đối tượng DataReader để đọc dữ liệu mỗi lần một dòng với phương thức Read(). DataReader đọc dữ liệu trực tiếp từ nguồn dữ liệu nên phải duy trì kết nối cho đến khi đọc xong. Cú pháp gọi phương thức này như sau.

Cú pháp:

ExecuteReader()

Hoặc

ExecuteReader(<behavior>)

Các giá trị của <behavior>

Giá trị Mô tả

CloseConnection Khi đối tượng DataReader đóng lại, Connection tự động đóng theo.

Dim bo_doc As New OledbReader = _

lenh.ExecuteReader(CommandBehavior.CloseConnection)

Dim ndung As String, i As Short

Do While bo_doc.Read

Page 96: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 96/187

For i = 0 To bo_doc.FieldCount -1

ndung &= bo_doc.GetValue(i) & vbTab

Next

ndung &= vbNewLine

Loop

bo_doc.Close()

MsgBox (lenh.Connection.State) ' trả về Closed

Default Tương tự như khi gọi ExecuteReader()

SchemaOnly Truy vấn chỉ trả về cấu trúc các cột và không làm ảnh hưởng đến các thao tác khác.

Dim bo_doc As New OledbReader = _

lenh.ExecuteReader(CommandBehavior.SchemaOnly)

Dim ndung As String, i As Short

For i = 0 To bo_doc.FieldCount -1

ndung &= bo_doc.GetName(i) & vbNewLine

Next

II.4.3. ExecuteScalar

Phương thức này thực hiện lệnh của Command và chỉ trả về giá trị của cột đầu tiên và dòng đầu tiên. Chúng ta thường gọi phương thức này khi muốn Command thực hiện các hàm tính toán thống kê SUM, COUNT, AVG, MAX, MIN, ... trên nguồn dữ liệu ngay lúc thực thi.

Cú pháp:

ExecuteScalar()

Ví dụ:

lenh.CommandText = "Select Sum(slnhap*dgnhap) from CTNHAP where sopn = ?"

lenh.Parameters.Add("pn", "PN01")

Dim kq As Integer = lenh.ExecuteScalar()

Console.WriteLine("Trị giá của phiếu nhập {0} là {1:#,###}", _

lenh.Parameters(0).Value, kq)

II.5. DataReader Là đối tượng truy cập dữ liệu trực tiếp, sử dụng cursor phía Server và duy trì kết nối với Server trong suốt quá trình đọc dữ liệu, DataReader thuộc không gian tên System.Data.OledbDataReader hoặc System.Data.SqlDataReader

Page 97: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 97/187

II.5.1. Các thuộc tính của DataReader

Các thuộc tính

Tên Mô tả

FieldCount Trả về số cột trên dòng hiện hành của DataReader.

IsClosed Cho biết DataReader đã đóng chưa.

Item Trị của cột truyền vào. Tham số truyền có thể là tên cột hoặc số thứ tự (từ 0)

II.5.2. Các phương thức của DataReader

Các phương thức

Tên Mô tả

Close Đóng DataReader.

GetFieldType Trả về kiểu dữ liệu của cột truyền vào.

GetName Trả về tên của cột truyền vào.

GetOrdinal Trả về số thứ tự của cột truyền vào (bắt đầu từ 0).

GetSchemaTable Trả về bảng chứa thông tin mô tả cột của DataReader.

GetValue Trả về giá trị trên cột truyền vào.

Read Di chuyển đến dòng kế tiếp và trả về True nếu còn dòng để di chuyển, ngược lại trả về False

Trong khi DataReader đang mở, các thao tác dữ liệu khác trên nguồn dữ liệu đều không thể cho đến khi DataReader đóng lại bằng lệnh Close.

III. DataAdapter Để lấy dữ liệu từ nguồn dữ liệu về cho ứng dụng, chúng ta sử dụng một đối tượng gọi là DataAdapter. Đối tượng này cho phép lấy cấu trúc và dữ liệu của các bảng trong nguồn dữ liệu.

DataAdapter là một bộ gồm bốn đối tượng Command:

SelectCommand: cho phép lấy thông tin từ nguồn dữ liệu về

InsertCommand: cho phép thêm dữ liệu vào bảng trong nguồn dữ liệu.

UpdateCommand: cho phép sửa đổi dữ liệu trên bảng trong nguồn dữ liệu.

DeleteCommand: cho phép hủy bỏ dữ liệu trên bảng trong nguồn dữ liệu.

Thông thường, chúng ta chỉ cần khai báo nội dung lệnh cho SelectCommand, các nội dung của các command còn lại có thể được phát sinh nhờ đối tượng CommandBuilder dựa vào nội dung của SelectCommand.

III.1. Tạo DataAdapter Cũng như Command, chúng ta cần khai báo rõ DataAdapter sử dụng theo Data Provider nào: SqlDataAdapter hoặc OledbDataAdapter. Hai lớp này thuộc không gian tên:

System.Data.OleDb.OleDbDataAdapter

Page 98: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 98/187

System.Data.SqlClient.SqlDataAdapter

Cú pháp:

New <loại>DataAdapter()

New <loại>DataAdapter(<đối tượng SelectCommand>)

<đối tượng SelectCommand>: Đối tượng Command có sẵn với nội dung lệnh truy xuất.

New <loại>DataAdapter(<lệnh>, <đối tượng Connection>)

<lệnh>: Câu lệnh SQL, tên storedprocedure… để thực hiện truy xuất từ nguồn dữ liệu

<đối tượng Connection>: Đối tượng Connection, trên đó DataAdapter thao tác với nguồn dữ liệu

New <loại> DataAdapter(<lệnh>,<chuỗi Connection>)

<chuỗi Connection>: Chuỗi ConnectionString để tạo một đối tượng Connection

DataAdapter chỉ thao tác được với nguồn dữ liệu qua một đối tượng Connection đang kết nối, nhưng điểm đặc biệt của DataAdapter là khi Connection chưa mở, DataAdapter sẽ tự động mở kết nối khi cần và tự động đóng lại, ngược lại, với một Connection đã mở sẵn, chúng ta phải tự đóng kết nối, DataAdapter không thực hiện tự động.

Ví dụ:

Dim bo_doc_ghi As New OledbDataAdapter()

bo_doc_ghi.SelectCommand.CommandText = "Select * from VATTU"

bo_doc_ghi.SelectCommand.Connection.ConnectionString = _

"Provider = Microsoft.Jet.OLEDB.4.0; Data Source = C:\QlHanghoa.mdb"

Hoặc

Dim lenh As New OledbCommand("Select * from VATTU", _

"Provider = Microsoft.Jet.OLEDB.4.0; Data Source = C:\QlHanghoa.mdb")

Dim bo_doc_ghi As New OledbDataAdapter(lenh)

Hoặc

Dim ketnoi As New OledbConnection("Provider =Microsoft.Jet.OLEDB.4.0;" & _

"Data Source = C:\QlHanghoa.mdb")

Dim bo_doc_ghi As New OledbDataAdapter("Select * from VATTU", ketnoi)

Hoặc

Dim chuoi As String = "Provider = Microsoft.Jet.OLEDB.4.0; " & _

"Data Source= C:\QlHanghoa.mdb"

Dim bo_doc_ghi As New OledbDataAdapter(“Select * from VATTU”, chuoi)

III.2. Các thuộc tính chính của DataAdapter Các thuộc tính chính

Tên Mô tả

ContinueUpdateOnError Chỉ định cách thức xử lý khi DataAdapter cập nhật dữ liệu về nguồn và bị lỗi. Nếu là True, DataAdapter bỏ qua dòng bị lỗi và cập nhật các dòng kế

Page 99: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 99/187

tiếp. Lỗi phát sinh sẽ được đưa vào thuộc tính RowError của dòng bị lỗi, ngược lại False, sẽ phát sinh Exception khi dòng bị lỗi.

DeleteCommand Đối tượng Command chứa nội dung lệnh hủy các mẩu tin trên nguồn dữ liệu.

InsertCommand Đối tượng Command chứa nội dung lệnh chèn các mẩu tin mới vào nguồn dữ liệu.

SelectCommand Đối tượng Command chứa nội dung lệnh truy xuất các mẩu tin từ nguồn dữ liệu.

TableMappings Tập hợp các ánh xạ tên bảng khi DataAdapter đổ dữ liệu hay cấu trúc vào đối tượng chứa.

UpdateCommand Đối tượng Command chứa nội dung lệnh cập nhật các mẩu tin vào nguồn dữ liệu.

III.3. Các chức năng của DataAdapter

III.3.1. Để lấy dữ liệu từ nguồn

Sau khi có đối tượng DataAdapter với nội dung SelectCommand và thông tin về kết nối, chúng ta có thể sử dụng DataAdapter để lấy dữ liệu về cho các đối tượng chứa dữ liệu như DataTable, DataSet qua phương thức Fill. Phương thức trả về số mẩu tin lấy về được.

Cú pháp:

Đổ dữ liệu vào DataTable có sẵn

Fill(<datatable>)

Đổ dữ liệu vào DataSet có sẵn. Dữ liệu được lấy về Dataset dưới dạng các DataTable, với tên mặc định là Table,Table1,Table2,…

Fill(<dataset>)

Đổ dữ liệu vào DataSet cho bảng <tên Datatable>; nếu chưa có, bảng sẽ được tạo

Fill(<dataset>, <tên Datatable>)

Ví dụ: Tiếp tục với của phần trước

Dim dst As New DataSet()

Dim so As Integer

so = bo_doc_ghi.Fill(dst, "Vattu")

Kinh nghiệm giảng dạy:

Khi dùng nhiều DataAdapter để đổ dữ liệu của nhiều bảng vào DataSet, nếu không chỉ rõ đổ vào bảng nào trong DataSet, dữ liệu sẽ đổ chung vào một bảng, số cột là tổng số cột có tên khác nhau trong các bảng từ nguồn dữ liệu, trên mỗi dòng cột nào không có dữ liệu tương ứng sẽ mang trị Null.

Page 100: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 100/187

Ví dụ: Tiếp tục với của phần trước

Dim dst As New DataSet()

Dim ketnoi As New OledbConnection("Provider =Microsoft.Jet.OLEDB.4.0;" & _

"Data Source = C:\QlHanghoa.mdb")

Dim bo_doc_ghi1 As New OledbDataAdapter("Select * from NHACC", ketnoi)

Dim bo_doc_ghi2 As New OledbDataAdapter("Select * from VATTU", ketnoi)

bo_doc_ghi1.Fill(dst)

bo_doc_ghi2.Fill(dst)

Dữ liệu trên bảng của DataSet có dạng

Kinh nghiệm giảng dạy:

Chúng ta có thể dùng một DataAdapter để đổ dữ liệu của nhiều bảng từ SQL Server vào DataSet với nội dung lệnh truy vấn là các lệnh liên tiếp và cách nhau bằng dấu (;)

Ví dụ:

Page 101: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 101/187

Dim dst As New DataSet()

Dim ketnoi As New OledbConnection("Provider =SQLOLEDB; " & _

"Data Source=(local); Integrated Security=SSPI;" & _

"Initial Catalog=Trac_nghiem;Persist Security Info=False")

Dim bo_doc_ghi As New OledbDataAdapter("Select * From VATTU;" & _

"Select * from NHACC", ketnoi)

bo_doc_ghi.Fill(dst)

Với lệnh Fill như trên (không có tên bảng), dữ liệu đổ về DataSet dưới hình thức các DataTable có tên lần lượt Table, Table1,…

Với lệnh Fill sau đây (có tên bảng)

bo_doc_ghi.Fill(dst, "Vattu")

Dữ liệu đổ về DataSet dưới hình thức các DataTable có tên lần lượt Vattu, Vattu1,…

Để đặt lại tên cho các bảng, chúng ta có thể dùng cách ánh xạ tên bảng như sau trước khi đổ dữ liệu:

Cho trường hợp không có tên bảng (sử dụng bo_doc_ghi.Fill(dst))

bo_doc_ghi.TableMappings.Add (“Table”, “Vattu”)

bo_doc_ghi.TableMappings.Add ("Table1", "Nhacc")

III.3.2. Để lấy cấu trúc từ nguồn dữ liệu

Cú pháp:

Tạo cấu trúc dữ liệu cho DataSet có sẵn, phương thức trả về một tập hợp các cấu trúc bảng được thêm vào DataSet

FillSchema(<dataset>, <kiểu cấu trúc>)

Tạo cấu trúc dữ liệu cho DataTable có sẵn, phương thức trả về DataTable

FillSchema(<datatable>, <kiểu cấu trúc>)

Tạo cấu trúc dữ liệu cho bảng <tên Datatable> trong DataSet; nếu chưa có, bảng sẽ được tạo ra

FillSchema(<datatable>, <tên Datatable>,<kiểu cấu trúc>)

<kiểu cấu trúc>: Qui định việc ánh xạ tên có được chấp nhận hay không.

Các giá trị của <kiểu cấu trúc>

Giá trị Mô tả

SchemaType.Mapped Sử dụng các TableMappings cho các cấu trúc đưa vào DataSet nếu trùng hợp.

SchemaType.Source Không sử dụng các TableMappings

Thông thường SchemaType.Mapped được sử dụng

Nếu bảng đã có cấu trúc sẵn, các cột có tên khác với cột có sẵn trên bảng sẽ được thêm vào.

Tùy theo cấu trúc trên nguồn dữ liệu, những thuộc tính sau sẽ được đưa vào cấu trúc của cột:

AllowDBNull: cho phép nhận giá trị Null hay không

Page 102: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 102/187

AutoIncrement: tự động tăng

MaxLength: kích thước tối đa của cột (tính theo Byte)

ReadOnly: chỉ cho phép đọc

Unique: cột có trị duy nhất

Phương thức FillSchema cũng định luôn khóa chính và các ràng buộc cho bảng theo nguyên tắc sau:

Các cột khóa chính trong lệnh truy vấn của SelectCommand được dùng làm các cột khóa chính cho bảng.

Nếu không có cột khóa chính trong lệnh truy vấn, nhưng có những cột có trị duy nhất và nếu những cột này không cho phép nhận giá trị Null, thì được dùng làm khóa chính. Ngược lại, mỗi một cột tuy có trị duy nhất nhưng chấp nhập giá trị Null, thì một ràng buộc duy nhất được thêm vào tập hợp Constraints của bảng nhưng không có khóa chính.

Chỉ có các ràng buộc khóa chính và khóa duy nhất mới thêm vào tập hợp Constraints, các loại ràng buộc khác không được đưa vào.

Những đặc điểm của phương thức FillSchema cũng giống như của Fill

Ví dụ:

Dim dst As New DataSet()

Dim ketnoi As New OledbConnection("Provider =SQLOLEDB; " & _

"Data Source=(local); Integrated Security=SSPI;" & _

"Initial Catalog=Trac_nghiem;Persist Security Info=False")

Dim bo_doc_ghi As New OledbDataAdapter("Select * From VATTU;" & _

"Select * from NHACC", ketnoi)

bo_doc_ghi.TableMappings.Add ("Table", "Vattu")

bo_doc_ghi.TableMappings.Add ("Table1", "Nhacc")

Khi sử dụng giá trị SchemaType.Source, bo_doc_ghi sẽ lấy cấu trúc về cho các bảng trong DataSet và đặt tên các bảng theo cách mặc nhiên Table, Table1

bo_doc_ghi.FillSchema(dst,SchemaType.Source)

Khi sử dụng giá trị SchemaType.Mapped, bo_doc_ghi sẽ lấy cấu trúc về cho các bảng trong DataSet và đặt tên các bảng lần lượt theo TableMappings đã tạo: Vattu, Nhac

bo_doc_ghi.FillSchema(dst,SchemaType.Mapped)

III.3.3. Tạo bộ lệnh cập nhật cho DataAdapter:

Để tự động phát sinh lệnh cập nhật cho các command còn lại của DataAdapter, chúng ta sử dụng CommandBuilder thuộc không gian tên:

System.Data.Oledb.OledbCommandBuilder

System.Data.SqlClient.SqlCommandBuilder

Cách thực hiện như sau:

Cú pháp:

New <loại>CommandBuilder(<đối tượng DataAdapter>)

Ví dụ:

Page 103: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 103/187

Imports System.Data.Oledb

Dim chuoi As String = "Provider = Microsoft.Jet.OLEDB.4.0; " & _

"Data Source = C:\QlHanghoa.mdb"

Dim bo_doc_ghi As New OledbDataAdapter("Select * from VATTU", chuoi)

Dim bo_phat_sinh As New OledbCommandBuilder(bo_doc_ghi)

Mỗi DataAdapter chỉ có thể kết hợp với một CommandBuilder. Đối tượng này dùng nội dung lệnh trong SelectCommand của DataAdapter để tạo nội dung lệnh cho các Command còn lại với các đặc điểm sau:

CommandBuilder chỉ phát sinh nội dung lệnh cập nhật cho các DataAdapter có nội dung SelectCommand truy xuất đến chỉ một bảng nguồn

Nội dung trong SelectCommand phải có ít nhất một khóa chính hoặc một khóa duy nhất (Unique key) để DataAdapter phân biệt các dòng khi cập nhật. Nếu không, CommandBuilder sẽ không phát sinh được nội dung lệnh cho các Command Insert, Update, Delete.

Trường hợp nội dung của SelectCommand là truy vấn từ hơn một bảng hoặc từ một StoredProcedure, các Command cập nhật không tự động phát sinh, nhưng chúng ta phải khai báo các Command cập nhật cách tường minh.

Sau khi lệnh được phát sinh, nếu nội dung lệnh của SelectCommand thay đổi, lệnh của các Command khác không tự động thay đổi theo cho đến khi phương thức RefreshSchema của CommandBuilder được gọi.

Trường hợp nội dung của SelectCommand là nhiều câu Select SQL, CommandBuilder chỉ tạo được lệnh cập nhật cho lệnh truy vấn đầu tiên.

Ví dụ: cách thức CommandBuilder phát sinh lệnh cho các Command

Dim chuoi As String = "Provider=Microsoft.Jet.OLEDB.4.0;" & _

"Data Source = C:\QlHanghoa.mdb"

Dim bo_doc_ghi As New OledbDataAdapter("Select * from VATTU", chuoi)

Dim bo_phat_sinh As New OledbCommandBuilder(bo_doc_ghi)

Console.WriteLine(bo_phat_sinh.GetInsertCommand.CommandText)

' kết quả in ra

' INSERT INTO VATTU( mavtu , tenvtu , dvtinh ) VALUES ( ? , ? , ? )

Console.WriteLine(bo_phat_sinh.GetUpdateCommand.CommandText)

' kết quả in ra

' UPDATE VATTU SET mavtu = ? , tenvtu = ? , dvtinh = ? WHERE ( (mavtu = ?)

' AND ((? = 1 AND tenvtu IS NULL) OR (tenvtu = ?))

' AND ((? = 1 AND dvtinh IS NULL) OR (dvtinh = ?)) )

Console.WriteLine(bo_phat_sinh.GetDeleteCommand.CommandText)

' kết quả in ra

' DELETE FROM VATTU WHERE ( (mavtu = ?) AND (( ? = 1 AND tenvtu IS NULL)

' OR (tenvtu = ?)) AND (( ? = 1 AND dvtinh IS NULL) OR (dvtinh = ?)) )

III.3.4. Để cập nhật các thay đổi về nguồn dữ liệu

Page 104: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 104/187

Cú pháp:

Update(<mảng dòng>)

Phương thức này cập nhật các dòng <mảng dòng> vào nguồn dữ liệu

<mảng dòng>: Mảng các đối tượng lớp DataRow, thường mảng này là kết quả trả về của phương thức GetChanges của DataSet

Update(<dataset>)

Phương thức này cập nhật các thay đổi trên tất cả các bảng của <dataset> vào nguồn dữ liệu

<dataset>: Đối tượng DataSet mà DataAdapter sẽ cập nhật vào nguồn

Update(<datatable>)

Phương thức này cập nhật các thay đổi trên DataTable vào nguồn dữ liệu

<datatable>: Đối tượng DataTable mà DataAdapter sẽ cập nhật vào nguồn

Update(<dataset>, <tên bảng>)

Phương thức này cập nhật các thay đổi trên bảng có tên <tên bảng> trong DataSet vào nguồn dữ liệu

Khi phương thức Update được gọi, DataAdapter sẽ kiểm tra tình trạng các dòng là thêm mới, sửa đổi, xóa và gọi thực hiện tự động các Command tương ứng cho mỗi dòng. Nếu các Command chưa được tạo sẽ phát sinh lỗi. Chúng ta có thể tạo và gán cho mỗi loại Command trên DataAdapter hoặc tự động phát sinh thông qua CommandBuilder như đề cập ở mục trên.

Thông thường, mỗi Command trên DataAdapter có một tập hợp tham số kết hợp với nó. Các tham số này được ánh xạ với dòng đang cập nhật thông qua thuộc tính:

SourceColumn: Cho biết tên cột trên dòng được cập nhật liên kết với tham số

SourceVersion: Cho biết giá trị của phiên bản nào trên dòng được cập nhật truyền vào vị trí tham số.

Các giá trị của SourceVersion

Giá trị Mô tả

Current Tham số dùng giá trị hiện hành của cột. Đây là giá trị mặc định.

Default Tham số dùng giá trị mặc định đã qui định cho cột.

Original Tham số dùng giá trị gốc: giá trị từ khi bảng được lấy về từ nguồn dữ liệu hay từ lần gọi cập nhật lần trước.

Proposed Tham số sử dụng một giá trị đề nghị.

Page 105: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 105/187

Bài 6

DATASET, DATATABLE, DATARELATION VÀ DATAVIEW

Tóm tắt Lý thuyết 6 tiết - Thực hành 5 tiết

Mục tiêu Các mục chính Bài tập

Kết thúc bài học này, học viên có thể làm việc với dữ liệu thông qua các đối tượng ADO.NET

1. DataSet

2. DataTable

3. DataRelation

4. DataView

3.3, 4.2, 4.3

Page 106: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 106/187

I. DataSet Một trong những điểm khác biệt chính giữa ADO và ADO.NET là đối tượng DataSet. Như đã trình bày ở chương trước, DataSet là một mô hình CSDL quan hệ thu nhỏ đáp ứng nhu cầu của ứng dụng.

DataSet chứa các bảng (DataTable), các quan hệ (DataRelation). DataSet thuộc không gian tên sau: SysTem.Data

Dataset trong hệ thống không gian tên

I.1. Khai báo DataSet Cú pháp:

New SysTem.Data.DataSet()

Hoặc

New SysTem.Data.DataSet(<tên>)

<tên>: tên của DataSet

I.2. Các thuộc tính của DataSet Các thuộc tính chính

Tên Mô tả

DataSetName Tên của DataSet. (đọc ghi)

HasErrors Giá trị cho biết có lỗi xảy ra trên một trong các bảng của DataSet: True/False (chỉ đọc)

Relations Tập hợp các quan hệ (DataRelation) một nhiều của DataSet. (chỉ đọc)

Tables Tập hợp các bảng (DataTable) của DataSet. (chỉ đọc)

I.3. Các phương thức của DataSet

I.3.1. Thêm một bảng vào DataSet:

Muốn đưa một DataTable vào DataSet, chúng ta dùng phương thức Add của tập hợp Tables.

Cú pháp:

<Dataset>.Tables.Add()

Một bảng mới tự động tạo ra với tên mặc nhiên (Table1, Table2,…) và đưa vào tập hợp Tables của

Page 107: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 107/187

DataSet

<Dataset>.Tables.Add(<tên bảng>)

Một bảng mới tự động tạo ra với tên là <tên bảng> và đưa vào tập hợp Tables

<Dataset>.Tables.Add(<bảng>)

Đưa <bảng> vào tập hợp Tables

<bảng>: là một đối tượng DataTable muốn đưa vào DataSet (sẽ đề cập đến trong phần sau)

Kinh nghiệm giảng dạy:

Tên bảng trong DataSet có phân biệt chữ HOA chữ thường. Nghĩa là có thể có 2 bảng tên "table1" và "Table1"

Ví dụ:

Imports SysTem.Data

Dim dst As New DataSet("Ví dụ")

Dim bang As New DataTable("Bảng 1")

Dst.Tables.Add(bang)

I.3.2. Thêm nhiều bảng vào DataSet:

Muốn đưa nhiều bảng vào DataSet, chúng ta dùng phương thức AddRange của tập hợp Tables.

Cú pháp:

<DataSet>.Tables.AddRange(<mảng DataTable>)

<mảng DataTable>: Là một mảng các DataTable đã tạo ra muốn đưa vào DataSet

Ví dụ:

Dim dst As New DataSet("Ví dụ")

Dim bang1 As New DataTable("Bảng 1")

Dim bang2 As New DataTable("Bảng 2")

dst.Tables.AddRange(New DataTable(){bang1,bang2})

I.3.3. Xóa bảng khỏi DataSet:

Để xóa một bảng khỏi DataSet, chúng ta dùng các phương thức sau của tập hợp Tables.

Cú pháp:

Xóa <DataTable> khỏi tập hợp Tables của DataSet.

<DataSet>.Tables.Remove(<DataTable>)

Xóa <DataTable> có tên là <tên bảng> khỏi tập hợp Tables của DataSet.

<DataSet>.Tables.Remove(<tên bảng>)

Xóa <DataTable> có chỉ số là <chỉ số> khỏi tập hợp Tables của DataSet.

Page 108: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 108/187

<DataSet>.Tables.RemoveAt(<chỉ số>)

Tuy nhiên, bảng có thể đang hiển thị dữ liệu trên Form nên chúng ta cần kiểm tra xem có thể xóa được không với cú pháp:

<DataSet>.Tables.CanRemove(<DataTable>)

Phương thức trả về True có thể xóa, ngược lại là False.

Ví dụ:

Dim bang As DataTable = dst.Tables(0)

If dst.Tables.CanRemove(bang) then

dst.Tables.Remove(bang)

End If

I.3.4. Xóa tất cả các bảng khỏi DataSet

Để xóa tất cả các bảng khỏi DataSet, chúng ta dùng các phương thức sau của tập hợp Tables.

Cú pháp:

<DataSet>.Tables.Clear()

I.3.5. Kiểm tra bảng có thuộc về DataSet

Cú pháp:

<DataSet>.Tables.Contains(<tên DataTable>)

Phương thức trả về True nếu trong Tables có DataTable có tên <tên DataTable>, ngược lại là False.

I.3.6. Lấy chỉ số của bảng

Cú pháp:

<DataSet>.Tables.IndexOf(<tên DataTable>)

Phương thức trả về chỉ số của DataTable có tên <tên DataTable>.

<DataSet>.Tables.IndexOf(<DataTable>)

Phương thức trả về chỉ số của <DataTable>.

I.3.7. Lấy số bảng chứa trong DataSet

Cú pháp:

<DataSet>.Tables.Count

I.3.8. Để kiểm tra dữ liệu của DataSet có thay đổi

Cú pháp:

<DataSet>.HasChanges()

Phương thức kiểm tra sự thay đổi của tất cả các dòng dữ liệu trên các bảng (thêm mới, xóa bỏ, sửa đổi) và trả về True nếu có, ngược lại False.

<DataSet>.HasChanges(<trạng thái dòng>)

Page 109: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 109/187

Phương thức kiểm tra sự thay đổi của tất cả các dòng dữ liệu trên các bảng có trạng thái như <trạng thái dòng> và trả về True nếu có, ngược lại False..

I.3.9. Lấy ra dòng dữ liệu đã thay đổi trong DataSet

Cú pháp:

<DataSet>.GetChanges()

Phương thức trả về bản sao của DataSet gồm những dòng dữ liệu đã bị thay đổi trên các bảng (do thêm mới, xóa bỏ, sửa đổi).

<DataSet>.GetChanges(<trạng thái dòng>)

Phương thức trả về bản sao của DataSet gồm những dòng dữ liệu đã bị thay đổi có trạng thái như <trạng thái dòng>.

Ví dụ:

Dim ds As DataSet

If dst.HasChanges() then ds = dst.GetChanges()

If dst.HasChanges(DataRowState.Modified) then

ds = dst.GetChanges(DataRowState.Modified)

End If

I.3.10. Để cập nhật các thay đổi trên DataSet

Cú pháp:

<DataSet>.AcceptChanges()

Phương thức cập nhật các thay đổi kể từ lúc lấy dữ liệu về hoặc từ lần gọi AcceptChanges trước.

Trên DataTable, DataRow cũng có phương thức tương ứng. Khi gọi AcceptChanges của DataSet sẽ kéo theo gọi AcceptChanges của DataTable, đến lượt kéo theo gọi AcceptChanges của DataRow.

I.3.11. Để hủy bỏ các thay đổi trên DataSet:

Cú pháp:

<DataSet>.RejectChanges()

Phương thức này của DataSet phục hồi tất cả các thay đổi kể từ lúc lấy dữ liệu về hoặc từ lần gọi AcceptChanges trước.

Khi gọi RejectChanges của DataSet sẽ kéo theo gọi RejectChanges của DataTable, DataRow.

I.3.12. Để trộn dữ liệu bên ngoài vào DataSet

Dữ liệu bên ngoài có thể là các dòng (mảng dòng), DataTable hoặc một DataSet khác.

Nguyên tắc của phương thức này như sau: khi được gọi, cấu trúc của nguồn và đích được so sánh với nhau. Nếu cấu trúc dữ liệu bên ngoài khác với cấu trúc của DataSet do thêm cột, các cột mới sẽ được thêm vào DataSet (tùy cú pháp) cùng với dữ liệu. Trên dữ liệu bên ngoài, những dòng có tình trạng Unchanged, Modified và Deleted phải có cột khóa chính như những dòng đã có trên DataSet. Những dòng có tình trạng Added (thêm mới) phải thỏa ràng buộc về khóa chính của DataSet.

Page 110: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 110/187

Trong quá trình trộn lẫn dữ liệu, các ràng buộc được bỏ qua: thuộc tính EnforceConstraints có giá trị False. Cuối quá trình, nếu ràng buộc nào không thể chuyển lại True sẽ làm phát sinh một Exception. Vì vậy, chúng ta cần giải quyết các vi phạm ràng buộc trước khi gán EnforceConstraints với giá trị True.

Phương thức này có rất nhiều cách sử dụng.

Cú pháp:

<DataSet>.Merge(<mảng dòng>)

Trộn một mảng các dòng vào DataSet.

<DataSet>.Merge(<DataTable>)

Trộn một DataTable bên ngoài vào DataSet.

<DataSet>.Merge(<DataSet>)

Trộn một Dataset bên ngoài vào DataSet.

<DataSet>.Merge(<DataSet>,<giữ thay đổi>)

Trộn một Dataset bên ngoài và cấu trúc của nó vào DataSet.

<giữ thay đổi>: nếu là True, các thay đổi từ bên ngoài được giữ nguyên trên DataSet, là False không thay đổi theo bên ngoài.

<DataSet>.Merge(<DataSet>,<giữ thay đổi>,<xử lý khi cấu trúc khác nhau>)

Trộn một Dataset bên ngoài và cấu trúc của nó vào DataSet.

<xử lý khi cấu trúc khác nhau>: tùy theo giá trị truyền vào.

<DataSet>.Merge(<mảng dòng>,<giữ thay đổi>,<xử lý khi cấu trúc khác nhau>)

Trộn một mảng dòng bên ngoài và cấu trúc của nó vào DataSet.

<DataSet>.Merge(<DataTable>,<giữ thay đổi>,<xử lý khi cấu trúc khác nhau>)

Trộn một DataTable bên ngoài và cấu trúc của nó vào DataSet.

Các giá trị của <xử lý khi cấu trúc khác nhau>

Tên Mô tả

Add Nếu khác nhau, thêm các cột mới vào cấu trúc của DataSet.

Error Nếu khác nhau phát sinh lỗi.

Ignore Nếu khác nhau, bỏ qua các cột mới.

I.3.13. Để hủy bỏ DataSet

Cú pháp:

<DataSet>.Dispose()

Khi được gọi, mọi tài nguyên trên vùng nhớ mà DataSet đang sử dụng sẽ được giải phóng.

I.3.14. Để tạo một quan hệ giữa hai bảng trong DataSet:

Để thiết lập quan hệ cha-con giữa hai bảng (DataTable) trong một DataSet, phải thỏa yêu cầu sau:

Page 111: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 111/187

Field hoặc các Field của bảng cha trong quan hệ phải thỏa yêu cầu tính duy nhất.

Chỉ có thể thiết lập quan hệ giữa hai bảng trong cùng DataSet

Chúng ta sử dụng phương thức Add của tập hợp Relations trong DataSet với các cú pháp sau.

Cú pháp:

<DataSet>.Relations.Add(<đối tượng DataRelation>)

<đối tượng DataRelation>: đối tượng này phải được tạo sẵn sẽ đề cập ở phần sau

<DataSet>.Relations.Add(<DataColumn trên bảng cha>, <DataColumn trên bảng con>)

<DataColumn trên bảng cha>, <DataColumn trên bảng con>: Các đối tượng này thuộc lớp DataColumn sẽ đề cập ở phần sau là các cột tham gia quan hệ trên bảng cha và bảng con tương ứng

<DataSet>.Relations.Add(<mảng DataColumn trên bảng cha>, _

<mảng DataColumn trên bảng con>)

<mảng DataColumn trên bảng cha>, <mảng DataColumn trên bảng con>: Các mảng này là mảng các cột tham gia quan hệ trên bảng cha và bảng con tương ứng.

<DataSet>.Relations.Add(<tên quan hệ>, <DataColumn trên bảng cha>, _

<DataColumn trên bảng con>)

<DataSet>.Relations.Add(<tên quan hệ>, <mảng DataColumn trên bảng cha>, _

<mảng DataColumn trên bảng con>)

<DataSet>.Relations.Add(<tên quan hệ>, <DataColumn trên bảng cha>, _

<DataColumn trên bảng con>, <tạo ràng buộc>)

<DataSet>.Relations.Add(<tên quan hệ>, <mảng DataColumn trên bảng cha>, _

<mảng DataColumn trên bảng con>, <tạo ràng buộc>)

Mặc định, khi tạo quan hệ giữa hai bảng, các ràng buộc đồng thời được tạo ra cho trên mỗi bảng như sau:

Ràng buộc duy nhất trên bảng cha dựa vào các cột của bảng cha tham gia vào quan hệ (nếu chưa có)

Ràng buộc khóa ngoại trên bảng con dựa vào các cột trên bảng cha và bảng con trong quan hệ.

Tham số <tạo ràng buộc> cho phép chúng ta quy định có tạo ràng buộc hay không: True có tạo, False không tạo.

I.3.15. Thêm nhiều quan hệ vào DataSet:

Muốn đưa nhiều quan hệ có sẵn vào DataSet, chúng ta dùng phương thức AddRange của tập hợp Relations.

Cú pháp:

<DataSet>.Relations.AddRange(<mảng quan hệ>)

<mảng quan hệ>: là một mảng các quan hệ đã tạo ra muốn đưa vào DataSet.

I.3.16. Xóa quan hệ khỏi DataSet

Để xóa một quan hệ khỏi DataSet, chúng ta dùng các phương thức sau của tập hợp Relations.

Page 112: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 112/187

Cú pháp:

<DataSet>.Relations.Remove(<quan hệ>)

Xóa <quan hệ> khỏi tập hợp Relations của Dataset.

<DataSet>.Relations.Remove(<tên quan hệ>)

Xóa quan hệ có tên là <tên quan hệ> khỏi tập hợp Relations.

<DataSet>.Relations.RemoveAt(<chỉ số>)

Xóa quan hệ có chỉ số là <chỉ số> khỏi tập hợp Relations.

Tuy nhiên, quan hệ có thể đang được sử dụng nên chúng ta cần kiểm tra xem có thể xóa được không với cú pháp:

<DataSet>.Relations.CanRemove(<quan hệ>)

Phương thức trả về True có thể xóa, ngược lại là False.

Để hủy tất cả các quan hệ trong DataSet, chúng ta dùng các phương thức sau của tập hợp Relations:

<DataSet>.Relations.Clear()

I.3.17. Kiểm tra quan hệ có thuộc về DataSet:

Cú pháp:

<DataSet>.Relations.Contains(<tên quan hệ>)

Phương thức trả về True nếu trong Relations có quan hệ tên <tên quan hệ>, ngược lại là False

II. DataTable Dữ liệu các bảng trong nguồn dữ liệu được lấy về và đưa vào các DataTable. DataTable thuộc không gian tên System.Data.DataTable

Có các cách khai báo như sau:

Cú pháp:

New DataTable()

New DataTable(<tên bảng>)

II.1. Các thuộc tính của DataTable Các thuộc tính

Tên Mô tả

CaseSensitive Qui định việc so sánh chuỗi trong bảng có phân biệt chữ Hoa chữ thường. True có phân biệt, False không phân biệt.

ChildRelations Trả về tập hợp những quan hệ trong đó DataTable đóng vai trò bảng cha (bảng một).

Columns Trả về tập hợp các cột trong DataTable (thuộc lớp DataColumn).

Constraints Trả về tập hợp các ràng buộc trong DataTable.

DataSet Trả về DataSet chứa DataTable.

Page 113: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 113/187

DefaultView Trả về DataView phát sinh từ DataTable.

HasErrors Cho biết có dòng nào trên DataTable bị lỗi : True có dòng bị lỗi, ngược lại là False.

ParentRelations Trả về tập hợp những quan hệ trong đó DataTable đóng vai trò bảng con (bảng nhiều).

PrimaryKey Mảng các cột có chức năng làm khóa chính của DataTable.

Rows Trả về tập hợp các dòng dữ liệu của DataTable.

TableName Tên của DataTable.

II.2. DataColumn Cấu trúc của bảng là tập hợp các DataColumn với các thuộc tính của chúng. Chúng ta có thể tạo cấu trúc của bảng từ cấu trúc bảng trong nguồn dữ liệu hoặc tạo lập từ các DataColumn.

DataColumn thuộc không gian tên System.Data.DataColumn

II.2.1. Các thuộc tính của DataColumn

Các thuộc tính

Tên Mô tả

AllowDBNull Thuộc tính cho biết cột có chấp nhận giá trị Null không (đọc ghi).

AutoIncrement Thuộc tính cho biết giá trị cột có tự động tăng khi thêm dòng mới không (đọc ghi)..

AutoIncrementSeed Giá trị bắt đầu cho cột khi thêm dòng đầu tiên, nếu AutoIncrement là True.

AutoIncrementStep Bước tăng cho dòng thêm mới kế tiếp, nếu AutoIncrement là True.

Caption Tiêu đề của cột.

ColumnName Tên cột.

DataType Kiểu dữ liệu của cột.

DefaultValue Giá trị mặc định cho cột khi thêm một dòng mới.

Expression Biểu thức dùng để tính giá trị cho cột

MaxLength Độ rộng tối đa cho cột kiểu chuỗi.

Ordinal Trả về số thứ tự của cột trong tập hợp DataColumn

ReadOnly Giá trị cho biết cột có được phép sửa đổi sau khi dòng mới được thêm vào.

Table Trả về DataTable chứa cột.

Unique Giá trị cho biết giá trị cột của mỗi dòng có phải là duy nhất.

II.2.2. Tạo mới DataColumn

Cú pháp:

New DataColumn()

New DataColumn(<tên cột>)

New DataColumn(<tên cột>,<kiểu dữ liệu>)

Page 114: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 114/187

New DataColumn(<tên cột>,<kiểu dữ liệu>,<biểu thức>)

<tên cột>: Tên muốn đặt cho cột

<kiểu dữ liệu>: Kiểu dữ liệu của cột.

<biểu thức>: Biểu thức tính giá trị cho cột

Kinh nghiệm giảng dạy:

Kiểu dữ liệu của DataColumn được khai báo thông qua cú pháp System.Type.GetType("<kiểu dữ liệu>")

Chuỗi kiểu dữ liệu phải đúng như không gian tên, tên lớp có phân biệt chử Hoa chữ thường Các khai báo sau đây sẽ bị lỗi: Dim cot As New DataColumn(“a”, System.Type.GetType(“System.string”))

Phải là System.String Dim cot As New DataColumn(“a”, System.Type.GetType(“String”))

Phải là System.String Dim cot As New DataColumn(“a”, System.Type.GetType(“System.Integer”))

Không có System.Integer nhưng System.Int32

Ví dụ:

Dim cotSL As New _

DataColumn("Soluong",System.Type.GetType("System.Double"))

Dim cotDG As New DataColumn("Dongia",System.Type.GetType("System.Double"))

Dim cotTT As New DataColumn("Thanhtien", _

System.Type.GetType("System.Double"),"Soluong * Dongia")

II.2.3. Sử dụng thuộc tính Expression

Để tạo thêm cột tính toán dựa trên các cột đã có, chúng ta có thể tạo thêm cột mới và sử dụng thuộc tính Expression để tính toán số liệu cho cột mới tạo này.

Thuộc tính Expression cho phép

Diễn dịch, tính toán dữ liệu từ các cột có sẵn trên DataTable

Ví dụ: Bang_dien_vien có cột Phai kiểu Boolean, chúng ta tạo thêm cột Gioi_tinh để hiển thị "Nam/Nữ"

Bang_dien_vien.Columns.Add("Gioi_tinh",Type. _

GetType("System.String"), "IIF(Phai,'Nam','Nữ')")

Hiển thị dữ liệu của các bảng khác trong cùng Dataset thông qua quan hệ

Ví dụ: Tạo thêm cột Ten_VK trên Bang_xuat_dien thông qua quan hệ VO_KICHXUAT_DIEN đã được tạo và sơ đồ quan hệ các bảng như sau

Page 115: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 115/187

Bang_xuat_dien.Columns.Add("Ten_VK",System.Type.GetType("System.String"),_

"Parent(VO_KICHXUAT_DIEN).Ten_VK")

Có thể sử dụng các hàm sau trong Expression

Các hàm sử dụng trong Expression

Tên Mô tả

CONVERT Chuyển đổi biểu thức sang kiểu dữ liệu của .Net FrameWork theo cú pháp CONVERT(<biểu thức>, <kiểu dữ liệu>) <biểu thức>: biểu thức cần chuyển đổi <kiểu dữ liệu>: kiểu dữ liệu muốn chuyển sang

LEN Lấy độ dài của chuỗi LEN(<biểu thức>)

ISNULL Kiểm tra biểu thức có trả về trị Null, nếu có hàm trả về giá trị thay thế, ngược lại trả về chính trị của biểu thức ISNULL(<biểu thức>, <giá trị thay thế>) <giá trị thay thế>: trị thay thế khi biểu thức là Null

IIF Sử dụng như hàm IIF của VB.NET IIF(<biểu thức luận lý>, <giá trị khi biểu thức đúng>, _ <giá trị khi biểu thức sai>)

TRIM Cắt các ký tự trắng ở hai đầu biểu thức TRIM(<biểu thức>)

SUBSTRING Lấy chuỗi con trong biểu thức SUBSTRING(<biểu thức>, <vị trí bắt đầu>, <số ký tự>) <vị trí bắt đầu>: vị trí bắt đầu chuỗi con trên biểu thức <số ký tự>: số ký tự sẽ lấy cho chuỗi con trên biểu thức

II.3. DataRow Dữ liệu lưu trữ trong DataTable qua các DataRow.

DataRow thuộc không gian tên System.Data.DataRow. Để tạo một DataRow chúng ta dùng phương thức AddNew của DataTable. Sau đây là các thuộc tính và các phương thức của DataRow

II.3.1. Các thuộc tính của DataRow

Các thuộc tính

Tên Mô tả

HasErrors Thuộc tính cho biết dòng có đang bị lỗi hay không. Item Nội dung dữ liệu lưu giữ của cột trên dòng có tên, cột datacolumn hay số thứ

tự cột truyền vào: <datarow>.Item(<tên>) <datarow>.Item(<cột>) <datarow>.Item(<chỉ số>) Nội dung dữ liệu lưu giữ của cột trên dòng có tên, datacolumn hay số thứ tự

Page 116: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 116/187

cột truyền vào , giá trị trả về theo phiên bản truyền vào: <datarow>.Item(<tên>,<phiên bản>) <datarow>.Item(<cột>,<phiên bản>) <datarow>.Item(<chỉ số>,<phiên bản>) Phiên bản có các trị sau : Current: Dòng chứa trị hiện hành. Default: Dòng chứa phiên bản mặc định. Đối với dòng có DataRowState là Added, Modified hoặc Current, phiên bản mặc định là Current. Đối với dòng có DataRowState là Deleted, phiên bản mặc định là phiên bản Original. Đối với dòng có DataRowState là Detached, phiên bản mặc định là phiên bản Proposed. Original: Dòng chứa trị gốc. Proposed: Dòng chứa trị đã chỉnh sửa

ItemArray Tất cả nội dung của DataRow dưới dạng một mảng.

RowError Mô tả nội dung lỗi của dòng, nếu đang bị lỗi.

RowState Trả về tình trạng của DataRow và có các trị sau : Added: Dòng đã được thêm vào tập hợp Rows nhưng chưa được cập nhật. Deleted: Dòng đã được đánh dấu hủy bằng phương thức Delete. Detached: Dòng không thuộc về tập hợp Rows gồm những dòng sau: Dòng đã được tạo mới nhưng chưa đưa vào tập hợp Rows Dòng đã bị loại bỏ khỏi tập hợp bằng phương thức Remove, RemoveAt của bảng Dòng đã bị đánh dấu hủy bằng Delete và sau đó đã gọi AcceptChanges của Datarow. Modified: Dòng đã được sửa đổi nhưng chưa được cập nhật. Unchanged: Dòng không thay đổi kể từ lúc đọc từ nguồn dữ liệu hoặc từ lần cập nhật trước.

Table Trả về tên bảng chứa DataRow.

II.3.2. Các phương thức của DataRow

Các phương thức

Tên Mô tả

BeginEdit Bắt đầu chỉnh sửa dòng. Trong chế độ này, mọi sự kiện tạm thời bị ngưng lại, các kiểm tra tạm thời bỏ qua. Khi người dùng bắt đầu thay đổi nội dung trên các điều khiển liên kết, phương thức này được ngầm gọi. Ở chế độ này, và khi EndEdit chưa được gọi, dòng sẽ mang trị các phiên bản Original (giá trị gốc) và Proposed (giá trị mới đề nghị). Có thể truy xuất các trị này thông qua thuộc tính Item(<cột>,<phiên bản>)

CancelEdit Hủy bỏ việc chỉnh sửa trên dòng.

Delete Đánh dấu hủy dòng. Khi phương thức được gọi, dòng có RowState là Deleted

EndEdit Chấm dứt việc chỉnh sửa.

GetChildRows Trả về các dòng có quan hệ nhánh con với dòng đang tham chiếu theo các cú pháp:

Page 117: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 117/187

GetChildRows(<đối tượng DataRelation>)

GetChildRows(<tên DataRelation>)

GetChildRows(<đối tượng DataRelation>, <phiên bản>)

GetChildRows(<tên DataRelation>, <phiên bản>)

GetParentRow Trả về dòng có quan hệ nhánh cha với đối tượng dòng đang tham chiếu theo các cú pháp:

GetParentRow(<đối tượng DataRelation>)

GetParentRow(<tên DataRelation>)

GetParentRow(<đối tượng DataRelation>, <phiên bản>)

GetParentRow(<tên DataRelation>, <phiên bản>)

IsNull Cho biết trị của cột truyền vào có mang trị Null.

IsNull(<DataColumn>)

IsNull(<chỉ số của DataColumn>)

IsNull(<tên DataColumn >)

IsNull(<DataColumn>, <phiên bản>)

RejectChanges Hủy bỏ các thay đổi từ lần cập nhật trước.

II.4. Constraint Constraint (ràng buộc) là một quy tắc áp dụng cho một hoặc nhiều cột để bảo đảm tính toàn vẹn dữ liệu trên DataTable.

Constraint thuộc không gian tên System.Data.Constraint

Có 2 loại Constraint:

System.Data.ForeignKeyConstraint: ràng buộc khóa ngoại

System.Data.UniqueConstraint: ràng buộc duy nhất

Những ràng buộc này do chúng ta tạo ra hoặc do thiết lập quan hệ giữa các bảng trong DataSet mà có. Chúng ta có thể không cho phát sinh ràng buộc bằng tham số <tạo ràng buộc> = False khi thiết lập quan hệ với phương thức <Dataset>.Relations.Add đã đề cập trong mục tạo quan hệ giữa hai DataTable trong một Dataset.

Do có 2 loại ràng buộc nên chúng ta có các cú pháp tạo mới khác nhau cho mỗi loại.

II.4.1. ForeignKeyConstraint

Cú pháp:

New ForeignKeyConstraint(<cột bảng cha>, <cột bảng con>)

New ForeignKeyConstraint(<tên>,<cột bảng cha>, <cột bảng con>)

New ForeignKeyConstraint(<mảng cột bảng cha>, _

<mảng cột bảng con>)

New ForeignKeyConstraint(<tên>, <mảng cột bảng cha>, _

<mảng cột bảng con>)

Page 118: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 118/187

<tên>: Tên ràng buộc khóa ngoại

<cột bảng cha>, <cột bảng con>: DataColumn trên DataTable cha, DataTable con tham gia khóa ngoại

<mảng cột bảng cha>, <mảng cột bảng con>: Mảng các DataColumn trên DataTable cha, DataTable con tham gia khóa ngoại

II.4.2. Các thuộc tính của ForeignKeyConstraint

Các thuộc tính

Tên Mô tả

AcceptRejectRule Qui định cách xử lý khi phương thức AcceptChanges trên DataTable cha xảy ra, gồm các trị :

Cascade : cập nhật dây chuyền trên bảng con

None : không làm gì cả.

Columns Trả về các cột tham gia khóa ngoại trên DataTable con

ConstraintName Tên của ràng buộc

DeleteRule Qui định cách xử lý khi một DataRow trên DataTable cha bị hủy, có các trị :

Cascade: Xóa các DataRow tương ứng trên DataTable con

None: Không làm gì cả.

SetDefault: Gán trị mặc định của DataColumn cho các dòng trên DataTable con liên quan đến dòng vừa bị xóa trên bảng cha

SetNull: Gán trị DBNull cho các dòng trên DataTable con ứng với dòng vừa bị xóa trên DataTable cha.

RelatedColumns Trả về các cột tham gia khóa ngoại trên DataTable cha.

RelatedTable Trả về DataTable cha.

Table Trả về DataTable con.

UpdateRule Qui định cách xử lý khi một dòng trên bảng cha thay đổi, có các trị:

Cascade: Cập nhật giá trị thay đổi trên DataTable cha vào các dòng tương ứng trên DataTable con

None: Không làm gì cả.

SetDefault: Gán trị mặc định của cột cho các dòng trên DataTable con ứng với dòng vừa thay đổi trên DataTable cha

SetNull: Gán trị DBNull cho các dòng trên DataTable con ứng với dòng vừa thay đổi trên DataTable cha.

II.4.3. UniqueConstraint

Cú pháp:

New UniqueConstraint(<tên>, <DataColumn>)

New UniqueConstraint(<DataColumn>)

New UniqueConstraint(<tên>, <mảng DataColumn>)

New UniqueConstraint(<mảng DataColumn>)

Page 119: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 119/187

New UniqueConstraint(<tên>, <mảng tên DataColumn>, <khoá chính>)

New UniqueConstraint(<tên>, <DataColumn>, <khoá chính>)

New UniqueConstraint(<tên DataColumn>, <khoá chính>)

New UniqueConstraint(<tên>, <mảng DataColumn>, <khoá chính>)

New UniqueConstraint(<mảng tên DataColumn>, <khoá chính>)

<tên> : tên ràng buộc duy nhất

<DataColumn> : DataColumn trên bảng muốn tạo khóa duy nhất

<mảng DataColumn> : mảng các DataColumn trên bảng muốn tạo khóa duy nhất

<khóa chính> : (True/False) là khóa chính trên bảng

II.4.4. Các thuộc tính của UniqueConstraint

Các thuộc tính

Tên Mô tả

Columns Trả về mảng các cột tham gia khóa duy nhất.

ConstraintName Tên ràng ruộc khóa duy nhất

IsPrimaryKey Khóa duy nhất có đồng thời là khóa chính không : True/False.

Table Trả về tên bảng chứa ràng buộc.

II.5. Tập hợp Columns Columns là tập hợp chứa các DataColumn trong cấu trúc của DataTable. Mọi tham chiếu đến DataColumn đều thông qua tập hợp này. Sau đây là một số chức năng của tập hợp Columns

II.5.1. Số cột trong tập hợp

Cú pháp:

<DataTable>.Columns.Count

II.5.2. Tham chiếu DataColumn trong tập hợp

Cú pháp:

<DataTable>.Columns.Item(<tên DataColumn muốn tham chiếu>)

<DataTable>.Columns.Item(<chỉ số DataColumn muốn tham chiếu>)

<DataTable>.Columns(<tên DataColumn muốn tham chiếu>)

<DataTable>.Columns(<chỉ số DataColumn muốn tham chiếu>)

II.5.3. Thêm DataColumn vào cấu trúc DataTable

Cú pháp:

<DataTable>.Columns.Add()

Tạo mới, đưa vào cấu trúc DataTable và trả về một DataColumn mới

<DataTable>.Columns.Add(<tên DataColumn>)

Page 120: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 120/187

Tạo và đưa vào cấu trúc DataTable, một DataColumn mới tên là tham số truyền vào

<DataTable>.Columns.Add(<DataColumn>)

Đưa vào cấu trúc DataTable DataColumn truyền vào

<DataTable>.Columns.Add(<tên DataColumn>,<kiểu dữ liệu>)

Tạo và đưa vào cấu trúc DataTable, một DataColumn mới tên là tham số truyền vào và có kiểu dữ liệu là kiểu truyền vào

<DataTable>.Columns.Add(<tên DataColumn>,<kiểu dữ liệu>,<biểu thức>)

Tạo và đưa vào cấu trúc DataTable, một DataColumn mới tên là tham số truyền vào, có kiểu dữ liệu là kiểu truyền vào và trị của DataColumn tính theo biểu thức truyền vào.

II.5.4. Thêm nhiều DataColumn vào cấu trúc DataTable

Cú pháp:

<DataTable>.Columns.AddRange(<mảng DataColumn>)

Đưa vào cấu trúc DataTable, mảng các DataColumn truyền vào.

II.5.5. Kiểm tra có thể loại bỏ DataColumn khỏi cấu trúc DataTable

Cú pháp:

<DataTable>.Columns.CanRemove(<DataColumn>)

Phương thức thực hiện một số kiểm tra như : DataColumn có thuộc về cấu trúc DataTable hay không, có liên quan đến ràng buộc hoặc quan hệ của DataTable không và trả về kết quả True/False.

II.5.6. Kiểm tra cấu trúc DataTable có DataColumn tên truyền vào

<DataTable>.Columns.Contains(<tên DataColumn>)

Phương thức trả về True/False. Chúng ta dùng phương thức kiểm tra này trước khi thực hiện một phương thức khác trên DataColumn

II.5.7. Hủy DataColumn khỏi cấu trúc DataTable

<DataTable>.Columns.Remove(<DataColumn>)

Hủy <DataColumn> khỏi cấu trúc DataTable

<DataTable>.Columns.Remove(<tên DataColumn>)

Hủy DataColumn có tên <tên DataColumn> khỏi cấu trúc DataTable

<DataTable>.Columns.RemoveAt(<chỉ số>)

Hủy DataColumn có chỉ số <chỉ số> khỏi cấu trúc DataTable

<DataTable>.Columns.Clear()

Hủy toàn bộ cấu trúc DataTable

Các phương thức trên sẽ gây lỗi nếu hủy DataColumn không được phép (CanRemove trả về False)

Page 121: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 121/187

II.5.8. Minh họa tạo cấu trúc DataTable

Ví dụ: Minh họa tạo cấu trúc các DataTable sau:

DataTable PHONGBAN gồm các thông tin Mã phòng ban, Tên phòng ban.

DataTable NHANVIEN gồm các thông tin Mã số NV, Họ, Tên, Phái, Ngày sinh, Hệ số lương, thuộc phòng ban nào.

Imports System.Data

Dim bang_phong As New DataTable("PHONGBAN")

Dim cot_Ma, cot_Ten As DataColumn

cot_Ma = New DataColumn("Mapb", Type.GetType("System.String"))

cot_Ma.MaxLength = 2

cot_Ten = New DataColumn("Ten_phong", Type.GetType("System.String"))

cot_Ten.MaxLength = 30

bang_phong.Columns.AddRange(New DataColumn(){cot_Ma,cot_Ten})

bang_phong.PrimaryKey = New DataColumn(){cot_Ma}

Dim bang_nhan_vien As New DataTable("NHANVIEN")

Dim cot(2) As DataColumn

cot(0) = New DataColumn("Manv", Type.GetType("System.String"))

cot(1) = New DataColumn("Honv", Type.GetType("System.String"))

cot(2) = New DataColumn("Tennv", Type.GetType("System.String"))

cot(0).MaxLength = 4

cot(1).MaxLength = 25

cot(2).MaxLength = 10

cot(0).AllowDBNull = False

cot(0).Unique = True

bang_nhan_vien.Columns.AddRange(a)

bang_nhan_vien.Columns.Add("Phai", Type.GetType("System.Boolean"))

bang_nhan_vien.Columns.Add("Ngaysinh", Type.GetType("System.DateTime"))

bang_nhan_vien.Columns.Add("Hsluong", Type.GetType("System.Single"))

bang_nhan_vien.Columns.Add("Mapb", Type.GetType("System.String"))

bang_nhan_vien.Columns("Mapb").MaxLength = 2

II.6. Tập hợp Rows Rows là tập hợp các dòng dữ liệu của DataTable. Mọi tham chiếu đến DataRow đều thông qua tập hợp này. Sau đây là một số chức năng của tập hợp Rows:

II.6.1. Số DataRow trong tập hợp

Cú pháp:

<DataTable>.Rows.Count

Page 122: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 122/187

II.6.2. Tham chiếu DataRow trong tập hợp

Cú pháp:

<DataTable>.Rows.Item(<chỉ số DataRow muốn tham chiếu>)

<DataTable>.Rows(<chỉ số DataRow muốn tham chiếu>)

II.6.3. Truy xuất trị của ô trên một DataRow

Cú pháp:

<DataTable>.Rows.Item(<chỉ số dòng>)(<chỉ số cột>)

<DataTable>.Rows(<chỉ số dòng>)(<chỉ số cột>)

Các cách sau áp dụng cho cả hai cách thông qua Item và không có Item

<DataTable>.Rows(<chỉ số dòng>)(<tên cột>)

<DataTable>.Rows(<chỉ số dòng>)(<cột>)

<DataTable>.Rows(<chỉ số dòng>)(<chỉ số cột>,<phiên bản>)

<DataTable>.Rows(<chỉ số dòng>)(<tên cột>,<phiên bản>)

<DataTable>.Rows(<chỉ số dòng>)(<cột>,<phiên bản>)

II.6.4. Thêm DataRow vào DataTable

Cú pháp:

<DataTable>.Rows.Add(<DataRow>)

Thêm một dòng có sẵn vào DataTable.

<DataTable>.Rows.Add(<mảng trị>)

Tạo một dòng mới với các trị trong mảng trị ứng với thứ tự các DataColumn và đưa vào tập hợp Rows của DataTable.

II.6.5. Để chèn dòng vào DataTable tại một vị trí

Cú pháp:

<DataTable>.Rows.InsertAt(<DataRow>,<vị trí>)

Chèn một DataRow có sẵn vào DataTable tại <vị trí>.

Nếu <vị trí> lớn hơn số dòng của DataTable, dòng mới được thêm vào vị trí cuối DataTable.

II.6.6. Hủy DataRow trên DataTable

Cú pháp:

<DataTable>.Rows.Remove(<DataRow>)

Hủy <DataRow> khỏi tập hợp Rows của DataTable.

<DataTable>.Rows.RemoveAt(<chỉ số>)

Hủy DataRow tại vị trí <chỉ số> khỏi DataTable

Phương thức trên là tương tự gọi phương thức Delete và AcceptChanges của Datarow

Page 123: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 123/187

<DataTable>.Rows.Clear()

Hủy toàn bộ các dòng dữ liệu của DataTable

II.6.7. Để kiểm tra trên khóa chính có chứa trị truyền vào

Cú pháp:

<DataTable>.Rows.Contains(<trị>)

Phương thức kiểm tra trên cột khóa chính xem có dòng nào chứa <trị> và trả về True nếu tìm thấy, ngược lại trả về False

<DataTable>.Rows.Contains(<mảng trị>)

Phương thức kiểm tra trên các cột khóa chính có dòng nào chứa bộ giá trị <mảng trị> và trả về True nếu tìm thấy, ngược lại trả về False. Thứ tự trị truyền vào phải theo thứ tự các cột khóa trên DataTable.

II.6.8. Tìm DataRow có khóa chính chứa trị truyền vào

Cú pháp:

<DataTable>.Rows.Find(<trị>)

Phương thức trả về dòng chứa <trị> trên cột khóa chính. Nếu không tìm thấy trả về Nothing

<DataTable>.Rows.Find(<mảng trị>)

Phương thức trả về DataRow chứa bộ giá trị <mảng trị> trên các cột khóa chính. Thứ tự trị truyền vào phải theo thứ tự các cột khóa trên DataTable.

II.6.9. Minh họa tạo thao tác với tập hợp Rows

Ví dụ sau đây sẽ sử dụng cấu trúc của DataTable PHONGBAN, NHANVIEN phần trên và thêm vào các mẩu tin.

Ví dụ:

bang_phong.Rows.Add(New Object(){"HC", "Hành chánh"})

bang_phong.Rows.Add(New Object(){"TC", "Tổ chức"})

Dim dong As DataRow = bang_nhan_vien.NewRow()

dong(0)= "A001"

dong(1)= "Nguyễn Văn"

dong(2)= "Ba"

dong(3)= True

dong(4)= #12/10/1980#

dong(5)= 1.25

dong(6)= "HC"

bang_nhan_vien.Rows.Add(dong)

bang_nhan_vien.Rows.Add(New Object(){"A002", "Trần Công", "Minh", True, _

"25/04/1977", 1.75, "TC"})

Dim nv() As Object = New Object(){"A003", "Lê Thị Kim", "Hương", False, _

Page 124: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 124/187

"05/09/1982", 1.25, "HC"}

bang_nhan_vien.Rows.Add(nv)

' Tìm nhân viên có mã là “A001”, nếu tìm thấy hủy nhân viên đó

If bang_nhan_vien.Rows.Contains(“A001”) then

Dim dg As DataRow = bang_nhan_vien.Rows.Find(“A001”)

' Để đánh dấu hủy

dg.Delete()

' Nếu muốn loại bỏ hẳn khỏi DataTable

' bang_nhan_vien.Rows.Remove(dg)

End If

II.7. Tập hợp Constraints Minh họa tạo thao tác với tập hợp Constraints

Ví dụ: Sử dụng cấu trúc của DataTable PHONGBAN, NHANVIEN ở trên

' tạo ràng buộc duy nhất là khóa chính cho DataTable PHONGBAN

bang_phong.Constraints.Add("Khoa", bang_phong.Columns("Mapb"), True)

' tạo một ràng buộc duy nhất trên cột Manv của DataTable NHANVIEN

Dim khoa_duy_nhat As New UniqueConstraint( bang_nhan_vien.Columns("Manv"))

' tạo ràng buộc khóa ngoại trên cột Mapb của PHONGBAN và Mapb của NHANVIEN

Dim khoa_ngoai as New ForeignKeyConstraint(bang_phong.Columns(“Mapb”), _

bang_nhan_vien.Columns("Mapb"))

' Đưa hai ràng buộc vừa tạo vào tập hợp Constraints

bang_nhan_vien.Constraints.Add(khoa_duy_nhat)

bang_nhan_vien.Constraints.Add(khoa_ngoai)

II.8. Một số phương thức của DataTable

II.8.1. Để phát sinh một dòng mới có cấu trúc của DataTable

Cú pháp:

<DataTable>.NewRow()

Phương thức này trả về một DataRow mới có cấu trúc như của DataTable với các giá trị mặc định nhưng chưa đưa vào tập hợp Rows (nghĩa là chưa thuộc về DataTable, có trạng thái là Detached). Và một khi được đưa vào tập hợp sẽ có trạng thái là Added.

II.8.2. Hủy tất cả các dòng dữ liệu trên DataTable

Cú pháp:

<DataTable>.Clear()

II.8.3. Sao chép cấu trúc, ràng buộc của DataTable thành DataTable khác

Cú pháp:

Page 125: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 125/187

<DataTable>.Clone()

Phương thức trả về một DataTable đã có sẵn cấu trúc và ràng buộc của DataTable nhưng không có dữ liệu

II.8.4. Sao chép cấu trúc, ràng buộc và dữ liệu của DataTable thành DataTable khác

Cú pháp:

<DataTable>.Copy()

Phương thức trả về một DataTable đã có sẵn cấu trúc, ràng buộc và dữ liệu của DataTable. DataTable trả về có cùng cấp với DataTable - nếu DataTable là đối tượng của một lớp kế thừa, DataTable trả về cũng thuộc lớp đó.

II.8.5. Để lấy ra một bản sao những thay đổi trên DataTable

Cú pháp:

<DataTable>.GetChanges()

Phương thức trả về một DataTable gồm những dòng dữ liệu đã thay đổi kể từ lần lấy dữ liệu từ nguồn về hoặc từ lần cập nhật trước vào DataTable bằng Phương thức AcceptChanges.

<DataTable>.GetChanges(<trạng thái DataRow>)

Như trên nhưng chỉ trả về những dòng có tình trạng đúng với <trạng thái DataRow>.

II.8.6. Lấy ra một mảng các dòng bị lỗi trên DataTable

Cú pháp:

<DataTable>.GetErrors()

Phương thức trả về một mảng các DataRow bị lỗi. Phương thức này được gọi sau khi gọi GetChanges nhằm phát hiện các dòng bị lỗi để xử lý.

II.8.7. Cập nhật các thay đổi vào DataTable

Cú pháp:

<DataTable>.AcceptChanges()

Phương thức cập nhật các thay đổi kể từ lần cập nhật trước hoặc khi DataTable được mở vào chính nó. Sau khi thực hiện tất cả các DataRow đều có trạng thái Unchanged. Những DataRow có trạng thái Deleted bị loại bỏ khỏi DataTable.

II.8.8. Hủy bỏ các thay đổi của DataTable

Cú pháp:

<DataTable>.RejeptChanges()

Phương thức phục hồi lại các giá trị kể từ lần cập nhật trước hoặc khi DataTable được mở vào chính DataTable. Sau khi thực hiện, tất cả các dòng mới thêm vào đều bị loại bỏ. Những DataRow có trạng thái Deleted, Modified được phục hồi lại tình trạng gốc.

Page 126: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 126/187

II.8.9. Tính toán trên các DataRow của DataTable

Cú pháp:

<DataTable>.Compute(<biểu thức tính toán>,<biểu thức lọc>)

Phương thức thực hiện tính toán theo <biểu thức tính toán> trên những dòng thỏa điều kiện của <biểu thức lọc> và trả về giá trị tính toán được kiểu Object.

Trong <biểu thức tính toán>, phải có hàm thống kê (Count, Sum,…)

<biểu thức lọc> : phải có dạng <tên cột> <toán tử> <giá trị>

Ví dụ: Dựa DataTable NHANVIEN ở trên, để đếm các nhân viên nữ thuộc phòng Hành chánh

Dim sonvNu = dt.Compute("Count(Manv)", "Phai = False And Mapb = 'HC'")

II.8.10. Chọn các DataRow của DataTable

Cú pháp:

<DataTable>.Select()

Phương thức trả về mảng các DataRow trên DataTable theo thứ tự của khóa chính nếu có.

Select(<biểu thức lọc>)

Phương thức trả về mảng các DataRow trên DataTable thỏa điều kiện của <biểu thức lọc> theo thứ tự của khóa chính nếu có.

Select(<biểu thức lọc>, <biểu thức sắp xếp>)

Phương thức trả về mảng các DataRow trên DataTable thỏa điều kiện của <biểu thức lọc> theo thứ tự của <biểu thức sắp xếp>.

Select(<biểu thức lọc>, <biểu thức sắp xếp>,<trạng thái dòng>)

Phương thức trả về mảng các DataRow trên DataTable thỏa điều kiện của <biểu thức lọc> theo thứ tự của <biểu thức sắp xếp> và có RowState ứng với tham số <trạng thái dòng>.

Ví dụ: Dựa DataTable NHANVIEN ở trên, chọn ra các nhân viên thuộc phòng Hành chánh

Dim dong() As DataRow = bang_nhan_vien.Select("Mapb = 'HC'")

Chọn và sắp xếp

Dim dong() As DataRow = bang_nhan_vien.Select("Mapb = 'HC'", _

"ngaysinh DESC")

II.9. Các sự kiện của DataTable Các sự kiện

Tên Mô tả

ColumnChanged Sự kiện xảy ra sau khi giá trị trên cột của một dòng đã thay đổi. Tham số EventArgs chứa thông tin:

Column: DataColumn thay đổi

ProposedValue: giá trị thay đổi của DataColumn

Page 127: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 127/187

Row: DataRow có cột thay đổi

ColumnChanging Sự kiện xảy ra khi giá trị trên cột của một DataRow đang thay đổi. Tham số EventArgs chứa thông tin như ColumnChanged

RowChanged Sự kiện xảy ra sau khi một DataRow đã thay đổi thành công (không phát sinh Exception) Tham số EventArgs chứa thông tin:

Action: hành động đã xảy ra trên dòng

Row: dòng có hành động xảy ra

RowChanging Sự kiện xảy ra khi một dòng đang thay đổi. Tham số EventArgs chứa thông tin như RowChanged

RowDeleted Sự kiện xảy ra sau khi một dòng trên DataTable đã bị đánh dấu hủy. Tham số EventArgs chứa thông tin như RowChanged

RowDeleting Sự kiện xảy ra trước khi một dòng trên DataTable bị đánh dấu hủy. Tham số EventArgs chứa thông tin như RowChanged

III. DataRelation DataSet quản lý quan hệ giữa các DataTable trong DataSet qua tập hợp Relations. Đây là những đối tượng DataRelation chứa thông tin về mối quan hệ đã tạo ra trong DataSet.

Quan hệ giữa hai DataTable nói lên sự liên quan của một dòng (DataRow) trên DataTable cha với các DataRow trên DataTable con. Do đó, chúng ta có thể thấy được mối quan hệ đó qua việc hiển thị dữ liệu các dòng tương ứng trên DataTable con (một cách tự động qua việc liên kết lưới DataTable con với quan hệ đã tạo) khi dòng hiện hành trên DataTable cha thay đổi.

Ràng buộc, ngược lại, nhằm bảo vệ tính toàn vẹn dữ liệu thông qua mối quan hệ sẽ kiểm tra sự tồn tại của DataRow bên DataTable cha khi thêm, sửa trên DataTable con hoặc kiểm tra tồn tại các dòng con khi hủy trên DataTable cha

DataRelation thuộc tên lớp System.Data.DataRelation

III.1. Khởi tạo Ngoài cách tạo quan hệ qua tập hợp Relations của DataSet đã đề cập ở phần trước, còn có các cách khởi tạo sau:

Cú pháp:

New DataRelation(<tên>, <cột DataTable cha>, <cột DataTable con>)

New DataRelation(<tên>, <mảng cột DataTable cha>, _

<mảng cột DataTable con>)

New DataRelation(<tên>, <cột DataTable cha>, <cột DataTable con>, _

<tạo ràng buộc>)

New DataRelation(<tên>, <mảng cột DataTable cha>, _

<mảng cột DataTable con>, <tạo ràng buộc>)

<tạo ràng buộc>: Có giá trị True/False cho biết khi thiết lập quan hệ sẽ tạo luôn các ràng buộc hay

Page 128: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 128/187

không (xem phần tạo DataRelation giữa 2 DataTable trên DataSet)

Kinh nghiệm giảng dạy:

Chỉ có thể thiết lập quan hệ giữa hai DataTable chỉ khi hai DataTable đó thuộc về một DataSet

III.2. Các thuộc tính của DataRelation Các thuộc tính

Tên Mô tả

ChildColumns Trả về các DataColumn trên DataTable con tham gia trong DataRelation.

ChildKeyConstraint Trả về ràng buộc khóa ngoại của DataRelation.

ChildTable Trả về DataTable con trong DataRelation.

DataSet Trả về DataSet chứa DataRelation.

ParentColumns Trả về các cột trên DataTable cha tham gia trong DataRelation.

ParentKeyConstraint Trả về ràng buộc duy nhất bảo đảm giá trị cột trên DataTable cha trong DataRelation có trị duy nhất.

ParentTable Trả về DataTable cha trong DataRelation.

RelationName Tên DataRelation (đọc ghi)

III.3. Minh họa thiết lập quan hệ Ví dụ sau đây sẽ sử dụng bang_phong_ban, bang_nhan_vien ở phần trên để thiết lập quan hệ giữa cột Mapb của bang_phong_ban với Mapb của bang_nhan_vien.

Ví dụ: Dựa DataTable NHANVIEN ở trên, chọn ra các nhân viên thuộc phòng Hành chánh

Đưa hai bảng vào một DataSet:

Dim dst As New DataSet()

dst.Tables.AddRange(New DataTable(){bang_phong,bang_nhan_vien})

Sau đó, có thể sử dụng một trong các cách sau:

Dim rel As New DataRelation("PB_NV", bang_phong.Columns("Mapb"), _

bang_nhan_vien.Columns(“Mapb”))

dst.Relations.Add(rel)

Hoặc:

dst.Relations.Add("PB_NV", bang_phong.Columns("Mapb"), _ bang_nhan_vien.Columns(“Mapb”))

Hoặc:

bang_phong.ChildRelations.Add("PB_NV", bang_phong.Columns("Mapb"), _

bang_nhan_vien.Columns(“Mapb”))

Hoặc:

bang_nhan_vien.ParentRelations.Add("PB_NV", bang_phong.Columns("Mapb"), _

Page 129: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 129/187

bang_nhan_vien.Columns(“Mapb”))

IV. DataView Trong các đối tượng chúng ta đã tìm hiểu, vẫn còn thiếu một số chức năng như tìm kiếm với ý nghĩa định vị trí, sắp xếp, lọc dữ liệu…ADO.Net đưa ra DataView như một đối tượng thuận tiện cho việc liên kết dữ liệu với các điều khiển, sắp xếp…nhằm bổ sung cho những yêu cầu trên và cung cấp cho chúng ta một cách hiển thị dữ liệu tùy biến của DataTable.

Với chức năng hiển thị dữ liệu tùy biến, DataView cho phép hiển thị dữ liệu của một DataTable qua các điều khiển khác nhau với các số liệu khác nhau như dùng một điều khiển hiển thị tất cả các dòng dữ liệu trên DataTable và một điều khiển khác hiển thị dữ liệu của những dòng đã bị đánh dấu hủy cũng của DataTable đó …

Mặc định mỗi DataTable có sẵn một DataView thông qua thuộc tính DefaultView.

DataView thuộc tên lớp System.Data.DataView

IV.1. Khởi tạo Cú pháp:

New DataView()

Tạo một đối tượng DataView mới

New DataView(<DataTable>)

Tạo một đối tượng DataView mới từ <DataTable>

New DataView(<DataTable>,<biểu thức lọc>, <biểu thức sắp xếp>, _

<trạng thái dòng>)

Tạo một DataView mới từ <DataTable> gồm những dòng thoả điều kiện <biểu thức lọc> và có tình trạng như <trạng thái dòng>, được hiển thị theo cách sắp xếp <biểu thức sắp xếp>

IV.2. Các thuộc tính chính của DataView Các thuộc tính

Tên Mô tả

AllowDelete Giá trị cho biết thao tác xóa dòng trên DataView có được phép không (đọc ghi).

AllowEdit Giá trị cho biết thao tác sửa đổi trên DataView có được phép không (đọc ghi).

AllowNew Giá trị cho biết thao tác thêm mới với Phương thức AddNew trên DataView có được phép không (đọc ghi).

Count Số mẩu tin trên DataView sau khi áp dụng thuộc tính RowFilter và RowStateFilter.

Item Trả về một dòng dữ liệu trên bảng theo tham số truyền vào.

RowFilter Biểu thức lọc của DataView để thay đổi dữ liệu hiển thị.

RowStateFilter Giá trị cho biết trạng thái dòng dữ liệu đang hiển thị trên DataView gồm các

Page 130: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 130/187

trị sau:

Added: Dòng mới thêm vào chưa cập nhật.

CurrentRows: Dòng hiện hành bao gồm những dòng không thay đổi, dòng mới và dòng đã thay đổi.

Deleted: Dòng đánh dấu hủy.

ModifiedCurrent: Dòng đã được thay đổi và giá trị hiển thị là phiên bản hiện hành, tức phiên bản đã sửa đổi từ dữ liệu gốc.

ModifiedOriginal: Dòng đã được thay đổi và giá trị hiển thị là phiên bản gốc.

None: Không gì cả.

OriginalRows: Dòng gốc bao gồm các dòng không thay đổi và dòng đã đánh dấu hủy.

Unchanged: Dòng không thay đổi.

Sort Tên cột hoặc các cột của DataTable dùng sắp xếp dữ liệu trên Dataview ngăn cách nhau bằng dấu phẩy (đọc ghi). Nếu sắp xếp tăng không ghi thêm gì hoặc "ASC", sắp xếp giảm thêm "DESC"

Table DataTable (đọc ghi) mà DataView đang lấy dữ liệu

IV.3. Các thao tác chính của DataView

IV.3.1. Thêm một dòng mới trên DataView

Cú pháp:

<DataView>.Add()

Phương thức trả về một DataRowView (sẽ đề cập đến phần sau).

IV.3.2. Đánh dấu hủy một dòng trên DataView

Cú pháp:

<DataView>.Delete(<chỉ số>)

Phương thức thực hiện đánh dấu hủy dòng trên DataView có chỉ số truyền vào. Sau khi thực hiện, dòng có trạng thái là Deleted và có thể phục hồi bằng RejectChanges.

IV.3.3. Tìm kiếm trên DataView

Cú pháp:

<DataView>.Find(<giá trị>)

Phương thức thực hiện tìm kiếm <giá trị> trên DataView và trả về chỉ số của dòng đầu tiên thỏa giá trị tìm. DataView phải được sắp xếp trên cột muốn tìm kiếm.

<DataView>.Find(<mảng giá trị>)

Phương thức thực hiện tìm kiếm <mảng giá trị> trên các cột tương ứng của DataView và trả về chỉ số của dòng đầu tiên thỏa giá trị tìm. DataView phải được sắp xếp trên các cột có trị muốn tìm kiếm.

Nếu tìm thấy, phương thức trả về chỉ số dòng tìm thấy, ngược lại không tìm thấy trả về -1

Page 131: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 131/187

<DataView>.FindRows(<giá trị>)

Phương thức thực hiện tìm kiếm <giá trị> trên DataView và trả về những dòng thỏa giá trị tìm. DatView phải được sắp xếp trên cột muốn tìm kiếm.

<DataView>.FindRows(<mảng giá trị>)

Phương thức thực hiện tìm kiếm <mảng giá trị> trên các cột tương ứng của DataView và trả về những dòng thỏa giá trị tìm. DataView phải được sắp xếp trên các cột có trị muốn tìm kiếm.

Nếu tìm thấy, phương thức trả về mảng các dòng thỏa điều kiện, ngược lại trả về mảng không có phần tử nào

Ví dụ : Để tìm kiếm nhân viên có họ “Lê Công”, tên “Minh” trên bang_nhan_vien đề cập ở trên

Dim dv As DataView = bang_nhan_vien.DefaultView

dv.Sort = "Honv,Tennv"

Dim vitri as Integer = dv.Find(New Object(){"Lê Công", "Minh"})

If vitri > -1 then

Console.WriteLine("Tìm thấy tại dòng thứ {0}", vitri )

Else

Console.WriteLine("Không tìm thấy")

End If

IV.4. DataRowView Tương tự DataRow trên DataTable, DataRowView là một cách hiển thị của DataRow theo phiên bản (xin xem phần dưới) trên DataView.

Khi liên kết với một điều khiển dữ liệu, chỉ có một phiên bản của DataRowView được hiển thị. Các phiên bản đó là Default, Original, Current, và Proposed như của DataRow.

Chỉ có thể tạo DataRowView bằng phương thức AddNew của DataView

IV.4.1. Các thuộc tính của DataRowView

Các thuộc tính

Tên Mô tả

DataView Trả về DataView chứa DataRowView.

IsEdit Cho biết dòng có đang ở trong trạng thái chỉnh sửa.

IsNew Cho biết dòng có phải là dòng mới thêm vào.

Item Giá trị của dòng trên cột truyền vào dưới hình thức tên cột hoặc chỉ số cột

Row Trả về DataRow tương ứng trên DataTable.

RowVersion Trả về phiên bản hiện hành trên dòng với các trị:

Default: Giá trị hiện hành là giá trị mặc định

Original: Giá trị hiện hành là giá trị gốc

Current: Giá trị trên dòng là giá trị hiện hành

Proposed: Giá trị trên dòng là giá trị đang chỉnh sửa.

Thuộc tính này cho biết giá trị hiện hành đang là giá trị của phiên bản nào.

Page 132: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 132/187

Các yếu tố sau giúp xác định phiên bản:

Sau khi phương thức BeginEdit được gọi, nếu chúng ta thay đổi giá trị chỉ có thể có các phiên bản Current và Proposed.

Sau khi phương thức CancelEdit được gọi, không còn giá trị Proposed.

Sau khi phương thức EndEdit được gọi, giá trị Proposed trở thành giá trị Current.

Sau khi phương thức AcceptChanges được gọi, giá trị Current trở thành giá trị Original.

IV.4.2. Các phương thức của DataRowView

Các phương thức

Tên Mô tả

BeginEdit Bắt đầu giai đoạn chỉnh sửa trên dòng. Sau khi giá trị thay đổi, để truy xuất giá trị mới, chúng ta phải tham chiếu qua RowVersion là DataRowVersion.Proposed

CancelEdit Sau khi phương thức BeginEdit được gọi, những thay đổi trên DataRowView có thể hủy bỏ bằng phương thức CancelEdit.

CreateChildView Trả về một DataView gồm những dòng trên DataTable con thông qua DataRelation ứng với DataRowView . Có các cú pháp sau :

<DataRowView>.CreateChildView(<DataRelation>)

<DataRowView>.CreateChildView(<tên DataRelation>)

Delete Đánh dấu hủy bỏ dòng. Dòng chưa thực sự bị hủy cho đến khi phương thức AcceptChanges của bảng được gọi.

EndEdit Chấm dứt giai đoạn chỉnh sửa và cập nhật các thay đổi trên dòng.

Page 133: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 133/187

Bài 7

XÂY DỰNG CÁC LỚP XỬ LÝ

Tóm tắt Lý thuyết 3 tiết - Thực hành 10 tiết

Mục tiêu Các mục chính Bài tập

Kết thúc bài học này, học viên có thể xây dựng các lớp xử lý sử dụng trong mô hình lập trình dữ liệu

1. Mô hình đa tầng

2. Xây dựng lớp xử lý lưu trữ

3. Xây dựng lớp xử lý nghiệp vụ

5.3, 5.4, 5.5

Page 134: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 134/187

I. Mô hình đa tầng (N-tier)

Trong mô hình này, ứng dụng được phân chia thành nhiều tầng với các chức năng khác nhau:

Tầng xử lý thể hiện có chức năng hiển thị thông tin ra màn hình giao tiếp và tiếp nhận thông tin từ người dùng

Tầng xử lý nghiệp vụ cung cấp và xử lý thông tin của dữ liệu từ hai tầng kế cận (thể hiện và lưu trữ)

Tầng xử lý lưu trữ có chức năng truy xuất và cập nhật thông tin vào nguồn dữ liệu (đọc/ghi)

Vì tính độc lập của các tầng, mô hình này thích hợp cho việc xây dựng ứng dụng khi thay đổi nguồn dữ liệu, môi trường lập trình, … và tận dụng được khả năng tái sử dụng.

Có nhiều hình thức xây dựng lớp cho mỗi tầng, nhưng trong phạm vi giáo trình này, chúng tôi sẽ sử dụng nguyên tắc kế thừa nhằm thuận lợi cho học viên trong khi triển khai

II. Xây dựng lớp xử lý lưu trữ Đây là lớp làm việc trực tiếp với nguồn dữ liệu. Với vai trò đọc dữ liệu về cho ứng dụng cũng như cập nhật các thay đổi từ phía người dùng vào nguồn dữ liệu, lớp sẽ có các thuộc tính, chức năng hổ trợ cho các vai trò này. Khi tạo lớp, cần thực hiện:

Phân chia các Region để tiện việc quản lý các thuộc tính, sự kiện và phương thức

Truy xuất dữ liệu của bảng được thực hiện thông qua DefaultView của DataTable

Người

Xử lý thể hiện

Xử lý nghiệp vụ

Dữ liệu

Xử lý lưu trữ

Page 135: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 135/187

II.1. Các khai báo Đây là nhóm khai báo các biến thành viên, hằng cần sử dụng bên trong lớp và thường được khai báo với từ khóa Private:

Khai báo đối tượng truy xuất cập nhật dữ liệu(DataAdapter): đối tượng này đóng vai trò đọc ghi dữ liệu cho lớp xử lý lưu trữ

Biến chuỗi chứa nội dung truy vấn dữ liệu

Biến chuỗi chứa tên bảng muốn truy vấn dữ liệu

Biến đối tượng dùng chung kết nối đến nguồn dữ liệu.

Ví dụ:

Imports System.Data

Imports System.Data.OleDb

Module PHAN_MEM

Public Const Chuoi_lien_ket As String = _

"Provider=Microsoft.JET.OLEDB.4.0;"

End Module

Public Class XL_BANG

Inherits DataTable

#Region "Khai báo cục bộ "

' Khai báo đối tượng đọc ghi dữ liệu trên CSDL

Private WithEvents mBo_doc_ghi As OleDbDataAdapter

' Khai báo biến chuỗi chứa nội dung truy vấn dữ liệu

Private mChuoi_SQL As String

' Khai báo biến chuỗi chứa tên bảng muốn truy vấn dữ liệu

Private mTen_bang As String

' Khai báo biến đối tượng dùng chung kết nối đến nguồn dữ liệu

Private Shared mKet_noi As OleDbConnection

#End Region

. . .

End Class

II.2. Khai báo các thuộc tính Đây là phần khai báo các thuộc tính của lớp xử lý lưu trữ cho phép truy xuất từ bên ngoài lớp thường được khai báo với từ khóa Public:

Ví dụ: XL_BANG: phần khai báo các thuộc tính

#Region " Khai báo các thuộc tính "

' Giá trị của thuộc tính này cần được khởi tạo trước khi sử dụng

Page 136: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 136/187

Public Shared Chuoi_CSDL As String

' Thuộc tính cho phép đọc và ghi nội dung truy vấn dữ liệu cần thực hiện cho thể hiện

Public Property Chuoi_SQL() As String

Get

Return mChuoi_SQL

End Get

Set(ByVal Value As String)

mChuoi_SQL = Value

End Set

End Property

' Thuộc tính cho phép truy xuất và gán tên bảng muốn truy vấn dữ liệu

Public Property Ten_bang() As String

Get

Return mTen_bang

End Get

Set(ByVal Value As String)

mTen_bang = Value

End Set

End Property

' Thuộc tính chứa đối tượng kết nối đến nguồn dữ liệu

Public Shared Property Ket_noi() As OleDbConnection

Get

Return mKet_noi

End Get

Set(ByVal Value As OleDbConnection)

mKet_noi = Value

End Set

End Property

' Thuộc tính chỉ đọc cho biết số dòng trên DefaultView của DataTable

Public ReadOnly Property So_dong() As Long

Get

Return Me.DefaultView.Count

End Get

End Property

#End Region

Page 137: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 137/187

II.3. Khai báo phương thức khởi tạo Nhóm gồm những hàm khởi tạo đối tượng chứa dữ liệu, đồng thời khởi tạo các đối tượng thực hiện đọc ghi dữ liệu:

Ví dụ: XL_BANG: phần khai báo các hàm khỏi tạo

#Region " Khai báo phương thức khởi tạo "

' Thủ tục khởi tạo một thể hiện DataTable chưa có cấu trúc và dữ liệu

Public Sub New()

MyBase.New()

End Sub

' Thủ tục khởi tạo đọc toàn bộ bảng

Public Sub New(ByVal pTen_bang As String)

MyBase.New(pTen_bang)

mTen_bang = pTen_bang

Doc_bang()

End Sub

' Thủ tục khởi tạo đọc bảng theo nội dung yêu cầu

Public Sub New(ByVal pTen_bang As String, ByVal pChuoi_SQL As String)

MyBase.New(pTen_bang)

mTen_bang = pTen_bang

mChuoi_SQL = pChuoi_SQL

Doc_bang()

End Sub

#End Region

II.4. Khai báo phương thức xử lý - cung cấp thông tin Nhóm gồm những chức năng xử lý và cung cấp thông tin:

Ví dụ: XL_BANG: phần khai báo các phương thức xử lý – cung cấp thông tin

#Region " Khai báo phương thức xử lý – cung cấp thông tin "

' Thủ tục khởi tạo đối tượng đọc ghi dữ liệu và khai báo thông tin cho đối tượpng kết nối

' Thực hiện lấy cấu trúc và dữ liệu vào DataTable. Sau cùng phát sinh các lệnh cập nhật

Private Sub Doc_bang()

If mChuoi_SQL = "" Then mChuoi_SQL = "SELECT * FROM " & mTen_bang

If mKet_noi Is Nothing Then

mKet_noi = New OleDbConnection

mKet_noi.ConnectionString = Chuoi_lien_ket & "Data Source=" & Chuoi_CSDL

Page 138: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 138/187

End If

Try

mBo_doc_ghi = New OleDbDataAdapter(mChuoi_SQL, mKet_noi)

mBo_doc_ghi.Fill(Me)

mBo_doc_ghi.FillSchema(Me, SchemaType.Mapped)

mBo_doc_ghi.SelectCommand.CommandText = "Select * FROM " & mTen_bang

Dim Bo_phat_sinh As New OleDbCommandBuilder(mBo_doc_ghi)

Catch ex As OleDbException

End Try

End Sub

' Hàm cập nhật các thay đổi trên DataTable vào CSDL và cập nhật các dòng trên DataTable

' về trạng thái không thay đổi. Nếu cập nhật được, hàm trả về True; ngược lại, bỏ qua các

' thay đổi và trả về False

Public Function Ghi() As Boolean

Dim ketqua As Boolean = True

Try

mBo_doc_ghi.Update(Me)

Me.AcceptChanges()

Catch e As Exception

Me.RejectChanges()

ketqua = False

End Try

Return ketqua

End Function

' Thủ tục lọc dữ liệu của DefaultView theo điều kiện lọc truyền vào

Public Sub Loc_du_lieu(ByVal pDieu_kien As String)

Try

Me.DefaultView.RowFilter = pDieu_kien

Catch ex As Exception

End Try

End Sub

#End Region

Page 139: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 139/187

II.5. Khai báo các phương thức thực hiện lệnh Nhóm gồm những hàm, thủ tục cung cập chức năng thực hiện lệnh:

Ví dụ: XL_BANG: Khai báo các phương thức thực hiện lệnh

#Region " Khai báo các phương thức thực hiện lệnh "

' Hàm thực hiện nội dung lệnh truyền vào và trả về số mẩu tin được cập nhật, nếu thành

' công. Nếu không thành công, hàm trả về -1

Public Function Thuc_hien_lenh(ByVal Lenh As String) As Integer

Try

Dim Cau_lenh As New OleDbCommand(Lenh, mKet_noi)

mKet_noi.Open()

Dim ket_qua As Integer = Cau_lenh.ExecuteNonQuery()

mKet_noi.Close()

Return ket_qua

Catch ex As OleDbException

Return -1

End Try

End Function

' Hàm thực hiện nội dung lệnh tính toán thống kê truyền vào và trả về kết quả, nếu thành

' công. Nếu không thành công, hàm trả về Nothing

Public Function Thuc_hien_lenh_tinh_toan(ByVal Lenh As String) As Object

Try

Dim Cau_lenh As New OleDbCommand(Lenh, mKet_noi)

mKet_noi.Open()

Dim ket_qua As Object = Cau_lenh.ExecuteScalar

mKet_noi.Close()

Return ket_qua

Catch ex As OleDbException

Return Nothing

End Try

End Function

#End Region

Page 140: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 140/187

II.6. Nhóm xử lý sự kiện Ví dụ: XL_BANG: Xử lý sự kiện

#Region " Xử lý sự kiện "

' Khi khóa chính là cột tự động tăng, giá trị cột này được CSDL tự

' phát sinh nên cần truy xuất về để sử dụng cho việc cập nhật sau đó.

Private Sub mBo_doc_ghi_RowUpdated(ByVal sender As Object, ByVal e As _

System.Data.OleDb.OleDbRowUpdatedEventArgs) _

Handles mBo_doc_ghi.RowUpdated

If e.Status = UpdateStatus.Continue AndAlso _

e.StatementType = StatementType.Insert Then

'Lấy gía trị AutoNumber

If Me.PrimaryKey(0).AutoIncrement Then

Dim lenh As New OleDbCommand("Select @@IDENTITY", mKet_noi)

e.Row.Item(0) = lenh.ExecuteScalar()

e.Row.AcceptChanges()

End If

End If

End Sub

#End Region

III. Xây dựng lớp xử lý nghiệp vụ Lớp xử lý nghiệp vụ gồm các thành phần của riêng lớp đó.

Với mỗi bảng trong CSDL, cần xây dựng một lớp xử lý tương ứng với các điểm cần lưu ý:

Lớp kế thừa từ lớp XL_BANG

Lớp có hàm khởi tạo và tìm kiếm thông tin

III.1. Khai báo phương thức khởi tạo Nhóm này có các phương thức khởi tạo khác nhau.

Ví dụ: Lớp xử lý nghiệp vụ XL_DIEN_VIEN

Imports System.Data

Imports System.Data.OleDb

Public Class XL_DIEN_VIEN

Inherits XL_BANG

#Region " Khai báo phương thức khởi tạo "

' Khởi tạo toàn bộ danh sách diễn viên

Public Sub New()

MyBase.New("DIEN_VIEN", "Select * From DIEN_VIEN")

End Sub

Page 141: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 141/187

' Khởi tạo thông tin diễn viên theo khóa chính

Public Sub New(ByVal pMDV As Int32)

MyBase.New("DIEN_VIEN", "Select * From DIEN_VIEN Where MDV = " & pMDV)

End Sub

' Khởi tạo danh sách diễn viên theo điều kiện

Public Sub New(ByVal pChuoi_SQL As String)

MyBase.New("DIEN_VIEN", pChuoi_SQL)

End Sub

#End Region

End Class

III.2. Khai báo phương thức tìm kiếm thông tin Dựa vào các yêu cầu tìm kiếm thông tin lập biểu thức lọc để xác định các dòng thoả điều kiện tìm:

Ví dụ: XL_DIEN_VIEN: Phương thức tìm kiếm thông tin

#Region " Khai báo phương thức xử lý tìm kiếm thông tin "

Public Sub Tim(ByVal pDong_dieu_kien As DataRow)

Dim chuoi_Dk As String = ""

Dim mang_Dk As New ArrayList

Dim so_Pt As Byte = 0

If Not IsDBNull(pDong_dieu_kien("Ho_ten_dv")) Then

mang_Dk.Add("Ho_ten_dv LIKE '" & _

pDong_dieu_kien("Ho_ten_dv") & "*'")

End If

'Tiếp theo cho những điều kiện khác …

If mang_Dk.Count > 0 Then

Dim i As Integer

For i = 0 To mang_Dk.Count - 1

If i = 0 Then

chuoi_Dk = mang_Dk(i)

Else

chuoi_Dk += " AND " + mang_Dk(i)

End If

Next

Loc_du_lieu(chuoi_Dk)

End If

End Sub

#End Region

Page 142: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 142/187

Bài 8

THIẾT KẾ CÁC MÀN HÌNH

Tóm tắt Lý thuyết 6 tiết - Thực hành 15 tiết

Mục tiêu Các mục chính Bài tập

Bài học này giúp cho học viên thiết kế và cài đặt các dạng màn hình cơ bản trong ứng dụng Visual Basic

4. Các điều khiển hiển thị dữ liệu

5. Màn hình đơn

6. Màn hình một nhiều

7. Màn hình lọc theo điều kiện

8. Màn hình một nhiều nhiều

9. Một số kỹ thuật trong hiển thị dữ liệu

5.6, 5.7, 5.8, 5.9, 5.10, 5.11, 5.12, 5.14

Bài làm thêm: 5.13

Page 143: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 143/187

I. Các điều khiển hiển thị dữ liệu Với mô hình liên kết dữ liệu (DataBinding) các thay đổi trên dữ liệu hay trên các điều khiển tự động tương tác qua lại. Ngược lại, trong mô hình không liên kết, dữ liệu từ lớp xử lý sẽ được xuất ra các điều khiển hiển thị trên màn hình. Các thay đổi trên điều khiển sẽ được kiểm tra trước khi nhập vào lớp xử lý. Vì vậy, cần phải có những chức năng nhập xuất, kiểm tra dữ liệu, . . .:

Dưới đây là bảng liệt kê thuộc tính hiển thị dữ liệu của một số điều khiển thường dùng trên màn hình

I.1. Thuộc tính liên kết dữ liệu của điều khiển Các điều khiển hiển thị dữ liệu

Điều khiển Thuộc tính liên kết dữ liệu

Label Text

TextBox Text

DomainUpdown Text

Checkbox Checked

RadioButton Checked

ComboBox SelectedValue

ListBox SelectedValue

CheckListbox SelectedValue

DateTimePicker Value

NumericUpdown Value

I.2. ComboBox, ListBox, CheckListBox Sau đây chúng ta sẽ đề cập đến một số điều khiển đặc biệt trong việc hiển thị dữ liệu.

Khi được dùng để hiển thị dữ liệu, chúng ta cần quan tâm đến các thuộc tính sau :

DataSource: Chỉ ra nguồn dữ liệu để lấy giá trị liệt kê chọn lựa

DisplayMember: Cho biết tên cột trên nguồn dữ liệu liệt kê sẽ được hiển thị trên điều khiển

ValueMember: Cho biết tên cột trên nguồn dữ liệu liệt kê sẽ được lấy giá trị để cập nhật vào nguồn dữ liệu khi chọn một dòng trên điều khiển

SelectedValue: Giá trị của dòng được chọn ứng với cột có tên là giá trị của ValueMember.

Sự kiện cần lưu ý trên các điều khiển nầy:

Các sự kiện

Tên Mô tả

SelectedIndexChanged Xảy ra khi thuộc tính SelectedIndex thay đổi (do lệnh và tương tác).

SelectedValueChanged Xảy ra khi thuộc tính SelectedValue thay đổi (do lệnh và tương tác).

SelectionChangeCommitted Xảy ra khi dòng chọn thay đổi và đã được cập nhật (do tương tác)

Page 144: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 144/187

I.3. DataGrid DataGrid là điều khiển cho phép liên kết dữ liệu dạng bảng gồm các dòng và các cột. Đặc điểm của DataGrid trong .NET là có thể liên kết với DataSet chứa nhiều bảng, quan hệ và có thể hiện thị từng bảng dữ liệu theo từng quan hệ trên lưới. Lưới lúc này hiển thị như cây thư mục, chọn bảng nào lưới sẽ chuyển sang liên kết dữ liệu của bảng đó và xuất hiện các nút di chuyển về bảng trước, v.v…

DataGrid với các cách liên kết dữ liệu

I.3.1. Các thuộc tính của DataGrid

Các thuộc tính thường dùng

Tên Mô tả

AllowSorting Định trị cho biết lưới có cho phép sắp xếp khi nhấn phần tiêu đề cột hay không.

AlternatingBackColor Màu dòng xen kẻ trên lưới. Mặc định màu trắng tức màu các dòng không xen kẻ.

CaptionFont Kiểu chữ cho phần tiều đề lưới.

CaptionText Nội dung tiêu đề lưới.

CaptionVisible Định trị cho biết có hiển thị tiêu đề lưới hay không.

ColumnHeadersVisible Định trị cho biết có hiển thị tiều đề cột hay không.

ContextMenu Thực đơn ngữ cảnh cho điều khiển.

Controls Trả về tập hợp các điều khiển trên lưới.

CurrentCell Ô hiện hành trên lưới. Không sử dụng được ở chế độ thiết kế.

CurrentRowIndex Chỉ số dòng hiện hành

DataMember Thành phần nhánh dữ liệu hiển thị trên lưới

DataSource Nguồn dữ liệu của lưới.

Enabled Định trị cho biết lưới sáng hay mờ.

Các nút di chuyển về bảng trước, sau v.v…

Page 145: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 145/187

Font Kiểu chữ dùng hiện thị dữ liệu trên lưới

HeaderFont Kiểu chữ dùng hiện thị tiều đề cột trên lưới

Item Trị của ô có chỉ số truyền vào: Item(<dòng>,<cột>)

Name Tên điều khiển.

PreferredColumnWidth Độ rộng mặc định mỗi cột trên lưới theo đơn vị pixels.

PreferredRowHeight Chiều cao mặc định của mỗi dòng trên lưới.

ReadOnly Định trị cho biết lưới ở chế độ chỉ đọc hay không.

RowHeadersVisible Định trị cho biết có hiển thị tiều đề dòng hay không.

RowHeaderWidth Độ rộng của tiều đề dòng.

TableStyles Tập hợp các kiểu DataGridTableStyle của lưới.

Text Nội dung trên ô hiện hành

VisibleColumnCount Trả về số cột nhìn thấy trên lưới.

VisibleRowCount Trả về số dòng nhìn thấy trên lưới.

I.3.2. Các phương thức của DataGrid

Các phương thức thường dùng

Tên Mô tả

HitTest Lấy thông tin của lưới tại một vị trí chỉ ra trên màn hình. Cú pháp

HitTest (<hoành độ>,<tung độ>)

Phương thức trả về một đối tượng HitTestInfo của DataGrid cho biết các thông tin về vùng được nhấn. Chúng ta có thể gọi phương thức này trong sự kiện MouseDown để xác định dòng cột tại vị trí nhấn chuột… thông qua HitTestInfo

IsSelected Trị cho biết dòng truyền vào có được chọn hay không.

IsSelected(<chỉ số dòng>)

SetDataBinding Liên kết dữ liệu với lưới thông qua DataSource và DataMember.

SetDataBinding(<datasource>, <datamember>)

Select Chọn dòng chỉ ra qua chỉ số truyền vào.

Select(<chỉ số dòng>)

UnSelect Bỏ chọn dòng chỉ ra qua chỉ số truyền vào.

UnSelect(<chỉ số dòng>)

I.3.3. Các sự kiện của DataGrid

Các sự kiện

Tên Mô tả

CurrentCellChanged Sự kiện xảy ra khi ô hiện hành thay đổi

MouseDown Sự kiện xảy ra khi nhấn chuột trên DataGrid

Page 146: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 146/187

I.4. DataGridTableStyle và TableStyles

I.4.1. DataGridTableStyle

DataGrid có tập hợp TableStyles gồm những DataGridTableStyle giúp chúng ta định dạng lưới theo một yêu cầu hiển thị cụ thể tùy theo bảng dữ liệu. DataGridTableStyle thuộc không gian tên System.Windows.Forms.DataGridTableStyle

Nếu DataView là nội dung cần hiển thị trên lưới thì DataGridTableStyle là hình thức phải tuân theo để hiển thị.

Cú pháp: Khởi tạo một DataGridTableStyle

New DataGridTableStyle()

Các thuộc tính của DataGridTableStyle đều kế thừa của DataGrid nên bảng dưới chỉ trình bày các thuộc tính mới và đáng chú ý:

Các thuộc tính của DataGridTableStyle

Tên Mô tả

DataGrid DataGrid mà DataGridTableStyle thuộc về.

GridColumnStyles Tập hợp các DataGridColumnStyle của DataGridTableStyle.

MappingName Tên dùng để ánh xạ đến một nguồn dữ liệu. Đây là tên của DataTable muốn liên kết dữ liệu.

I.4.2. TableStyles

Do lưới có thể dùng hiển thị dữ liệu của các nguồn khác nhau nên chúng ta có thể tạo nhiều DataGridTableStyle cho phù hợp với mỗi nguồn dữ liệu. Các DataGridTableStyle của lưới được tập hợp lại thành TableStyles. Là một tập hợp (collection) nên TableStyles có các thuộc tính và phương thức đặc trưng của tập hợp như Count, Item, Add, AddRange, Clear, Contains, Remove, RemoveAt. Cách sử dụng các thuộc tính và phương thức của TableStyles cũng giống như cách đã trình bày trước đây về các tập hợp khác.

I.5. DataGridColumnStyle và GridColumnStyles

I.5.1. DataGridColumnStyle

Trong khi DataGridTableStyle qui định cách hiển thị của nguồn dữ liệu của lưới thì DataGridColumnStyle qui định cách hiển thị dữ liệu trên một cột. DataGridColumnStyle thuộc không gian tên System.Windows.Forms.DataGridColumnStyle. Đây là lớp phải kế thừa (MustInherit). Hiện có hai lớp phát sinh từ lớp này là:

System.Windows.Forms.DataGridBoolColumn

System.Windows.Forms.DataGridTextBoxColumn

Cú pháp: Khởi tạo một DataGridColumnStyle

New DataGridBoolColumn()

New DataGridTextBoxColumn()

Page 147: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 147/187

Các thuộc tính của DataGridColumnStyle

Tên Mô tả

Alignment Canh lề trong cột.

DataGridTableStyle Trả về DataGridTableStyle chứa cột.

HeaderText Tiêu đề của cột.

MappingName Tên cột trên bảng liên kết với cột.

NullText Nội dung hiển thị khi cột có trị Null.

ReadOnly Định trị cho biết có được phép chỉnh sửa dữ liệu trên cột hay không.

Width Độ rộng của cột.

Ngoài các thuộc tính chung nói trên, mỗi loại còn có các thuộc tính riêng của nó

Các thuộc tính riêng của DataGridBoolColumn

Tên Mô tả

AllowNull Trị cho biết cột có nhận giá trị Null hay không.

FalseValue Trị được sử dụng khi cột có giá trị False.

NullValue Trị được sử dụng khi cột có giá trị Null.

TrueValue Trị được sử dụng khi cột có giá trị True.

Các thuộc tính riêng của DataGridTextBoxColumn

Tên Mô tả

Format Biểu thức định dạng của cột FormatInfo Đối tượng chứa thông tin định dạng theo văn hóa, quốc gia… TextBox Trả về Textbox của cột

I.5.2. GridColumnStyles

GridColumnStyles là tập hợp các DataGridColumnStyle (cả DataGridBoolColumn lẫn DataGridTextBoxColumn) của một DataGridTableStyle.

I.6. Thiết kế DataGrid Khi DataGrid liên kết với nguồn dữ liệu, nếu chúng ta không tạo DataGridTableStyle qui định cách hiển thị dữ liệu, lưới sẽ hiển thị dữ liệu theo định dạng mặc định của lưới. Để lưới hiển thị dữ liệu theo ý muốn, chúng ta phải tạo DataGridTableStyle và các thành phần của nó.

I.6.1. Tạo DataGridTableStyle khi thiết kế (Design time)

Chúng ta tạo DataGridTableStyle và các DataGridColumnStyle theo các bước sau :

Chọn thuộc tính TableStyle trên Properties và nhấn nút […]

Trên cửa sổ kế tiếp nhấn nút [Add] để tạo một DataGridTableStyle mới, khai báo các thuộc tính cần thiết như MappingName, ReadOnly,… và nhấn nút […] ở mục

Page 148: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 148/187

GridColumnStyles để tạo các DataGridColumnStyle.

Tạo DataGridTableStyle mới

Trên cửa sổ kế tiếp nhấn nút [ ] bên phải nút [Add] để lựa chọn loại DataGridColumnStyle muốn tạo, mặc định là DataGridTextBoxColumn :

Chọn loại DataGridColumnStyle

Nhấn nút [Add] để tạo một DataGridColumnStyle đã chọn và khai báo các thuộc tính cần thiết : Alignment, HeaderText, Width, Format, MappingName, ReadOnly, NullText…Tiếp tục các cột khác

Page 149: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 149/187

Tạo DataGridColumnStyle mới và khai báo

I.6.2. Tạo DataGridTableStyle lúc thực thi (Runtime)

Sử dụng lệnh tạo mới một DataGridTableStyle, kế tiếp tạo các DataGridColumnStyle và thêm vào GridColumnStyles của DataGridTableStyle, sau cùng thêm DataGridTableStyle vừa tạo vào tập hợp TableStyles của lưới.

Đoạn lệnh sau đây minh họa tạo DataGridTableStyle hiển thị dữ liệu bang_phong trên lưới LUOI_PHONG.

Ví dụ:

Dim kieu_hien_thi_bang_phong As New DataGridTableStyle()

With kieu_hien_thi_bang_phong

.MappingName = bang_phong.TableName

Dim cot_ma_phong As New DataGridTextBoxColumn()

cot_ma_phong.MappingName = bang_phong.Columns(0).ColumnName

cot_ma_phong.HeaderText = “Mã PB”

cot_ma_phong.Width = 40

.GridColumnStyles.Add(cot_ma_phong)

Dim cot_ten_phong As New DataGridTextBoxColumn()

cot_ten_phong.MappingName = bang_phong.Columns(1).ColumnName

cot_ten_phong.HeaderText = “Tên phòng ban”

cot_ten_phong.Width = 150

.GridColumnStyles.Add(cot_ten_phong)

End With

LUOI_PHONG.TableStyles.Add(kieu_hien_thi_bang_phong)

Page 150: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 150/187

Kinh nghiệm giảng dạy:

Luôn luôn tạo các DataGridColumnStyle và thêm chúng vào GridColumnStyles của DataGridTableStyle trước khi thêm DataGridTableStyle này vào TableStyles của lưới. Khi thêm một DataGridTableStyle rỗng (chưa có các DataGridColumnStyle) vào TableStyles, các DataGridColumnStyle sẽ được phát sinh tự động, vì thế khi chúng ta thêm DataGridColumnStyle vào sẽ phát sinh lỗi do có các DataGridColumnStyle có MappingName trùng nhau

I.7. Hiển thị dữ liệu ra điều khiển Để hiển thị dữ liệu lên màn hình, chúng ta có thể xuất dữ liệu của lớp xử lý ra các điều khiển cần hiển thị và khi cần cập nhật vào lớp xử lý lại thực hiện gán trị trên các điều khiển vào các cột tương ứng.

Phần dưới đây giới thiệu một số đối tượng liên quan đến việc đồng bộ dữ liệu trên màn hình

I.7.1. Dòng hiện hành

Như đã đề cập trong phần ADO.Net, dữ liệu trên DataTable hoặc trên DataView không có dòng hiện hành như trong Recordset và tại mỗi thời điểm, có thể làm việc với bất kỳ dòng dữ liệu nào. Ngược lại khi dữ liệu hiển thị trên màn hình, khái niệm hiện hành được đưa ra nhằm đồng bộ dữ liệu trên các điều khiển cùng hiển thị thông tin của một nguồn dữ liệu.

Dưới đây giới thiệu các lớp đối tượng quản lý dữ liệu trên màn hình

I.7.2. BindingManagerBase

BindingManagerBase là đối tượng quản lý và cho phép đồng bộ dữ liệu các điều khiển trên màn hình cùng liên kết đến cùng một đối tượng nguồn. Đây là một lớp trừu tượng. BindingManagerBase thuộc không gian tên System.Windows.Forms.BindingManagerBase gồm hai lớp:

System.Windows.Forms.CurrencyManager

System.Windows.Forms.PropertyManager

CurrencyManager thực hiện việc đồng bộ bằng cách duy trì một con trỏ đến dòng hiện hành trên danh sách. Các điều khiển liên kết đến dòng hiện hành sẽ hiển thị thông tin của cùng một dòng.

PropertyManager được dùng để duy trì thuộc tính hiện hành của đối tượng, đúng hơn là thuộc tính của đối tượng hiện hành trên danh sách.

Cách tạo thường dùng nhất là từ đối tượng BindingContext của Form như sau:

Cú pháp: Khởi tạo một DataGridColumnStyle

Dim bm As BindingManagerBase = _

<form>.BindingContext(<nguồn dữ liệu>)

Hoặc:

Dim bm As BindingManagerBase = _

<form>.BindingContext(<nguồn dữ liệu>, <thành phần>)

Nếu nguồn dữ liệu là đối tượng chỉ trả về một thuộc tính, BindingContext sẽ trả về một ProtertyManager. Ví dụ liên kết Text của Label với Text của Textbox.

Nếu nguồn dữ liệu là đối tượng chứa một danh sách, BindingContext sẽ trả về một CurrencyManager. Ví dụ nguồn là DataSet, DataTable, DataView... một CurrencyManager được trả về.

Page 151: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 151/187

Các thuộc tính cần lưu ý của BindingManagerBase

Các thuộc tính cần chú ý của BindingManagerBase

Tên Mô tả

Count Số dòng trên danh sách do BindingManagerBase quản lý

Current Trả về đối tượng hiện hành (chỉ có tác dụng với CurrencyManager)

Position Vị trí của đối tượng hiện hành trên danh sách (đọc ghi, chỉ có tác dụng với CurrencyManager).

Các phương thức cần chú ý của BindingManagerBase

Tên Mô tả

AddNew() Thêm dòng mới trên danh sách do BindingManagerBase quản lý. (như AddNew của DataView). Dòng mới thêm được chuyển thành đối tượng hiện hành (Current) trên BindingManagerBase

EndCurrentEdit() Chấm dứt chỉnh sửa trên đối tượng hiện hành và nếu là dòng mới sẽ được đưa vào tập hợp Rows của DataTable (chỉ có tác dụng với CurrencyManager)

CancelCurrentEdit() Bỏ qua các thay đổi của đối tượng hiện hành.

Các sự kiện của BindingManagerBase

Tên Mô tả

CurrentChanged Sự kiện xảy ra khi đối tượng hiện hành thay đổi

PositionChanged Sự kiện xảy ra khi vị trí hiện hành của BindingManagerBase thay đổi

I.7.3. BindingContext

Phát sinh từ lớp đối tượng System.Windows.Forms.BindingContext, BindingContext là đối tượng quản lý các BindingManagerBase. Các đối tượng kế thừa từ lớp Control đều có thể có BindingContext. Tuy nhiên, chỉ có Form và các điều khiển chứa các điều khiển khác như Groupbox, TabControl, Panel mới có thể tạo một BindingContext để quản lý các BindingManagerBase hiển thị dữ liệu của các điều khiển chứa trong nó.

Tuy cùng liên kết với một nguồn dữ liệu (cách tham chiếu hoàn toàn giống nhau), nhưng hai BindingContext sẽ phát sinh hai BindingManagerBase khác nhau và không đồng bộ dữ liệu với nhau.

I.7.4. Các thủ tục nhập xuất dữ liệu trên màn hình

Để hiển thị dữ liệu trên màn hình, chúng ta sử dụng các điều khiển đã đề cập ở trên thông qua thuộc tính liên kết dữ liệu và thường có các thủ tục nhập xuất sau:

Thủ tục Xuat_ho_so_<ten_bang>: xuất các trị của dòng đang làm việc ra các điều khiển trên màn hình

Thủ tục Xuat_ho_so_<ten_bang>_moi: xuất các trị mặc định ra các điều khiển trên màn hình để chuẩn bị tiếp nhận thông tin của dòng mới

Thủ tục Nhap_ho_so_<ten_bang>: nhập trị của các điều khiển trên màn hình vào các cột tương ứng trên dòng đang làm việc.

Thủ tục Xuat_danh_sach_chon_<ten_bang>: sử dụng khi cấp nguồn liệt kê cho các điều khiển ComboBox, ListBox, ListCheckBox

Page 152: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 152/187

Thủ tục Xuat_luoi_<ten_bang>: sử dụng khi xuất dữ liệu của bảng ra lưới (DataGrid)

II. Màn hình đơn

II.1. Các khai báo Nguồn dữ liệu cho màn đơn chỉ là một bảng, phần khai báo cho màn hình này thường như sau:

Ví dụ:

Private <bang_du_lieu> As <XL_TEN_BANG>

Private Them_moi As Boolean = False

Private WithEvents Danh_sach As BindingManagerBase

<bang_du_lieu> là biến tham chiếu đến đối tượng của lớp xử lý nghiệp vụ trên màn hình.

Them_moi là biến theo dõi trạng thái thêm mới của dòng đang làm việc trên màn hình.

Danh_sach là biến tham chiếu đến BindingManagerBase của <bang_du_lieu> đang hiển thị trên màn hình

II.2. Các thủ tục nhập xuất Thực hiện nhập xuất trên màn hình đơn, chúng ta có ba thủ tục sau:

Xuat_ho_so_<ten_bang>:

Private Sub Xuat_ho_so_<ten_bang> ()

If Danh_sach.Position >= 0 Then

Them_moi = False

<Điều khiển 1>.<Thuộc tính liên kết dữ liệu> = _

Danh_sach.Current(<Cột 1>)

<Điều khiển 2>.<Thuộc tính liên kết dữ liệu> = _

Danh_sach.Current(<Cột 2>)

. . .

Else

Xuat_ho_so_<ten_bang>_moi

End If

End Sub

Xuat_ho_so_<ten_bang>_moi:

Private Sub Xuat_ho_so_<ten_bang>_moi()

Them_moi = True

<Điều khiển 1>.<Thuộc tính liên kết dữ liệu> = _

<Giá trị mặc định của cột hoặc của kiểu>

<Điều khiển 2>.<Thuộc tính liên kết dữ liệu> = _

<Giá trị mặc định của cột hoặc của kiểu>

. . .

End Sub

Page 153: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 153/187

Nhap_ho_so_<ten_bang>:

Private Sub Nhap_ho_so_<ten_bang>()

Danh_sach.Current(<Cột 1>) = <Điều khiển 1>.<Thuộc tính liên kết dữ liệu>

Danh_sach.Current(<Cột 2>) = <Điều khiển 2>.<Thuộc tính liên kết dữ liệu>

. . .

End Sub

Nếu trên màn hình có sử dụng các điều khiển liệt kê (ListControl) như ComboBox, ListBox, CheckListBox, lúc này cần phải có thêm nguồn dữ liệu liệt kê cho điều khiển (<bang_liet_ke>) và có thêm thủ tục:

Xuat_danh_sach_chon_<ten_bang>:

‘ <bang_liet_ke> là đối tượng cung cấp danh sách liệt kê cho điều khiển

Private Sub Xuat_danh_sach_chon_<ten_bang>()

<Điều khiển liệt kê>.DisplayMember = _

<Tên cột muốn hiển thị trên bảng liệt kê>

<Điều khiển liệt kê>.ValueMember = _

<Tên cột muốn liên kết trên bảng dữ liệu>

<Điều khiển liệt kê>.DataSource = <bang_liet_ke>

End Sub

Nếu màn hình hiển thị dữ liệu dưới dạng dòng cột sử dụng DataGrid, thủ tục xuất lưới sẽ là:

Xuat_luoi_<ten_bang>:

Private Sub Xuat_luoi_<ten_bang>()

<Điều khiển lưới>.DataSource = <bang_du_lieu>

End Sub

II.3. Các hàm kiểm tra Trước khi thực hiện nhập dữ liệu vào DataTable, cần kiểm tra dữ liệu nhập của mỗi điều khiển có hợp lệ (không vi phạm các ràng buộc toàn vẹn dữ liệu, miền giá trị, v.v...)

Các hàm hiểm tra trả về trị Boolean: True là hợp lệ, False là không hợp lệ

Nội dung các hàm kiểm tra như sau:

Kiem_tra_<ten cot > As Boolean: (số lượng tùy theo số điều khiển cần kiểm tra)

Private Function Kiem_tra_<ten_cot> As Boolean

Dim Ketqua As Boolean = <điều kiện giá trị trên điều khiển muốn kiểm tra hợp lệ>

If Not Ketqua Then

' Thông báo lỗi

<Điều khiển>.Focus

' Phần này thay đổi tùy mỗi trường hợp

[Else

Page 154: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 154/187

Ketqua = <điều kiện kiểm tra khác trên cùng điều khiển nếu có>

If Not Ketqua Then

' Thông báo lỗi

<Điều khiển>.Focus

End If]

End If

Return Ketqua

End Function

Kiem_tra_ghi_<ten_bang > As Boolean: phối hợp các hàm kiểm tra trên để lấy kết quả tổng hợp

Private Function Kiem_tra_ghi_<ten_bang> As Boolean

Dim Ketqua As Boolean = Kiem_tra_<ten_cot_1> AndAlso _

Kiem_tra_<ten_cot_2> ...

Return Ketqua

End Function

Kiem_tra_huy_<ten_bang > As Boolean: kiểm tra hủy dữ liệu có vi phạm ràng buộc toàn vẹn không (kiểm tra trên các bảng nhiều)

Private Function Kiem_tra_huy_<ten_bang> As Boolean

Dim Ketqua As Boolean

Dim bang As _

New XL_<TEN_BANG_CON>(<điều kiện lọc theo khóa bảng kiểm tra>)

Ketqua = (bang.So_dong = 0)

' kiểm tra trên các bảng con khác nếu cần

Return Ketqua

End Function

II.4. Các xử lý sự kiện Trên màn hình đơn, chúng ta thường có các xử lý sự kiện sau:

Form_Load: Khởi tạo bảng dữ liệu và thực hiện xuất danh sách chọn (nếu có), xuất lưới, xuất hồ sơ

Private Sub MH_Load(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles MyBase.Load

<bang_du_lieu> = New <XL_TEN_BANG>

Danh_sach = Me.BindingContext(<bang_du_lieu>)

Xuat_luoi_<ten_bang>()

Xuat_ho_so_<ten_bang>()

End Sub

Page 155: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 155/187

Sự kiện nhấn của các nút lệnh di chuyển: thay đổi dòng hiện hành nếu hợp lệ

Private Sub Dau_Click(ByVal sender As Object, ByVal e As _

System.EventArgs) Handles Dau.Click

If Danh_sach.Position > 0 Then

Danh_sach.Position = 0

End If

End Sub

Private Sub Truoc_Click(ByVal sender As Object, ByVal e As _

System.EventArgs) Handles Truoc.Click

If Danh_sach.Position > 0 Then

Danh_sach.Position -= 1

End If

End Sub

Private Sub Sau_Click(ByVal sender As Object, ByVal e As _

System.EventArgs) Handles Sau.Click

If Danh_sach.Position < Danh_sach.Count - 1 Then

Danh_sach.Position += 1

End If

End Sub

Private Sub Cuoi_Click(ByVal sender As Object, ByVal e As _

System.EventArgs) Handles Cuoi.Click

If Danh_sach.Position < Danh_sach.Count - 1 Then

Danh_sach.Position = Danh_sach.Count - 1

End If

End Sub

Sự kiện nhấn của nút thêm: Thực hiện xuất hồ sơ mới và đưa con trỏ nhập liệu về điều khiển bắt đầu

Private Sub Them_Click(ByVal sender As Object, ByVal e As _

System.EventArgs) Handles Them.Click

Xuat_ho_so_<ten bang>_moi()

<Điều khiển bắt đầu>.Focus

End Sub

Sự kiện nhấn của nút ghi: Thực hiện kiểm tra ghi. Nếu hợp lệ, thực hiện các bước:

+ Nếu Them_moi là True (đang thêm), thêm dòng mới trên Danh_sach

+ Nhập hồ sơ

+ Thực hiện ghi dữ liệu của lớp xử lý

Page 156: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 156/187

+ Xuất hồ sơ

Private Sub Ghi_Click(ByVal sender As Object, ByVal e As _

System.EventArgs) Handles Ghi.Click

If Kiem_tra_ghi_<ten bang>() Then

If Them_moi Then Danh_sach.AddNew()

Nhap_ho_so_<ten bang>()

Danh_sach.EndCurrentEdit()

<bang_du_lieu>.Ghi()

Xuat_ho_so_<ten bang>()

End If

End Sub

Sự kiện nhấn của nút không: Thực hiện xuất lại thông tin trước đó.

Private Sub Khong_Click(ByVal sender As Object, ByVal e As _

System.EventArgs) Handles Khong.Click

Xuat_ho_so_<ten bang>()

End Sub

Sự kiện nhấn của nút hủy: Nếu Them_moi là True, thực hiện xuất hồ sơ; ngược lại nếu kiểm tra hủy hợp lệ và đồng ý xóa thực hiện:

+ Đánh dấu hủy dòng hiện hành trên Danh_sach

+ Thực hiện ghi dữ liệu của lớp xử lý

+ Xuất hồ sơ

Private Sub Huy_Click(ByVal sender As Object, ByVal e As _

System.EventArgs) Handles Huy.Click

If Them_moi Then

Xuat_ho_so_<ten bang>()

Exit Sub

Else If Kiem_tra_huy_<ten bang>() Then

If MsgBox("Đồng ý hủy ?", MsgBoxStyle.Question + _

MsgBoxStyle.YesNo,"Xin cho biết") = MsgBoxResult.Yes Then

Danh_sach.Current.Delete()

<bang_du_lieu>.Ghi()

End If

Else

' Thông báo lỗi

End If

End Sub

Sự kiện CurrentChanged của Danh_sach: Thực hiện xuất hồ sơ, nếu không phải đang thêm mới

Private Sub Danh_sach_CurrentChanged(ByVal sender As Object, ByVal e As _

System.EventArgs) Handles Danh_sach.CurrentChanged

Page 157: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 157/187

If Not Them_moi Then

Xuat_ho_so_<ten_bang>()

End If

End Sub

III. Màn hình một nhiều Màn hình này hiển thị dữ liệu của bảng một và dữ liệu của bảng nhiều ứng với dòng hiện hành trên bảng một. Dữ liệu cho màn hình gồm bảng một và bảng nhiều.

Có thể có các dạng :

III.1. Màn hình một-nhiều hai trang Màn hình gồm các điều khiển cho bảng một, lưới cho bảng một và lưới cho bảng nhiều. Các điều khiển bảng một trên một tab của TabControl và tab còn lại chứa lưới bảng một. Lưới bảng nhiều được đặt trên Form.

Bảng dữ liệu phía nhiều phải được khai báo và có thể:

Được đọc theo trị cột khóa bảng phía một khi bảng phía một thay đổi dòng làm việc và xuất ra lưới

Hoặc được lọc theo trị cột khóa bảng phía một khi bảng phía một thay đổi dòng làm việc và xuất ra lưới (nếu đã được đọc toàn bộ từ đầu)

Ví dụ: Xử lý bảng nhiều được đọc theo khóa bảng một (khi số liệu bảng nhiều quá lớn)

Private <bang_du_lieu> As <XL_TEN_BANG>

Private <bang_du_lieu_phia_nhieu> As <XL_TEN_BANG_NHIEU>

Private Danh_sach As BindingManagerBase

Private Danh_sach_nhieu As BindingManagerBase

Page 158: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 158/187

Private Sub MH_Load(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles MyBase.Load

....

Call Danh_sach_CurrentChanged(sender, e)

End Sub

Private Sub Xuat_luoi_<ten_bang_nhieu>()

LUOI_<TEN_BANG_NHIEU>.DataSource = <bang_du_lieu_phia_nhieu>

End Sub

Private Sub danh_sach_CurrentChanged(ByVal sender As Object, ByVal e As _

System.EventArgs) Handles danh_sach.CurrentChanged ...

Dim khoa As Integer = 0

If Not Them_moi AndAlso Danh_sach.Position >= 0 Then

...

khoa = Danh_sach.Current(<Khóa>)

End If

<bang_du_lieu_phia_nhieu> As New <XL_TEN_BANG_NHIEU> _

("điều kiện lọc theo khóa bảng một")

Xuat_luoi_<ten_bang_nhieu>()

End Sub

Ví dụ: Xử lý bảng nhiều được đọc hết và được lọc theo khóa bảng một khi dòng hiện hành bảng một thay đổi (khi số liệu bảng nhiều không lớn)

Private <bang_du_lieu_phia_nhieu> As <XL_TEN_BANG_NHIEU>

Private Sub MH_Load(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles MyBase.Load

....

<bang_du_lieu_phia_nhieu> As New <XL_TEN_BANG_NHIEU>()

Xuat_luoi_<ten_bang_nhieu>()

Call Danh_sach_CurrentChanged(sender, e)

End Sub

Private Sub Xuat_luoi_<ten_bang_nhieu>()

LUOI_<TEN_BANG_NHIEU>.DataSource = <bang_du_lieu_phia_nhieu>

End Sub

Private Sub danh_sach_CurrentChanged(ByVal sender As Object, ByVal e As _

Page 159: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 159/187

System.EventArgs) Handles danh_sach.CurrentChanged ...

Dim khoa As Integer = 0

If Not Them_moi AndAlso Danh_sach.Position >=0 Then

...

khoa As Integer = Danh_sach.Current(<Khóa>)

End If

<bang_du_lieu_phia_nhieu>.Loc_du_lieu("điều kiện lọc theo khóa bảng một")

End Sub

III.2. Màn hình một-nhiều ba trang Màn hình có TabControl ba tab : một tab chứa các điều khiển bảng một, một tab chứa lưới bảng một và một tab chứa lưới bảng nhiều. Cách thức xử lý cũng như trên.

Page 160: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 160/187

IV. Màn hình lọc dữ liệu

IV.1. Màn hình lọc một điều kiện Màn hình gồm các điều khiển cho bảng một và lưới (hoặc ListBox) cho bảng nhiều. Điều khiển của bảng một thường có một Combobox, ListBox liệt kê các giá trị giúp người dùng lựa chọn. Chúng ta dùng sự kiện SelectedIndexChanged để lọc dữ liệu

Trên đây là một dạng khác của màn hình lọc theo một điều kiện: (các bảng vở kịch, diễn viên, tham gia được đọc khi mở màn hình)

Diễn viên được phân vai hiển thị dữ liệu THAM_GIA lọc theo vở kịch được chọn

Danh sách diễn viên hiển thị dữ liệu DIEN_VIEN đã loại trừ các diễn viên được phân vai

Ví dụ: bang_tham_gia và bang_dien_vien được khởi tạo khi mở màn hình

Private Sub MVK_SelectedIndexChanged(ByVal sender As Object, ByVal e As _

System.EventArgs) Handles Danh_sach_chon_vo_kich.SelectedIndexChanged

bang_tham_gia.Loc_du_lieu("MVK=" & MVK.SelectedValue)

Dim chuoi As String = Lap_danh_sach_MDV(bang_tham_gia)

If chuoi <>"" Then chuoi = "MDV Not In(" & chuoi & ")"

bang_dien_vien.Loc_du_lieu(chuoi)

End Sub

Private Function Lap_danh_sach_MDV(bang As XL_BANG) As String

Dim ketqua As String = ""

For i As Integer = 0 To bang.So_dong - 1

ketqua &= bang.DefaultView(i)("MDV") & ","

Next

If ketqua.Length > 0 Then ketqua = _

ketqua.SubString(0, ketqua.Length - 1)

Return ketqua

Page 161: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 161/187

End Function

Các nút >, >> thực hiện thêm các dòng chọn trên Danh sách diễn viên vào bang_tham_gia và lọc lại dữ liệu trên bang_dien_vien

Các nút <, << thực hiện hủy các dòng chọn trên Diễn viên được phân vai khỏi bang_tham_gia và lọc lại dữ liệu trên bang_dien_vien

IV.2. Màn hình lọc hai điều kiện Màn hình gồm hai điều khiển (ComboBox, ListBox hoặc Option Group) và lưới để hiển thị dữ liệu lọc. Chúng ta dùng sự kiện SelectedIndexChanged của Combobox hoặc ListBox, CheckedChanged của Option để lọc dữ liệu.

V. Màn hình một-nhiều-nhiều Màn hình này hiển thị dữ liệu của bảng một, dữ liệu của bảng nhiều thứ nhất ứng với dòng hiện hành trên bảng một và dữ liệu của bảng nhiều thứ hai ứng với dòng hiện hành trên bảng nhiều thứ nhất.

Màn hình gồm các điều khiển cho bảng một, lưới cho bảng nhiều thứ nhất và lưới cho bảng nhiều thứ hai. Các điều khiển cho bảng một thường có một ComboBox để lọc dữ liệu cho bảng nhiều thứ nhất.

Khi chọn dòng trên lưới của bảng nhiều thứ nhất, lọc (hoặc đọc) dữ liệu của bảng nhiều thứ hai

VI. Một số kỹ thuật trong hiển thị dữ liệu

VI.1. Tạo lớp DataGridColumnStyle chuyển đổi dữ liệu hiển thị Trên lưới, có những trường hợp cần cột hiển thị dữ liệu khác với dữ liệu lưu trữ như cột MÃ hiển thị TÊN. Chúng ta có thể thực hiện thông qua việc tạo một kiểu DataGridColumnStyle mới đáp ứng nhu cầu này kế thừa từ DataGridTextBoxColumn.

DataGridTextBoxColumn kế thừa từ DataGridColumnStyle và có một DataGridTextBox (phát sinh từ lớp TextBox). Điều khiển TextBox được đưa vào tập hợp Controls của DataGrid. Mỗi lần người dùng bắt đầu soạn thảo trên ô của cột có kiểu DataGridTextBoxColumn, DataGridTextBox được di chuyển đến vị trí soạn thảo và người dùng chỉnh sửa trên chính DataGridTextBox. Giá trị hiển thị trên lưới và cập nhật vào bảng thông qua hai phương thức GetColumnValueAtRow, SetColumnValueAtRow.

Cách giải quyết :

Để có giá trị hiển thị cho cột, chúng ta sử dụng một tập hợp (Collection) chứa tất cả những giá trị cần hiển thị tương ứng.

Giá trị đưa vào tập hợp thuộc một Class với hai thuộc tính đọc ghi chứa giá trị hiển thị và giá trị lưu trữ do chúng ta xây dựng.

Lớp DataGridColumnStyle được tạo sẽ có tập hợp (collection) các đối tượng của lớp vừa tạo ở trên lấy giá trị do người dùng cung cấp thông qua các phương thức thêm xóa của collection.

Trong hàm GetColumnValueAtRow, chúng ta tìm và trả về giá trị hiển thị tương ứng trong tập hợp. Loại cột này dùng để hiển thị thông tin, không cho cập nhật nên chúng ta sẽ không sử dụng thủ tục SetColumnValueAtRow.

Xin tham khảo giáo trình phần gợi ý tạo Class mới của DataGridColumnStyle.

Page 162: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 162/187

VI.2. Tạo lớp DataGridColumnStyle có ComboBox Loại này có một ComboBox chứa danh sách liệt kê để người dùng chọn lựa. Ngoài ra đây cũng là cột có thể có nhu cầu hiển thị khác nội dung lưu trữ nên chúng ta kế thừa từ lớp TranslateColumn ở trên.

Các yêu cầu cho loại cột này là:

Đưa vào một ComboBox

Xử lý cập nhật khi giá trị trên cột thay đổi qua ComboBox

Cách thực hiện:

Khai báo một ComboBox mới và đưa vào tập hợp Controls của lớp và diều khiển này sẽ ẩn hiện theo TextBox của cột và sẽ di chuyển đến vùng hiện hành của lưới.

DisplayMember, ValueMember và DataSource của ComboBox sẽ được gán thông qua một phương thức.

Để cập nhật dữ liệu cho lưới, chúng ta gán SelectedValue của ComboBox sau khi chọn thông qua phương thức SetColumnAtRowValue

Xin xem thêm giáo trình.

VI.3. Tạo lớp DataGridColumnStyle cho phép định dạng chi tiết Với lớp DataGridTextBoxColumn, chúng ta không thể định dạng riêng cho một ô. Vì vậy, cần xây dựng một lớp có thể cho phép định dạng riêng biệt qua việc tạo một kiểu DataGridColumnStyle mới kế thừa từ DataGridTextBoxColumn (xem thêm trong giáo trình)

VI.4. Minh họa sử dụng

VI.4.1. Lớp TranslateColumn

Chúng ta thiết kế lưới hiển thị các diễn viên sử dụng lớp TranslateColumn hiển thị dữ liệu cột Phai trên bảng

Khai báo cột TranslateColumn khi thiết kế:

Định cột Phai kiểu DataGridTextBoxColumn (giả sử được đặt tên là cotPhai) với MappingName là "Phai"

Sau đó chuyển sang cửa sổ Code, vùng Windows Form Designer generated code, tìm và sửa kiểu của cột này từ DataGridTextBoxColumn -> TranslateColumn

Viết thủ tục cấp nguồn hiển thị cho cotPhai và gọi trong sự kiện Form_Load

Ví dụ:

Private Sub Nguon_hien_thi()

' Tri là lớp đã xây dựng (xem giáo trình)

cotPhai.Tap_hop.Add(New Tri(False, "Nữ"))

Page 163: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 163/187

cotPhai.Tap_hop.Add(New Tri(True, "Nam"))

End Sub

Thiết kế lưới bằng lệnh:

Ví dụ: Lưới có tên LUOI_DIEN_VIEN

Private Sub Thiet_ke_luoi_dien_vien()

Dim kieu_the_hien As New DataGridTableStyle

kieu_the_hien.MappingName = "DIEN_VIEN"

Dim cotHo_ten_DV As New DataGridTextBoxColumn

' các lệnh thiết kế cột ...

Dim cotPhai As New TranslateColumn

cotPhai.HeaderText = "Phái"

cotPhai.MappingName = "Phai"

cotPhai.NullText = ""

cotPhai.Width = 60

cotPhai.Tap_hop.Add(New Tri(False, "Nữ"))

cotPhai.Tap_hop.Add(New Tri(True, "Nam"))

Dim cotNgay_sinh As New DataGridTextBoxColumn

' các lệnh thiết kế cột ...

Dim cotDia_chi As New DataGridTextBoxColumn

' các lệnh thiết kế cột ...

kieu_the_hien.GridColumnStyles.AddRange(New DataGridColumnStyle() _

{cotHo_ten_DV, cotPhai, cotNgay_sinh, cotDia_chi})

LUOI_DIEN_VIEN.TableStyles.Add(kieu_the_hien)

End Sub

Sau đó, gọi thực hiện Thiet_ke_luoi_dien_vien trong sự kiện Form_Load

VI.4.2. Lớp ComboBoxColumn

Với yêu cầu thiết kế màn hình như hình bên

Khai báo cột ComboBoxColumn khi thiết kế

Định cột Diễn viên kiểu DataGridTextBoxColumn (giả sử được đặt tên là cotMDV) với MappingName là "MDV"

Sau đó chuyển sang cửa sổ Code, vùng Windows Form Designer generated code, tìm và sửa kiểu của cột này từ DataGridTextBoxColumn -> ComboBoxColumn

Trong sự kiện Form_Load, sau khi có dữ liệu của DIEN_VIEN (qua biến bang_dien_vien của lớp XL_DIEN_VIEN), gọi phương thức Cap_nguon_hien_thi_liet_ke

Page 164: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 164/187

Ví dụ:

bang_dien_vien =New XL_DIEN_VIEN

cotMDV.Cap_nguon_hien_thi_liet_ke(bang_dien_vien, "MDV", "Ho_ten_DV")

Thiết kế lưới bằng lệnh

Ví dụ: Lưới có tên LUOI_THAM_GIA

Private Sub Thiet_ke_luoi_tham_gia()

Dim kieu_the_hien As New DataGridTableStyle

kieu_the_hien.MappingName = "THAM_GIA"

Dim cotMDV As New ComboBoxColumn

cotMDV.HeaderText = "Diễn viên"

cotMDV.MappingName = "MDV"

cotMDV.NullText = ""

cotMDV.Width = 190

cotMDV.Cap_nguon_hien_thi_liet_ke (bang_dien_vien, "MDV", "Ho_ten_DV")

kieu_the_hien.GridColumnStyles.Add(cotMDV)

LUOI_THAM_GIA.TableStyles.Add(kieu_the_hien)

End Sub

Sau đó, gọi thực hiện Thiet_ke_luoi_tham_gia trong sự kiện Form_Load

VI.4.3. Lớp ColoredColumn

Với yêu cầu thiết kế lưới hiển thị vở kịch như sau:

Tạo thêm cột số diễn viên tham gia vở kịch

Nếu số diễn viên tham gia vượt quá trị nào đó, sẽ đổi màu chữ, màu nền, hiệu ứng của font chữ, canh lề nội dung: canh phải, tiêu đề: canh trái

Khai báo cột ColoredColumn khi thiết kế:

Định cột Số diễn viên tham gia kiểu DataGridTextBoxColumn (giả sử được đặt tên là cotSo_dv) với MappingName là "So_dv"

Chuyển sang cửa sổ Code, vùng Windows Form Designer generated code, tìm và sửa kiểu của cột này từ DataGridTextBoxColumn -> ColoredColumn. Sau đó định lại thuộc tính Canh_le_noi_dung trên cửa sổ Properties là Far

Xử lý sự kiện Phat_sinh_bien_co_ve_o như sau:

Ví dụ:

Private Sub cotSo_dv_Phat_sinh_bien_co_ve_o (ByRef e As _

Tham_so_ve_o) Handles cotSo_dv.Phat_sinh_bien_co_ve_o

Page 165: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 165/187

If CInt(e.Gia_tri) > 3 Then

e.Font_Chu = New Font(LUOI_VO_KICH.Font, FontStyle.Italic)

e.Mau_nen = Brushes.Cyan

e.Mau_chu = Brushes.Blue

End If

End Sub

Page 166: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 166/187

Bài 9

BÁO BIỂU CRYSTAL REPORT

Tóm tắt Lý thuyết 6 tiết - Thực hành 10 tiết

Mục tiêu Các mục chính Bài tập

Bài học này giúp cho học viên cách thiết kế báo biểu theo mô hình Pul, Push trong VB.Net.

1. Giới thiệu CrysTal Reportl

2. Tạo báo biểu mô hình Pull, Push

5.15, 5.16, 5.18, 5.19

Bài làm thêm: 5.17

Page 167: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 167/187

I. Giới thiệu Crystal Report Crystal Report là phần mềm thiết kế báo biểu chuyên nghiệp được tích hợp trong các phiên bản của Visual Studio. Phiên bản Studio .NET của Microsoft được tích hợp Crystal Report 8.5.

Bản thân Crystal Report là một phần mềm tạo báo biểu độc lập với rất nhiều chức năng thiết kế báo biểu và dịch vụ. Người dùng có thể kết nối với nhiều nguồn dữ liệu khác nhau bằng các ODBC Driver. Báo biểu khi tạo ra cũng có thể được lưu trữ thành những file .rpt độc lập, ở dạng có dữ liệu hay không có dữ liệu. Sau đó, file .rpt có thể được chuyển tới người dùng khác và mở bằng Crystal Report hay có thể kết hợp với các ứng dụng viết bằng Visual Basic, Visual C++.

Xét về mặt thiết kế báo biểu, Crystal Report cung cấp đầy đủ các chức năng đinh dạng dữ liệu và các chức năng phân nhóm, tính toán, sub – report và kể cả khả năng lập trình bằng formula dựa trên các fomula field. Người dùng ngoài việc sử dụng formula field còn có thể tự xây dựng bộ thư viện hàm của riêng mình và đưa vào Crystal Report thông qua các DLL. Bên cạnh khả năng thiết kế báo biểu thông thường, Crystal Report còn cung cấp chức năng thiết kế biểu đồ dựa trên nguồn dữ liệu lấy từ CSDL.

Xét về mặt sử dụng báo biểu, công cụ hiển thị của Crystal Report cho phép người dùng tương tác rất linh hoạt. Báo biểu hiển thị có thể được lọc lại các dữ liệu cần thiết hay xem một phần báo biểu bằng cách sử dụng cấu trúc hiển thị dữ liệu dạng cây. Các Section trong báo biểu cũng có thể mở rộng hay thu hẹp để hiển thị hay che bớt những dữ liệu không cần thiết. Một khi báo biểu đã được xây dựng, người dùng còn có thể Export sang các dạng file khác như Word, Excel, HTML,…

Bằng cách tích hợp Crystal Report 8.5, Visual Studio .NET đem lại cho người dùng một công cụ xây dựng báo biểu hiệu quả, tiết kiệm nhiều thời gian so với việc phải sử dụng các đối tượng in ấn để tự phát sinh báo biểu. Chúng ta có thể sử dụng Report Expert để tạo ra báo biểu dựa vào wizard và template định sẵn hay thiết kế chi tiết báo biểu bằng tay. Nội dung phần này không đề cập đến các chi tiết thiết kế cụ thể (có thể tham khảo cách tạo báo biểu trên Crystal Report trong giáo trình Visual Basic tập hai) nhưng tập trung vào việc tạo mới báo biểu trong Visual Studio .Net, hiển thị báo biểu trong ứng dụng và sử dụng DataSet làm nguồn dữ liệu cho báo biểu.

II. Tạo báo biểu

Page 168: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 168/187

Báo biểu là một phần của project do đó, để tạo mới một báo biểu chúng ta thực hiện thông qua menu Project | Add new item… và lần lượt thực hiện

Trong phần Templates, chọn mục Crystal Report để tạo mới một báo biểu.

Trong phần Name của hộp thoại Add New Item nhập vào tên file báo biểu cần tạo.

Khi nhấn nút Open, Visual Studio .Net tự động chuyển đổi sang giao diện của Crystal Report để chúng ta thực hiện việc tạo mới báo biểu. Có thể chọn tạo mới báo biểu ở một trong hai hình thức: Wizard (Using Report Expert) hay tự thiết kế từ đầu (Blank Report). Chúng ta cũng có thể mở một báo biểu đã tạo sẵn để đưa vào project.

Khi chọn Blank Report, khác với sử dụng phần mềm Crystal Report độc lập, Visual Studio .NET sẽ

chuyển ngay sang màn hình thiết kế mà không chọn CSDL cho báo biểu (xem hình trên)

Để chọn CSDL cho báo biểu, nhắp chuột phải trên mục Database Fields và chọn mục Add/Remove Database

Một điểm cần chú ý khác trong quá trình thiết kế báo biểu đó là một số thay đổi trong giao diện so với phần mềm Crystal Report chạy độc lập. Ví dụ, chúng ta sẽ tìm thấy TextObject trong phần Toolbox hay thuộc tính của các đối tượng thiết kế có thể thay đổi trực tiếp từ cửa sổ Properties như khi đang thiết kế form

Cuối cùng, cũng giống như Crystal Report Designer trên Visual Basic 6.0, chúng ta không thể chuyển sang chế độ Preview để xem kết quả thiết kế báo biểu, thay vào đó cần phải sử dụng đối tượng Crystal Report Viewer của Visual Studio .NET.

Màn hình dưới là thiết kế của báo biểu hiển thị danh sách các mặt hàng theo từng loại, lấy nguồn dữ liệu từ CSDL Northwind của SQL Server.

Page 169: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 169/187

II.1. Nguồn dữ liệu cho báo biểu Crystal Report kết nối với nguồn dữ liệu thông qua các trình dữ liệu của nó. Mỗi trình được viết để xử lý cho một loại dữ liệu hoặc cho một kỹ thuật truy xuất dữ liệu cụ thể.

Để tạo thuận lợi cho người lập trình, các trình dữ liệu của Crystal Report cung cấp hai mô hình truy xuất: PULL và PUSH

II.1.1. Pull Model (mô hình kéo)

Mô hình Pull

Trong mô hình này, trình sẽ kết nối với nguồn dữ liệu và lấy về dữ liệu yêu cầu. Kết nối với nguồn và lệnh SQL truy xuất dữ liệu đều do Crystal Reports xử lý; chúng ta không phải viết dòng lệnh nào. Nếu không có dòng lệnh nào viết cho lúc thực hiện, báo biểu sử dụng mô hình Pull.

II.1.2. Push Model (mô hình đẩy)

Ngược lại, mô hình đẩy (Push) đòi hỏi chúng ta phải viết lệnh kết nối dữ liệu, thực hiện truy xuất dữ liệu để tạo Recordset hoặc DataSet chứa các field cần thiết cho báo biểu. Mô hình này cho phép chia sẽ kết nối trong ứng dụng và lọc dữ liệu trước khi đưa vào báo biểu.

Page 170: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 170/187

Mô hình Push

II.2. Sử dụng Crystal Report Viewer để hiển thị báo biểu Để hiển thị báo biểu, chúng ta cần có điều khiển CrystalReportViewer. Có thể thiết kế riêng một form chứa điều khiển này để hiển thị báo biểu và cung cấp thêm các chức năng đặc biệt nào đó trong chương trình. Trong trường hợp đơn giản, bản thân CrystalReportViewer cũng đã cung cấp khá đầy đủ các chức năng hiển thị báo biểu và tương tác với người dùng. Do đó, chúng ta có thể sẽ tạo ra form và đối tượng CrystalReportViewer ngay trong đoạn lệnh của chương trình.

CrystalReportViewer trên ToolBoox

Ví dụ: Sau đây khai báo một form và đối tượng CrystalReportViewer để hiển thị báo biểu CrystalReport1.rpt vừa được tạo ở trên

' Tạo form mới

Dim f As New Form

' Tạo đối tượng CrystalReportViewer

Dim cv As New CrystalDecisions.Windows.Forms.CrystalReportViewer

' Đưa cv vào trong form, đặt cv.Dock = Fill để chiếm đầy màn hình

f.Controls.Add(cv)

cv.Dock = DockStyle.Fill

' Gán report sẽ hiển thị trên cv là một thể hiện của CrystalRport1

cv.ReportSource = New CrystalReport1

f.ShowDialog()

Khi thực hiện chương trình với đoạn lệnh trên, chúng ta sẽ có một màn hình hiển thị report tương tự như hình dưới.

CrystalReportViewer có khá đầy đủ các chức năng, từ lật trang, in ấn, gửi mail, phóng lớn/thu nhỏ cho tới tìm kiếm, định vị các group,…

Page 171: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 171/187

II.3. Nguồn dữ liệu cho báo biểu từ DataSet Một điểm đặc biệt trong Visual Studio .NET là có thể tạo nguồn dữ liệu cho báo biểu từ một DataSet (mô hình Push). Sử dụng DataSet làm nguồn dữ liệu của báo biểu cho phép tạo ra những báo biểu không cần kết nối với CSDL hay thậm chí tạo ra những báo biểu trong các ứng dụng hoạt động không cần có CSDL đi cùng. Chẳng hạn, có thể lấy cấu trúc DataSet từ một file XML làm nguồn dữ liệu cho báo biểu.

Để gán nguồn dữ liệu cho báo biểu, chúng ta cần một biến đối tượng là một thể hiện của báo biểu đã thiết kế. Khi đã có một DataSet, chúng ta sử dụng phương thức SetDataSource của đối tượng báo biểu để gán DataSet đó làm nguồn dữ liệu:

Ví dụ:

Dim Rpt As New CrystalReport1

Rpt.SetDataSource(ds)

Sau đây minh họa cách thiết kế báo biểu sử dụng DataSet làm nguồn dữ liệu.

Trong Project, tạo một DataSet mới

+ Menu Project | Add new item, chọn mục DataSet, trong phần Name, gõ vào tên của DataSet là: Products_Schema.xsd

+ Thiết kế DataSet như sau:

Page 172: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 172/187

+ Lưu DataSet lại sau khi tạo xong cấu trúc bảng

Tạo mới một báo biểu, khi chọn nguồn dữ liệu cho báo biểu chúng ta chọn mục ADO.NET DataSet

+ Chọn DataSet vừa tạo

+ Chọn 2 bảng Categories và Products làm nguồn dữ liệu

+ Chọn OK để lưu lại nguồn dữ liệu của báo biểu

Thiết kế báo biểu tương tự như của ví dụ trước

Trong đoạn lệnh hiển thị dữ liệu, sửa lại nội dung như sau:

Ví dụ:

Dim bo_doc_ghi As New Data.OleDb.OleDbDataAdapter _

("Select CategoryID, CategoryName From Categories;Select ProductID, ProductName, " _

& "UnitPrice, UnitsInStock, CategoryID From Products" & _

"Provider=SQLOLEDB;Server=NTH;Initial Catalog=Northwind; User ID=sa")

bo_doc_ghi.TableMappings.Add ("Table", "Categories")

bo_doc_ghi.TableMappings.Add ("Table1", "Products")

Dim DS As New Products_Schema, rpt As New CrystalReport1

Dim f As New Form

Dim cv As New CrystalDecisions.Windows.Forms.CrystalReportViewer

f.Controls.Add(cv)

cv.Dock = DockStyle.Fill

rpt.SetDataSource(DS)

Page 173: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 173/187

rpt.RecordSelectionFormula = "{Categories.CategoryID} > 4"

cv.ReportSource = rpt

f.ShowDialog()

Khi chạy chương trình, báo cáo sẽ được hiển thị như sau:

Trên hình, dữ liệu đã được lọc lại so với báo cáo trước để chỉ hiển thị những Category có CategoryID >4.

II.4. Định lại dữ liệu cho báo biểu từ nguồn CSDL Trong mô hình Pull đã đề cập ở trên, khi khai báo nguồn dữ liệu trong thiết kế, chúng ta phải chỉ rõ nguồn dữ liệu (đường dẫn của tập tin mdb hay thông tin đăng nhập trong SQL Server). Vì thế, lúc thực thi, cần định lại thông tin nguồn CSDL.

Trước hết cần làm quen với một số đối tượng trong CrystalDecisions.CrystalReports.Engine:

Các đối tượng trong CrystalDecisions.CrystalReports.Engine

Tên Mô tả

Database Nguồn CSDL sử dụng cho báo biểu.

Table Thông qua chỉ số, tên trả về bảng tương ứng được sử dụng trong báo biểu.

Tables Tập hợp các bảng sử dụng trên báo biểu.

Báo biểu có thành phần Database cho biết nguồn dữ liệu hiển thị. Khi vị trí nguồn thay đổi, chúng ta phải định lại vị trí nguồn mới cho báo biểu thông qua thông tin đăng nhập của Table, thuộc tập hợp Tables của Database.

Thông tin đăng nhập thuộc lớp TableLogOnInfo trong không gian tên CrystalDecisions.Shared.TableLogOnInfo với các thông tin:

Các thuộc tính của TableLogOnInfo

Page 174: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 174/187

Tên Mô tả

ConnectionInfo Đối tượng chứa thông tin kết nối của bảng.

DatabaseName Tên tập tin CSDL.

Password Mật khẩu truy cập nguồn CSDL

ServerName Tên server hoặc nguồn dữ liệu ODBC.

UserID Tên người dùng để truy cập CSDL.

Thông tin TableLogOnInfo của bảng có tính chỉ đọc và mặc định lưu giữ thông tin kết nối lúc chúng ta khai báo nguồn để thiết kế báo biểu. Khi thay đổi và muốn cập nhật lại, chúng ta phải sử dụng phương thức ApplyLogOnInfo của đối tượng Table với tham số là TableLogOnInfo chúng ta đã thay đổi.

Ví dụ: Minh họa khi nguồn dữ liệu là MS Access

Dim f As New Form()

' CReportVD là báo biểu đã tạo lúc thiết kế

Dim rpt As New CreportVD()

Dim cv As New CrystalDecisions.Windows.Forms.CrystalReportViewer()

f.Controls.Add(cv)

cv.Dock = DockStyle.Fill

Dim logOnInfo As CrystalDecisions.Shared.TableLogOnInfo

' Nếu các Table cùng từ một nguồn dữ liệu, chỉ cần định lại cho một bảng là đủ

logOnInfo = rpt.Database.Tables(0).LogOnInfo

logOnInfo.ConnectionInfo.ServerName = <đường dẫn đến .mdb>

rpt.Database.Tables(0).ApplyLogOnInfo(logOnInfo)

cv.ReportSource = rpt

f.ShowDialog()

Ví dụ: Minh họa khi nguồn dữ liệu là SQL Server

Dim f As New Form()

' CReportVD là báo biểu đã tạo lúc thiết kế

Dim rpt As New CreportVD()

Dim cv As New CrystalDecisions.Windows.Forms.CrystalReportViewer()

f.Controls.Add(cv)

cv.Dock = DockStyle.Fill

Dim logOnInfo As CrystalDecisions.Shared.TableLogOnInfo

' Nếu các Table cùng từ một nguồn dữ liệu, chỉ cần định lại cho một bảng là đủ

logOnInfo = rpt.Database.Tables(0).LogOnInfo

logOnInfo.ConnectionInfo.ServerName = <Tên server>

logOnInfo.ConnectionInfo.DatabaseName = <Tên CSDL>

logOnInfo.ConnectionInfo.UserID = <Người dùng>

logOnInfo.ConnectionInfo.Password = <Mật khẩu>

Page 175: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 175/187

rpt.Database.Tables(0).ApplyLogOnInfo(logOnInfo)

cv.ReportSource = rpt

f.ShowDialog()

II.5. Lọc dữ liệu báo biểu Để lọc dữ liệu trên báo biểu, sử dụng thuộc tính RecordSelectionFormula với cú pháp:

Cú pháp:

<CrystalReport>.RecordSelectionFormula = _

"{<Tên bảng>.<Tên field>} <Toán tử so sánh> <Giá trị>"

<Toán tử so sánh> có thể là =, >=, <=, >, <, <>, In (<danh sách>), Not In (<danh sách>), In <giá trị đầu> To <giá trị cuối>

<Giá trị> cần phải có ký hiệu của kiểu dữ liệu như ['] cho kiểu String, [#] cho kiểu DateTime

Hoặc sử dụng thuộc tính SelectionFormula của điều khiển hiển thị báo biểu CrystalReportViewer

Cú pháp:

<CrystalReportViewer>.SelectionFormula = _

"{<Tên bảng>.<Tên field>} <Toán tử so sánh> <Giá trị>"

II.6. Truyền tham số cho báo biểu Để truyền tham số cho báo biểu, sử dụng phương thức SetParameterValue của báo biểu theo cú pháp sau:

Cú pháp:

<CrystalReport>.SetParameterValue(<Tên tham số>, <Giá trị>)

<Tên tham số> là tên của tham số (ParameterField) đã tạo trong báo biểu.

<Giá trị> không cần có ký hiệu của kiểu dữ liệu.

II.7. Các loại kết xuất báo biểu Mặc định, báo biểu được kết xuất ra màn hình, chúng ta có thể xuất báo biểu ra máy in hoặc tập tin theo cú pháp sau:

II.7.1. Kết xuất ra máy in

Cú pháp:

<CrystalReport>.PrintToPrinter(<số bản>, <Collate>, _

<từ trang>, <đến trang>)

II.7.2. Kết xuất ra tập tin

Cú pháp:

<CrystalReport>.ExportToDisk(<loại tập tin>, <tên tập tin>)

<loại tập tin> có thể có các giá trị sau:

Page 176: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 176/187

Các gía trị thuộc tính của CrystalDecisions.[Shared].ExportFormatType (loại tập tin)

Giá trị Mô tả

Excel Xuất ra tập tin .XLS.

HTML40 Xuất ra tập tin HTML4.0

NoFormat Xuất ra tập tin không kiểu.

PortableDocFormat Xuất ra tập tin .PDF.

RichText xuất ra tập tin .RTF

WordForWindows xuất ra tập tin .DOC

Page 177: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 177/187

ĐỀ THI MẪU CUỐI HỌC PHẦN

Lập Trình Quản Lý (VB.NET) Thời gian: 60 phút

Ngày thi: *** Các kết quả lưu vào đĩa làm việc để chấm điểm ***

Phần I: Các thành phần cung cấp sẵn

1. Cơ sở dữ liệu

Mô tả

Đơn vị ABC có nhiều phòng ban với các nhân viên trực thuộc. Do nhu cầu công tác, nhân viên có thể được điều động từ phòng ban này sang phòng ban khác. Viết chương trình tra cứu thông tin nhân viên.

Quan hệ giữa các bảng

2. Cấu trúc thư mục tổ chức ứng dụng

Thư mục Ý nghĩa

Bao_cao Chứa tập tin báo biểu BC_QUA_TRINH.rpt.rpt sử dụng trong ứng dụng

Du_lieu Chứa tập tin cơ sở dữ liệu QL_NHAN_SU.mdb

Lop_xu_ly_luu_tru Chứa XL_BANG.vb là lớp xử lý lưu trữ của ứng dụng

Lop_xu_ly_nghiep_vu Chứa các lớp xử lý nghiệp vụ của ứng dụng

Man_hinh Chứa tập tin màn hình MH_TRA_CUU.vb sử dụng trong ứng dụng

3. Danh sách các lớp xử lý

Lớp xử lý Ý nghĩa

XL_BANG.vb Lớp đối tượng đọc ghi dữ liệu và một số chức năng khác

XL_<Nghiệp vụ>.vb Các lớp xử lý nghiệp vụ kế thừa từ lớp bảng ứng với mỗi bảng trong CSDL

4. Danh sách các đối tượng thể hiện

Thể hiện Ý nghĩa

MH_TRA_CUU.vb Màn hình cho phép thực hiện chức năng tra cứu thông tin nhân viên

BC_QUA_TRINH.rpt Báo biểu xuất thông tin quá trình công tác của nhân viên

Page 178: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 178/187

5. MH_TRA_CUU.vb

Màn hình Tra cứu thông tin

Màn hình MH_TRA_CUU đã được cài đặt để:

Liệt kê ra danh sách chọn Thuộc phòng những phòng ban trong đơn vị.

Lưới đã được thiết kế để hiển thị dữ liệu tìm thấy (không cho chỉnh sửa).

Có thủ tục xuất dữ liệu ra lưới

6. BC_QUA_TRINH.rpt

Báo biểu đã được thiết kế để hiển thị thông tin như hình:

Báo biểu BC_QUA_TRINH.rpt được cung cấp

Page 179: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 179/187

Phần II: Các yêu cầu phải thực hiện

1. Bổ sung cho các lớp xử lý nghiệp vụ: (1 điểm)

Cài đặt để XL_NHAN_VIEN có thông tin của tên phòng dựa trên MPH, cột hiển thị Nam/Nữ dựa trên Nam

2. Cài đặt cho màn hình MH_TRA_CUU: ( 7 điểm)

Viết hàm Lap_bieu_thuc_loc() As String trả về điều kiện lọc dữ liệu dựa vào các giá trị trên màn hình có nội dung sau: (cộng chung 6.5 điểm)

+ Nếu Họ có chứa khác rỗng, lọc theo điều kiện họ nhân viên có chứa nội dung (Like ) trên điều khiển, ngược lại không lọc theo họ nhân viên (0.5 điểm)

+ Nếu Tên có chứa khác rỗng, lọc theo điều kiện tên nhân viên có chứa nội dung trên điều khiển, ngược lại không lọc theo tên nhân viên (0.5 điểm)

+ Giới tính lọc theo điều kiện trên màn hình: (Nam), (Nữ) hoặc không lọc nếu (Nam Nữ) được chọn. (0.5 điểm)

+ Nếu Thuộc phòng rỗng, không lọc theo phòng ban, ngược lại lọc theo phòng được chọn (0.5 điểm)

+ Lọc theo hệ số lương: (1.25 điểm với điểm chi tiết như mô tả bên dưới)

− Nếu hệ số lương từ, đến đều rỗng: không lọc

− Nếu hệ số lương từ khác rỗng và hệ số lương đến rỗng: lọc theo hệ số lương >= hệ số lương từ

− Nếu hệ số lương từ rỗng và hệ số lương đến khác rỗng: lọc theo hệ số lương <= hệ số lương đến.

− Ngược lại, lọc ra hệ số lương trong đoạn hệ số lương từ đến hệ số lương đến

+ Lọc theo tuổi (dựa vào ngày sinh): (1.5 điểm với điểm chi tiết như mô tả bên dưới)

− Nếu tuổi từ, đến đều rỗng: không lọc

− Nếu tuổi từ khác rỗng và tuổi đến rỗng: lọc theo tuổi >= tuổi từ

− Nếu tuổi từ rỗng và tuổi đến khác rỗng: lọc theo tuổi <= tuổi đến

− Ngược lại, lọc ra tuổi trong đoạn tuổi từ đến tuổi đến

+ Không yêu cầu kiểm tra giá trị hệ số lượng, tuổi đến lớn hơn giá trị hệ số lương, tuổi từ.

+ Kết hợp các điều kiện lọc lại thành chuỗi lọc và trả về giả trị chuỗi lọc (0.5 điểm)

Nhấn nút lệnh Tra cứu, thực hiện các yêu cầu sau: (chung 0.75 điểm)

+ Lập dữ liệu nhân viên theo yêu cầu tra cứu trên màn hình (nội dung của hàm Lap_bieu_thuc_loc)

+ Xuất dữ liệu ra lưới Kết quả tìm kiếm

Bổ sung các đối tượng thích hợp để khi nhấn nút lệnh Xuất In, xuất báo biểu BC_QUA_TRINH.rpt lọc theo nhân viên hiện hành trên lưới Kết quả tìm kiếm (1 điểm)

3. Xử lý trên báo biểu: (2 điểm)

Bổ sung tên phòng vào tiêu đề hồ sơ nhân viên như hình bằng chữ HOA (0.5 điểm)

Hiển thị họ tên trong cùng một field như hình (0.5 điểm)

Đánh số thứ tự các lần thuyên chuyển như hình (0.5 điểm)

Định dạng ngày sinh và ngày thuyên chuyển như hình: ngày tháng năm (0.5 điểm)

Page 180: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 180/187

Báo biểu BC_QUA_TRINH.rpt đã bổ sung theo yêu cầu

Page 181: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 181/187

ĐỀ THI MẪU KIỂM TRA CHUYÊN MÔN GIÁO VIÊN Đề thi kiểm tra chuyên môn giáo viên:

LẬP TRÌNH QUẢN LÝ (VB.NET) Thời gian: 150 phút

Phần lý thuyết (30 phút) Câu 1. Biến khai báo trong VB.NET thuộc loại nào dưới đây:

a) Value Type, Pointer Type b) Value Type, Reference Type c) Pointer Type, Reference Type d) Pointer Type, Reference Type, Value Type

Câu 2. Giả sử khai báo biến d có kiểu ngày: Dim d As Date d = Now

Hãy cho biết câu lệnh nào sau đây sẽ in ra ngày hiện hành theo dạng ngày tháng năm: a) Msgbox (d.Date) b) MsgBox (d.ToString(“dd/mm/yyyy”)) c) MsgBox (d.ToString(“dd/MM/yyyy”)) d) MsgBox (d.ToShortDateString())

Câu 3. Chọn lý do khai báo thủ tục sau đây bị lỗi: Private Sub TEST(ByVal a As Integer, ByVal b As Integer, Optional ByVal c As Boolean ) ' các lệnh End Sub

a) Lỗi vì thiếu kiểu dữ liệu của thủ tục b) Lỗi vì từ khóa ByVal của các tham số c) Lỗi vì tham số Optional không có giá trị mặc định d) Lỗi vì thừa từ ByVal trong Optional ByVal.

Câu 4. Tính chất nào sau đây không thuộc các tính chất của Lập trình hướng đối tượng: a) Tính Cụ thể (Concret) b) Tính Đa hình (Polymorphism)

c) Tính Bảo bọc (Encapsulation) d) Tính Kế thừa (Inheritance)

Câu 5. Có các dòng lệnh sau: Public … Property <Ten thuoc tinh> Get ' Trả về giá trị

End Get End Property

Chọn từ khóa thích hợp để điền vào phần … của thuộc tính: a) MustOverride b) ReadOnly

c) WriteOnly d) ReadWrite

Câu 6. Từ khóa Shared trong khai báo các thành phần cho biết thành phần đó: a) Được sử dụng chung giữa các đối tượng thuộc lớp đó b) Có thể sử dụng thành phần Shared thông qua tên lớp c) Có thể sử dụng thành phần Shared thông qua một biến thuộc lớp đó, ngay cả khi chưa cấp phát vùng

nhớ cho biến. d) Từ khóa Shared hàm ý tất cả các câu trên.

Câu 7. Các thành phần được khai báo với từ khóa Protected cho phép truy xuất: a) Chỉ trong chính lớp nơi thành phần đó được khai báo b) Trong chính lớp nơi thành phần đó được khai báo và trong các lớp kế thừa từ lớp đó c) Chỉ trong chính lớp nơi thành phần đó được khai báo và trong các thể hiện của lớp đó.

Page 182: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 182/187

d) Chỉ trong chính lớp nơi thành phần đó được khai báo và trong lớp cha của lớp đó.

Câu 8. Để tạo ra một đối tượng OleDbDataReader, chúng ta sử dụng cách nào sau đây: a) Dim bo_doc As New System.OleDb.OleDbDataReader b) ' với Lenh là đối tượng OleDbCommand đã tạo sẵn

Dim bo_doc As System.OleDb.OleDbDataReader = Lenh.ExecuteReader() c) ' với Lenh là đối tượng OleDbCommand đã tạo sẵn

Dim bo_doc As System.OleDb.OleDbDataReader = Lenh.ExecuteDataReader() d) Các câu a, b đúng

Câu 9. Cho bảng dữ liệu như sau: CONG_VIEC

MCV Ten_cong_viec Don_vi_tinh Don_gia1 Đào móng đất cấp 3 M3 20000 2 Đổ bê tông 4x6 M3 22000 3 Đổ bê tông 1x2 M3 35000 4 Xây tường 10 M2 10000 5 Xây tường 20 M3 25000 6 Đổ đất nền M3 10000 7 Đóng cốp pha M2 25000 8 Lót gạch men M2 30000

Cho biết biến ketqua chứa giá trị nào khi thực hiện đoạn lệnh sau đây. Biết rằng Ket_noi là đối tượng OleDbConnection đã kết đến nguồn dữ liệu cần thiết: Dim Lenh As New System.OleDb.OleDbCommand("Select Ten_cong_viec From CONG_VIEC", _ Ket_noi) Ket_noi.Open Dim ketqua = Lenh.ExecuteScalar() Ket_noi.Close a) "Đào móng đất cấp 3" b) "Lót gạch men"

c) "Đào móng đất cấp 3, Đổ bê tông 4x6, …, Lót gạch men"

d) Chương trình bị lỗi

Câu 10. Đối tượng OleDbCommandBuilder được dùng để ? a) Khai báo các OleDbCommand b) Phát sinh ra OleDbDataAdapter c) Phát sinh ra SelectCommand của OleDbDataAdapter d) Phát sinh ra các DeleteCommand, InsertCommand và UpdateCommand của OleDbDataAdapter dựa

trên SelectCommand của nó

Câu 11. Cho bảng NHAN_VIEN có cấu trúc sau: Field Name Field Type Field Size Description MNV Autonumber Long Integer Mã nhân viên Ho_ten Text 50 Họ tên nhân viên Gioi_tinh Yes/No Giới tính: Yes: Nam ; No: Nữ Ngay_sinh Date/Time Ngày sinh Dia_chi Text 50 Địa chỉ

Với Mo_ket_noi là hàm trả về OleDbConnection kết nối đến CSDL chứa bảng NHAN_VIEN nói trên Xét các câu lệnh sau: (1) Dim bo_doc_ghi As New OleDbDataAdapter("Select Ho_ten, Gioi_tinh, Ngay_sinh, Dia_chi " _ & "From NHAN_VIEN", Mo_ket_noi) (2) Dim bo_phat_sinh As New OleDbCommandBuilder(bo_doc_ghi) Khi thực hiện, bo_phat_sinh sẽ không phát sinh được các lệnh DeleteCommand, InsertCommand và UpdateCommand vì: a) Dòng lệnh khai báo (2) thiếu tham số b) OleDbCommandBuilder không phải là đối tượng phát sinh các Command còn lại c) Nội dung SelectCommand của OleDbDataAdapter không có cột khóa chính hoặc cột duy nhất d) Nội dung SelectCommand của OleDbDataAdapter không phải từ hai bảng trở lên

Page 183: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 183/187

Câu 12. Cho cấu trúc dữ liệu như sau:

Với bang_to_xay_dung là DataTable chứa dữ liệu đọc về từ TO_XAY_DUNG bang_tho là DataTable chứa dữ liệu đọc về từ THO Hai bảng này chưa thuộc về DataSet nào Để tạo quan hệ giữa bang_to_xay_dung và bang_tho, sử dụng đoạn lệnh nào sau đây: a) Dim quan_ly As New Dataset

Dim qh As New DataRelation("TO_THO", bang_to_xay_dung.Columns("MTO"), _ bang_tho.Columns("MTO")) quan_ly.Relations.Add(qh)

b) Dim quan_ly As New Dataset quan_ly.Tables.AddRange(New DataTable(){bang_tho, bang}) Dim qh As New DataRelation("TO_THO", bang_to_xay_dung.Columns("MTO"), _ bang_tho.Columns("MTO"))

c) Dim quan_ly As New Dataset quan_ly.Tables.AddRange(New DataTable(){bang, bang_tho}) Dim qh As New DataRelation("TO_THO", bang_tho.Columns("MTO"), _ bang_to_xay_dung.Columns("MTO"))) quan_ly.Relations.Add(qh)

d) Dim quan_ly As New Dataset quan_ly.Tables.AddRange(New DataTable(){bang_tho, bang}) Dim qh As New DataRelation("TO_THO", bang_to_xay_dung.Columns("MTO"), _ bang_tho.Columns("MTO")) quan_ly.Relations.Add(qh)

Câu 13. DataTable bang_chi_tiet có các DataColumn như sau: MHD, MHH, So_luong, Don_gia với ý nghĩa Mã hóa đơn kiểu Integer, Mã hàng hóa kiểu Integer, Số lượng kiểu Integer, Đơn giá kiểu Integer. Để tính toán trị giá của một mã hóa đơn M có thể sử dụng cú pháp nào dưới đây: a) Compute( Sum(So_luong*Don_gia) ) b) Compute( "Sum(So_luong*Don_gia)", "MHD=" & M) c) Compute( "Sum(So_luong*Don_gia)", "Where MHD =" & M) d) Không thể sử dụng cú pháp nào ở trên

Câu 14. Các phát biểu nào sau đây về DataView được xem là SAI: (chọn 2 câu) a) Một DataTable có thể tạo ra nhiều DataView b) Không thể cập nhật cho DataView c) Có thể lọc và sắp xếp dữ liệu trên DataView d) Một DataView có thể được tạo ra từ nhiều DataTable

Câu 15. Sử dụng đoạn lệnh nào sau đây để tạo cột tự động tăng STT trên DataTable bang: a) bang.Columns.Add("STT", Type.GetType("System.Integer"), "AutoIncrement") b) bang.Columns.Add("STT", Type.GetType("System.Integer"), "AutoIncrement=True") c) bang.Columns.Add("STT", Type.GetType("System.Integer"), "Identity=True") d) Dim cot As DataColumn= bang.Columns.Add("STT", Type.GetType("System.Integer"))

cot.AutoIncrement = True

Câu 16. Giữa hai DataTable bang_hoa_don (bảng một) và bang_chi_tiet (bảng nhiều) có một quan hệ (DataRelation) tên "HD_CT" thông qua cột "MHD". Chọn hai cách tạo cột cho bang_hoa_don thể hiện số mặt hàng được bán qua mỗi hóa đơn: a) bang_hoa_don.Columns.Add("So_mat_hang", System.Integer, "Count(Child.MHD)") b) bang_hoa_don.Columns.Add("So_mat_hang", Type.GetType("System.Integer"), _

"Count(Child.MHD)")

Page 184: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 184/187

c) bang_hoa_don.Columns.Add("So_mat_hang", Type.GetType(System.Integer), _ "Count(Child.MHD)")

d) bang_hoa_don.Columns.Add("So_mat_hang", Type.GetType("System.Integer"), _ "Count(Child(HD_CT).MHD)")

Câu 17. Thuộc tính RowState của DataRow có các giá trị nào sau đây: a) Added, Deleted, Detached, Modified, Unchanged b) Added, Deleted, Modified, Unchanged c) Added, Deleted, Modified Original, Modified Current, Unchanged d) Deleted, EditAdd, EditInProgress, Unchanged

Câu 18. Khai báo nào sau đây không hợp lệ trên phần General: a) Const Chuoi_vi_tri = "\..\Du_lieu\CSDL.mdb" b) Const Chuoi_vi_tri As String= "\..\Du_lieu\CSDL.mdb" c) Const Chuoi_vi_tri As String= Application.StartUpPath & "\..\Du_lieu\CSDL.mdb" d) Private Chuoi_vi_tri As String= Application.StartUpPath & "\..\Du_lieu\CSDL.mdb"

Câu 19. Date.Today trả về giá trị của ngày hiện hành. Trên một máy tính có Region Settings qui định cách hiển thị ngày tháng năm là dd/MM/yyyy, trên Immediate Window, kết quả nào sau đây được in ra khi thực hiện dòng lệnh : ?Date.Today (giả sử có trị ngày 15 tháng 6 năm 2005) a) #15/06/2005# b) #15/06/2005 12:00:00#

c) #6/15/2005# d) #06/15/2005#

Câu 20. Phương thức AddNew của DataView trả về một DataRowView và khi được gọi số dòng trên DataView (<Dataview>.Count) tăng thêm một. Trên DataTable mà DataView được tạo, số dòng (<DataTable>.Rows.Count) sẽ: a) Bằng số dòng trên DataView b) Bằng số dòng trên DataView có tình trạng là DataViewRowState.CurrentRows c) Không thay đổi so với số dòng trên DataTable trước khi AddNew của DataView được gọi d) Các câu trên đều sai

Câu 21. Xét đoạn lệnh sau trên DataTable bang_nv: Dim a,b As Integer a = bang_nv.Rows.Count bang_nv.Rows(0).Delete() b = bang_nv.Rows.Count Hãy cho biết a và b thế nào sau khi thực hiện thành công đoạn lệnh trên (không bị lỗi)

a) a < b b) a = b c) a > b d) a = b + 1

Câu 22. Để xuất dữ liệu liệt kê ra điều khiển ComboBox, khi sử dụng đoạn lệnh sau: <ComboBox>.DisplayMember = "<tên cột hiển thị>" <ComboBox>.ValueMember = "<tên cột lưu trữ>" <ComboBox>.DataSource = <DataTable>

Người ta thấy các dòng trên ComboBox hiển thị cùng nội dung là "System.Data.DataRowView"

Hãy chọn giải thích đúng cho trường hợp này a) <tên cột hiển thị> không có trên <DataTable> b) <tên cột lưu trữ> không có trên <DataTable> c) <ComboBox>.DataSource phải sửa lại là <ComboBox>.RowSource d) Các giải thích trên đều sai

Câu 23. Để gọi thực hiện báo biều Crystal Report BC_NHAN_VIEN, sử dụng đoạn lệnh nào sau đây: a) Dim bb As New BC_NHAN_VIEN

bb.Show

Page 185: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 185/187

b) Dim bb As New BC_NHAN_VIEN Dim crv As New CrystalDecisions.Windows.Forms.CrystalReportViewer crv.ReportSource = bb crv.Show

c) Dim bb As New BC_NHAN_VIEN Dim crv As New CrystalDecisions.Windows.Forms.CrystalReportViewer crv.ReportSource = bb crv.PrintReport

d) Các câu trên đều sai

Câu 24. Trong mô hình PUSH của Crystal Report, dữ liệu xuất trên báo biểu: a) Do .Net FrameWork xử lý đọc về. b) Do người lập trình viết lệnh đọc dữ liệu và gửi lên cho báo biểu. c) Do Crystal Report tự đọc về qua việc khai báo các bảng và thông tin kết nối khi thiết kế báo biểu d) Các câu trên đều sai

Câu 25. Để truyền giá trị cho tham số Ngay_sinh cho báo biểu Crystal Report BC_NHAN_VIEN, sử dụng cú pháp nào dưới đây: a) Dim bb As New BC_NHAN_VIEN

Dim ngay As New Date(1988,1,1) bb.ParameterFields(0) = ngay

b) Dim bb As New BC_NHAN_VIEN Dim ngay As New Date(1988,1,1) bb.SetParameterValue("Ngay_sinh", ngay)

c) Dim bb As New BC_NHAN_VIEN Dim ngay As New Date(1988,1,1) bb.ParameterFields.Add( ngay)

d) Các câu trên đều đúng

Page 186: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 186/187

Phần thực hành (120 phút) I. Tạo CSDL

a) Mô tả Vào mỗi cuối tháng, công ty xây dựng ABC dựa trên bảng chấm công và lương của các tổ xây dựng để tính lương cho thợ. Mỗi tổ trưởng, ngoài phần lương của mình còn nhận được khoản phụ cấp trách nhiểm trích từ lợi nhuận của công ty.

b) Cấu trúc các bảng Tập tin cơ sở dữ liệu QL_LUONG.mdb gồm các bảng : (các field in đậm và gạch dưới là khóa chính) TO_XAY_DUNG – Danh saùch caùc toå xaây döïng Field Name Field Type Field Size Description MTO Autonumber Long Integer Maõ toå xaây döïng Ten_to Text 30 Teân toå xaây döïng To_truong Number Long Integer Maõ thôï laø toå tröôûng

THO – Danh saùch thôï Field Name Field Type Field Size Description MTH Autonumber Long Integer Maõ thôï Ho_ten Text 30 Hoï teân thôï Gioi_tinh Yes/No Giôùi tính: Yes: Nam ; No: Nöõ Ngay_sinh Date/Time Ngaøy sinh HSL Number Single Heä soá löông MTO Number Long Integer Maõ toå xaây döïng

CHAM_CONG – Chaám coâng thôï Field Name Field Type Field Size Description MCC Autonumber Long Integer Maõ chaám coâng MTH Number Long Integer Maõ thôï Ngay_nghi Date/Time Ngaøy nghæ

LUONG_TO – Löông thaùng cuûa caùc toå xaây döïng Field Name Field Type Field Size Description MLG Autonumber Long Integer Maõ löông toå MTO Number Long Integer Maõ toå xaây döïng Nam_thang Text 6 Naêm thaùng tính löông Tong_luong Number Double Löông thaùng cuûa toå

LUONG – Löông thaùng cuûa thôï Field Name Field Type Field Size Description STT Autonumber Long Integer Soá thöù töï löông MLG Number Long Integer Maõ löông toå MTH Number Long Integer Maõ thôï So_cong Number Integer Soá ngaøy coâng Phu_cap Number Long Integer Phuï caáp traùch nhieäm Tien_luong Number Long Integer Tieàn löông thaùng

Page 187: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 187/187

c) Quan hệ giữa các bảng

Hình 1 – Quan hệ giữa các bảng

II. Các màn hình làm việc a) Màn hình khởi động

Tạo form MDI với tiêu đề Quản lý lương có thực đơn như sau:

Hình 2 – Màn hình và các thành phần của hệ thống menu

Khi người dùng chọn các mục trong menu, thực hiện các yêu cầu tương ứng sau: o Giới thiệu: dùng MsgBox hiển thị thông tin của thí sinh: Họ tên – Năm sinh o Chọn thời gian: Hiển thị màn hình chọn thời gian câu 2 ở chế độ hộp thoại. o Đóng: Hiển thị cửa sổ thông báo “Ứng dụng sẽ đóng lại. Bạn có đồng ý không ?”. Tùy theo trả lời của

người dùng, sẽ thực hiện đóng ứng dụng hay không (Có thể sử dụng hàm MsgBox). o Tính lương: Hiển thị màn hình câu 3 Khi mở màn hình này mặc nhiên mở luôn màn hình chọn thời gian câu 2 ở chế độ hộp thoại

b) Màn hình thời gian Thiết kế một màn hình cho phép xác định thời gian làm việc và ghi nhận lại thời gian này:

Hình 3 – Màn hình chọn thời gian làm việc

o Tháng liệt kê các tháng trong năm (bằng chữ) o Năm liệt kê các năm từ 2000 đến 2010 o Nút Chọn: xác nhận thời gian chọn và đóng màn hình lại

c) Màn hình tính lương

Thiết kế một màn hình cho phép cập nhật số công và thực hiện tính lương:

Page 188: TAØI LIEÄU HÖÔÙNG DAÃN GIAÛNG DAÏYdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/lap...cấu trúc của .Net Framework, đồng thời thông qua việc trình bày một

Tài liệu hướng dẫn giảng dạy

Học phần 3 – VB.NET Trang 188/187

Hình 4 – Màn hình tính lương

o Tiêu đề hiển thị "Tính lương tháng" <tháng làm việc> " năm " <năm làm việc> o Điều khiển Tổ liệt kê các tổ xây dựng. o Khi chọn một tổ xây dựng, Tổng lương hiển thị lương của tổ trong năm tháng làm việc, thực hiện các

yêu cầu sau: o Nếu lương tổ > 0, lưới hiển thị thông tin tính lương của các thợ trong tổ được chọn ứng với năm tháng

làm việc nếu có. Nếu trong CSDL chưa có, cần phát sinh thông tin cho tổ được chọn ứng với năm tháng làm việc.

o Nếu không tồn tại lương tổ được chọn, lưới sẽ không hiển thị. o Cập nhật công cho phép cập nhật số công của thợ ứng với năm tháng làm việc:

Số công = số ngày trong tháng năm tính lương - số ngày nghỉ trong tháng o Chia lương: thực hiện các bước: o Xác định đơn vị lương của tổ được chọn = Tổng lương / Tổng(số công *HSL) của các thợ trong tổ o Cập nhật cột Tien_luong = đơn vị lương * Số công * HSL cho các thợ trong tổ . Nếu là tổ trưởng, cập

nhật thêm cột Phu_cap = Tien_luong*0.05 o In phiếu lương: xuất báo biểu phiếu lương các thợ trong tổ được chọn ứng với năm tháng làm việc

III. Báo biểu

Thiết kế báo biểu sau:

…các thợ khác trong tổ

Hình 5 – Báo biểu của câu 3