Chương M t - Hoan nghênh ñ n v i VB6

Chào m ng b n ñ n v i Visual Basic 6
Dùng VB6 là cách nhanh và t t nh t ñ l p trình cho Microsoft Windows. Cho dù b n là chuyên nghi p hay m i m ñ i v i chương trình Windows, VB6 s cung c p cho b n m t b công c hoàn ch nh ñ ñơn gi n hóa vi c tri n khai l p trình ng d ng cho MSWindows. Visual Basic là gì? Ph n "Visual" ñ c p ñ n phương phàp ñư c s d ng ñ t o giao di n ñ h a ngư i dùng (Graphical User Interface hay vi t t c là GUI) . Có s n nh ng b ph n hình nh, g i là controls, b n tha h s p ñ t v trí và quy t ñ nh các ñ c tính c a chúng trên m t khung màn hình, gi là form. N u b n ñã t ng s d ng chương trình v ch ng h n như Paint, b n ñã có s n các k năng c n thi t ñ t o m t GUI cho VB6. Ph n "Basic" ñ c p ñ n ngôn ng BASIC (Beginners All-Purpose Symbolic Instruction Code), m t ngôn ng l p trình ñơn gi n, d h c, ñư c ch ra cho các khoa h c gia (nh ng ngư i không có thì gi ñ h c l p trình ñi n toán) dùng. Visual Basic ñã ñư c ra t MSBasic, do Bill Gates vi t t th i dùng cho máy tính 8 bits 8080 hay Z80. Hi n nay nó ch a ñ n hàng trăm câu l nh (commands), hàm (functions) và t khóa (keywords). R t nhi u commands, functions liên h tr c ti p ñ n MSWindows GUI. Nh ng ngư i m i b t ñ u có th vi t chương trình b ng cách h c ch m t vài commands, functions và keywords. Kh năng c a ngôn ng này cho phép nh ng ngư i chuyên nghi p hoàn thành b t kỳ ñi u gì nh s d ng ngôn ng l p trình MSWindows nào khác. Ngư i mang l i ph n "Visual" cho VB là ông Alan Cooper. Ông ñã gói môi trư ng ho t ñ ng c a Basic trong m t ph m vi d hi u, d dùng, không c n ph i chú ý ñ n s tinh x o c a MSWindows, nhưng v n dùng các ch c năng c a MSWindows m t cách hi u qu . Do ñó, nhi u ngư i xem ông Alan Cooper là cha già c a Visual Basic. Visual Basic còn có hai d ng khác: Visual Basic for Application (VBA) và VBScript. VBA là ngôn ng n m phía sau các chương trình Word, Excel, MSAccess, MSProject, .v.v.. còn g i là Macros. Dùng VBA trong MSOffice, ta có th làm tăng ch c năng b ng cách t ñ ng hóa các chương trình. VBScript ñư c dùng cho Internet và chính Operating System. Dù cho m c ñích c a b n là t o m t ti n ích nh cho riêng b n, trong m t nhóm làm vi c c a b n, trong m t công ty l n, hay c n phân b chươ ng trình ng d ng r ng rãi trên th gi i qua Internet, VB6 cũng s có các công c l p trình mà b n c n thi t.

Các n b n Visual Basic 6
Có ba n b n VB6: Learning, Professional và Enterprise. Chúng ta hãy gát qua n b n Learning. B n có th dùng n b n Professional hay Enterprise. n b n Professional cung c p ñ y ñ nh ng gì b n c n ñ h c và tri n khai m t chương trình VB6, nh t là các control ActiveX, nh ng b ph n l p trình ti n ch và r t h u d ng cho các ch ươ g trình n ng d ng (application programs) c a b n trong tương lai. Ngoài ñĩa compact chính cho VB6, tài li u ñính kèm g m có sách Visual Studio Professional Features và hai ñĩa CD Microsoft Developer Network (MSDN). n b n Enterprise là n b n Professional c ng thêm các công c Back Office ch ng h n như SQL Server, Microsoft Transaction Server, Internet Information Server.

Cài ñ t VB6
ð cài ñ t VB6, máy tính c a b n c n ph i có m t ñĩa CD-ROM (CD drive) . B n c n 1 nh t 32 MB ít RAM, 2 GB hard disk và CPU Pentium II. Khi b VB6 CD vào CD drive, nó s t kh i ñ ng ñ display menu cho b n ch n nh ng th gì c n Setup, hãy click Install Visual Basic 6.0 ñ cài VB6.

Ngo i tr các file h ñi u hành (Operating System) trong thư m c (folder) \Os, các file trong ñĩa compact ñ u không b nén. Vì th , b n có th s d ng chúng tr c ti p t ñĩa. Ví d , có nhi u công c và thành ph n trong folder \Tools v n có th ñư c cài ñ t tr c ti p t CD-ROM. Ngoài ra, b n có th ch y Setup khi nào c n thi t. Ví d , b n có th ch y Setup ñ cài ñ t l i Visual Basic trong folder khác, ho c ñ cài ñ t thêm b t các ph n c a VB6. N u vì lý do gì h th ng không install các ñĩa compact MSDN (b n s khám phá ra ñi u n y khi th y Help không có m t lúc ch y VB6), b n có th cài ñ t chúng tr c ti p t ñĩa s 1 c a b MSDN. ð b xung và xóa các thành ph n VB: 1. B ñĩa compact vào CD drive. 2. N u menu không t ñ ng hi n lên thì ch y chương trình Setup có s n tong folder g c trên ñĩa compact. 3. Ch n nút Custom trong h p tho i (dialog) Microsoft Visual Basic 6.0 Setup. 4. Ch n hay xóa các thành ph n b ng cách check hay uncheck các h p danh sách Options c a dialog Custom. 5. Th c hi n các ch d n Setup trên màn hình. Ghi chú: Trong lúc cài VB6, nh ch n Graphics n u không b n s thi u m t s hình nh như icons, bitmaps v.v... ðáng l Microsoft cho t ñ ng cài ñ t Graphics, t c là Default (không có nói gì) thì cài ñ t Graphics.

Integrated Development Environment (IDE) c a VB6
Khi kh i ñ ng VB6 b n s th y m ra nhi u c a s (windows), scrollbars, v.v.. và n m ch ng lên là New Project dialog. ñây VB6 cho b n ch n m t trong nhi u lo i công trình.

Ch n Standard EXE. M t lát sau trên màn nh s hi n ra giao di n c a môi trư ng phát tri n tích h p (Integrated Development Environment - IDE ) gi ng như dư i ñây:

2

IDE c a VB6 bao g m các y u t sau:

Menu Bar
Ch a ñ y ñ các commands mà b n s d ng ñ làm vi c v i VB6, k c các menu ñ truy c p các ch c năng ñ c bi t dành cho vi c l p trình ch ng h n như Project, Format, ho c Debug. Trong Menu Add-Ins có Add-Ins Manager cho phép b n g n thêm nh ng menu con nhi m ý ñ ch y các chương trình l i ích cho vi c l p trình.

Trong Add-Ins Manager dialog b n ch n m t Add-In r i check m t hay nhi u h p trong khung Load behavior:

Toolbars (Debug, Edit, form Editor, Standard)

3

Các toolbars có hình các icons cho phép b n click ñ th c hi n công vi c tương ñương v i dùng m t menu command, nhưng nhanh và ti n hơn. B n dùng menu command View | Toolbars (click lên menu command View cho popupmenu hi n ra r i click command con Toolbars) ñ làm cho các toolbars hi n ra hay bi n m t ñi. B n có th thay ñ i v trí m t toolbar b ng cách n m vào hai g ch vertical n m bên trái toolbar r i d i toolbar ñi ch khác (n m ñây nghĩa là ñ pointer c a mouse lên ch ch m ñ trong hình phía dư i r i b m xu ng và gi nút bên trái c a mouse, trong khi kéo pointer ñi nơi khác).

Ngoài ra b n cũng có th s a ñ i các toolbars theo ý thích b ng cách dùng Menu command View | Toolbars | Customize...

Toolbox
ðây là h p ñ ngh v i các công c , g i là controls, mà b n có th ñ t lên các form trong lúc thi t k (design). N u Toolbox bi n m t, b n có th display nó tr l i b ng cách dùng menu command View | Toolbox. B n có th khi n toolbox display nhi u controls hơn b ng cách ch n Components... t context menu (ch n Toolbox r i b m nút ph i c a mouse ñ display context menu) hay dùng menu command Project | Components. Ngoài vi c trình bày Toolbox m c ñ nh, b n có th t o cách trình bày khác b ng cách ch n Add Tab... t context menu và b sung các control cho tab t k t qu .

Project Explorer
S li t kê các forms và các modules trong project hi n hành c a b n. M t project là s t p h p các files mà b n s d ng ñ t o m t trình ng d ng. T c là, trong VB6, khi nói vi t m t program có nghĩa là tri n khai m t project.

Properties window

4

Li t kê các ñ c tính c a các forms ho c controls ñư c ch n. M t property là m t ñ c tính c a m t object ch ng h n như size, caption, ho c color. Khi b n s a ñ i m t property b n s th y hi u qu ngay l p t c, thí d thay ñ i property Font c a m t Label s th y Label y ñư c display b ng Font ch m i. Khi b n ch n m t Property c a control hay form trong Properties window, phía bên ph i ch value c a property có th display ba ch m (. . .) hay m t tam giác ch a xu ng. B m vào ñó ñ display m t dialog cho b n ch n value. Thí d dư i ñây là dialog ñ ch n màu cho property ForeColor c a control Label1.

Form Layout
B n dùng form Layout ñ ch nh v trí c a các forms khi form hi n ra l n ñ u lúc chương trình ch y. Dùng context command Resolution Guides ñ th y n u dùng m t màn nh v i ñ m n (resolution) t hơn, thí d như 640 X 480, thì nó s nh như th nào.

Form Designer
Dùng ñ thi t k giao di n l p trình. B n b sung các controls, các ñ h a (graphics), các hình nh và m t form ñ t o s ma sát mà b n mu n. M i form trong trình ng d ng c a b n có designer form riêng c a nó. Khi b n maximise m t form designer, nó chi m c khu làm vi c. Mu n làm cho nó tr l i c bình thư ng và ñ ng th i ñ th y các form designers khác, click nút Restore Window góc bên ph i, phía trên.

Immediate Window
Dùng ñ g r i (debug) trình ng d ng c a b n. B n có th display d ki n trong khi ch y chương trình ng d ng. Khi chương trình ñang t m ng ng m t break point, b n có th thay ñ i giá tr các variables hay ch y m t dòng chương trình.

View Code button
Click lên nút n y ñ xem code c a m t form mà b n ñã ch n. Window c a code gi ng như dư i ñây:

5

Trong Code window b n có th ch n display t t c Sub c a code cùng m t lúc như trong hình hay display m i l n ch m t Sub b ng cách click button có hình ba dòng n m góc bên trái phía dư i.

View form button
Click lên nút n y ñ xem form c a m t form mà b n ñã ch n. Ghi chú: Nhi u windows trong IDE như Toolbars, Toolbox, Project Explorer .v.v..có th trôi lình bình (floating) hay ñ u b n (docked). B n có th thay ñ i v trí chúng b ng cách n m vào Title Bar c a window r i d i ñi. Dĩ nhiên b n cũng có th m r ng hay làm nh m t window b ng cách d i m t c nh vertical hay horizontal c a nó. Khi ñ m t window lên trên m t window khác chúng có th tìm cách dính nhau. Trong hình dư i ñây, Properties Window và Form Layout ñã ñư c kéo ra ngoài cho floating.

Nh n tr giúp trong khi ñang làm vi c
Trong khi l p trình b n có th c n tìm hi u các thông tin liên quan ñ n các commands, functions .v.v.. c a VB6. B n có th kh i ñ ng Microsoft Developer Network | MSDN Library Visual Studio 6.0 t nút Start, hay click Help | Contents t Menu Bar c a VB6, hay ch n m t keyword (highlight keyword) r i n F1 ñ ñ c Help.

N i dung Help bao g m nhi u ñ c ñi hơn. B n có th d a trên Contents ñ nh c ñ n m t keyword hay Search ñ ngu n t nhi u ñ c tính khác nhau ph

m ñư c thi t k ñ th c hi n vi c tìm ki m thông tin d dàng ñ c tài li u như m t quy n sách, Index ñ ñ c nh ng ño n có tìm m t tài li u nhanh hơn. Ví d , vi c g r i thông tin b t thu c vào lo i ñ án mà b n ñang làm vi c. Các liên k t ñư c

6

mô t trong ph n n y th c hi n vi c tìm ki m d dàng hơn. Ngoài ra, b n cũng có th click See Also dư i tiêu ñ c a ch ñi m ñ xem các tiêu ñ c a các ch ñi m mà b n có th ñi ñ n ho c liên h ñ n nhi u thông tin.

Context Sensitive Help (tr giúp trong ñúng tình hu ng)
Nhi u ph n c a VB6 là context sensitive, có nghĩa là lúc b i r i ch c n n nút F1 ho c highlight keyword r i nh n F1 là ñư c thông tin nh ng gì liên h tr c ti p v i tình hu ng hi n gi c a b n. B n có th nh n F1 t b t kỳ ph n context sensitive nào c a giao di n VB6 ñ display thông tin Help v ph n ñó. Các ph n context sensitive là:
• • • • • •

Các Windows c a VB6 như Properties, Code .v.v.. Các control trong Toolbox. Các Object trên m t form ho c Object tài li u. Các ñ c tính trong Window Properties. Các keywords c a VB6 Các thông báo l i (error messages)

Ngoài ra, trong Help thư ng có Example. B n click lên ch Example ñ display m t thí d minh h a cách dùng m t function hay property.

Microsoft on the Web
Web site c a Microsoft ch a nhi u thông tin c p nh t cho nh ng ngư i l p trình VB6. Trang ch Visual Basic ñ t t i URL http://www.microsoft.com/vbasic/. Thông tin có s n t i ñ a ch n y bao g m:
• • •

C p nh t các ñ c tính m i, các phiên b n s n ph m, các s n ph m liên h , các thuy t trình (seminar) và các ho t ñ ng (event) ñ c bi t. Thông tin b sung trên các ñ c tính VB6 ch a trong các bài vi t g i là White Papers, các mách nư c (tips) và các trình tr giáo, ngu n ñào t o. S n ph m m i t i xu ng (download) bao g m s c p nh t ñ n các file chương trình, các c p nh t tr giúp, các trình ñi u khi n, và các file liên h khác c a VB6.

ð truy c p Web site c a Microsoft, t menu Help ch n Microsoft on the Web r i ch n menu con tùy thích như dư i ñây.

7

Ghi chú: M t s n i dung trên Web site c a Microsoft ñư c t i ưu hóa dành cho Microsoft Internet Explorer và không th display ñ y ñ trong m t b trình duy t (browser) khác. Do ñó b n nên ch dùng Internet Explorer làm browser trên máy b n mà thôi.

Chương Hai- Vi t chương trình ñ u tiên
B n ñang làm quen v i môi trư ng tri n khai l p trình (Integrated Development Environment - IDE) c a MS VB6 và r t nóng ru t mu n vi t nh ng dòng mã ñ u tiên ñ chào m ng th gi i. Ta th ôn l i m t s v n ñ mà có l b n ñã bi t r i. M t chương trình Visual Basic g m có ph n mã l p trình và các hình nh (visual components). B n có th thi t k ph n hình nh b ng cách dùng nh ng ñ ngh (Controls hay Objects) t Túi ñ ngh (Toolbox) n m bên trái. N u b n không th y cái Túi ñ ngh thì dùng m nh l nh Menu View|Toolbox ñ b t nó hi n ra. Khi b n b t ñ u thi t k m t chương trình b ng cách ch n Standard EXE, môi trư ng tri n khai l p trình (IDE) cho b n s n m t Form tên là Form1. B n có th ñ i tên (Name) nó trong cái c a s Propeties n m phía dư i bên ph i (trong hình dư i ñây ta edit Name property c a Form1 thành ra frmMainForm). B n cũng có th s a ñ t a (Title) c a form ra cái gì có ý nghĩa hơn b ng cách ñ i Caption c a form cũng trong c a s Propeties (trong hình dư i ñây ta edit Caption property c a form thành ra "Chi tiet cua ban toi").

8

S p ñ t các v t d ng lên Form
Mu n ñ t m t Control lên Form, click hình cái Control trong Toolbox r i Drag (b m nút trái c a con chu t r i kéo cho thành hình ch nh t trư c khi buông nút trái ra) con chu t trên Form v thành c c a Control. Nh ng Controls b n s dùng thư ng nh t t Toolbox là Label (nhãn), Textbox (h p ñ ñánh ch vào) và CommandButton (nút b m m nh l nh).

Trong hình trên ta có ba Label và ba Textbox. Mu n s a ch Label1 ra "Ten" thì edit Property Caption. Còn Textbox không dùng Property Caption mà dùng Property Text. Ta cũng có th thay ñ i các Property Caption và Text trong khi ch y chương trình (at run-time). Trong lúc thi t k (design time) b n có th s a ñ i ki u ch c a nh ng Controls b ng cách edit Property Font c a chúng trong c a s Properties (click bên ph i c a Property Font trong Properties Window, IDE s pop-up cái Font dialog ñ b n l a ch n nh ng ñ c tính c a Font như trong hình dư i ñây).

N u b n th y b c mình t i sao cái c ch t có (default size) c a các Control hơi nh , b n có th gi i quy t b ng cách s a c ch c a chính Form cho nó l n hơn. Vì khi m t Control ñư c ñ t lên m t Form, nó th a k c ch c a Form. ð s p x p cho m t s Control th ng hàng v i nhau b n ch n c nhóm r i dùng m nh l nh Menu Format|Align|Lefts .v.v..N u b n chưa bi t cách ch n m t nhóm Control thì có hai cách. Cách th nh t b n ñè nút Shift trong khi click các Control b n mu n ch n. Cái Control mà b n ch n sau cùng s là cái chu n ñ các Control khác s làm gi ng theo. Cách th hai là Drag cho s i dây thun (rubber band) b c chung quanh các Control. Trong trư ng h p các Control n y n m trong m t container, thí d như m t khung (Frame) hay PictureBox, thì b n ph i click Form trư c, r i ñè nút Ctrl trong khi Drag rubber band bao các Control.

9

Ch a m i th

c am td

án VB

T i ñây b n ñ ý th y trong c a s bên ph i, phía trên, g i là Project Explorer, có hình gi ng như m t cái cây (tree) cho th y ta có m t Form trong m t Project (d án). Project là m t cách ti n d ng ñ ta s p x p nh ng gì c n thi t cho m t d án. Thư ng thì m t d án có nhi u Form và có th c n nh ng th khác. M i Form s ñư c ch a vào ñĩa dư i d ng "frmMainForm.frm". B n save m t form b ng menu command File | Save formfilename.frm. N u trong Form1 có ch a hình nh (thí d b n dùng Properties Window ñ ch n m t icon hình gương m t cư i làm icon cho frmMainForm) thì các hình nh c a frmMainForm s ñu c t ñ ng ch a trong h sơ "frmMainForm.frx". Lưu ý là không nh t thi t tên c a h sơ (file) mà b n ph i cho bi t khi ch a (save) ph i gi ng như tên c a Form mà b n dùng trong chương trình. Tuy nhiên b n nên dùng cùng m t tên cho c hai ñ sau n y d tìm h sơ n u có th t l c. Theo qui ư c thông thư ng, các Form ñư c ñ t tên b t ñ u b ng "frm", thí d như "frmMainForm". Khi b n save m t Project thì có nghĩa là save t t c h sơ dùng cho d án, k c các Form và m t h sơ cho chính Project, thí d như "MyFirstProg.vbp" ("vbp" là vi t t t ch Visual Basic Project). B n save Vb6 project b ng menu command File | Save Project. À, mu n ñ i tên Project, b n click lên hàng trên cùng bên ph i trong c a s Project Explorer (Project1 (Project1.vbp)), r i edit tên c a Project trong c a s Properties phía dư i. B n nên ch a t t c nh ng h sơ dùng cho cùng m t Project trong cùng m t t p (Folder/Directory). B n có th dùng Notepad ñ m ra xem chơi, coi trong "frmMainForm.frm" có gì. B n s th y trong y g m có hai ph n: ph n ñ u là di n t các Control n m trong Form, ph n còn l i là mã l p trình mà b n vi t. B n cũng s chú ý là các properties mà b n ñã s a cho các Control ñ u ñư c ghi l i trong ph n ñ u nói trên. VB d a vào ph n di n t các Control ñ thi t l p l i (reconstruct) hình nh c a Form.

10

Sau n y, khi ñã lão luy n VB, b n có th dùng m t chương trình t ñ ng ch (generate) ra nh ng hàng di n t các Control cho m t Form. ðó là k thu t dùng trong các Wizards c a VB ñ ch m t s chương trình kh i ñ u cho chúng ta t các b ng k m (Template).

Thêm mã l p trình ñ x lý m t s c
H u h t l p trình trong Visual Basic là vi t mã ñ x lý các s c (Event). Thí d mu n ch m d t chương trình, ngư i s d ng s click nút "Xuat". ð th c hi n ñi u n y trong khi tri n khai chương trình b n doubleClick (click liên ti p 2 l n) nút "Xuat". VB IDE s vi t s n cho b n cái v c a m t Subroutine:
Private Sub cmdXuat_Click() End ' B n ch vi t thêm dòng n y ñ k t thúc chương trình End Sub

ð ý là tên (Name) c a nút Xuat là "cmdXuat" ("cmd" là vi t t t ch CommandButton), VB g n thêm d u g ch dư i và Event Click ñ làm thành tên cmdXuat_Click c a Sub, chương trình nh s ñư c x lý khi ngư i s d ng click nút Xuat. Chương trình nh hay Subroutine n y còn ñư c g i là Event Handler cho Event Click. Hàng ch xanh lá cây là dùng ñ gi i thích cho l p trình viên (g i là Comment), VB s hoàn toàn không chú ý ñ n nó khi x lý Sub cmdXuat_Click. Comment có nghĩa là chú thích. Trong VB chú thích b t ñ u b ng d u single quote '. Khi VB th y d u n y là nó b qua nh ng gì còn l i trên dòng mã.

11

Là L p trình viên chuyên nghi p b n nên t p thói quen dùng Comment m i nơi ñ giúp ngư i khác và chính b n hi u chương trình c a mình. Nên nh là ti n phí t n ñ b o trì m t chương trình thì ít nh t là tương ñương v i s ti n b ra l n ñ u ñ tri n khai. B o trì có nghĩa là thăm vi ng l i chương trình ñ s a l i (fix bug) và thêm các ñ c ñi m cho hay hơn (enhancement). Nói chung h b n làm ñi u gì bí hi m hay c c c thì làm ơn gi i thích rõ ràng. N u mu n c t m t dòng mã VB ra làm hai dòng thì ch m d t dòng th nh t b ng d u g ch dư i _. Ti p theo, b n doubleClick nút "Viet vao dia" và vi t nh ng hàng mã sau:
Private Sub cmdViet_Click() Open "myFriends.txt" For Output As #2 ' M m t h sơ ñ vi t ra và g i là c ng s 2 ' Vi t vào c ng s 2: Tên, ð a ch và Tu i, ngăn cách nhau b ng d u ch m ph y Print #2, txtTen & ";" & txtDiachi & ";" & txtTuoi Close #2 ' ðóng c ng s 2 End Sub

Trong Sub cmdViet_Click, trư c h t ta m m t h sơ tên là "myFriends.txt" và g i nó là c ng s 2. Sau khi m h sơ ñ vi t ra ta ráp Tên, ð a ch và Tu i l i, ngăn cách b ng d u ch m ph y (;) ñ ñánh d u nh sau n y ta mu n g riêng ba th ra tr l i. D u "&" là operator ñ ráp (concatenate) hai dòng ch (text string) l i v i nhau. Print #2 có nghĩa là vi t ra c ng s 2, t c là h sơ "myFriends.txt". Th chúng ta vi t ra c ng 2 là Tên, ð a ch và Tu i (txtTen & ";" & txtDiachi & ";" & txtTuoi).

Nh ng r c r i c a vi c m m t h sơ
Cái c ng s 2 trên là ta t ch n (arbitrary). Th t ra mu n g i c ng s m y cũng ñư c, mi n là chưa có ph n nào khác trong cùng chương trình n y ñang dùng c ng s y. ðây là m t cách VB làm vi c cho ti n thay vì g i nguyên m t cái tên h sơ dài. N u mu n ch c ch n không trùng s c ng v i ch nào khác, ta có th làm như sau:
fileNo = freefile

R i thay th s 2 b ng ch fileNo trong Sub cmdViet_Click. freeFile là m t Function (chương trình nh dùng ñ tính ra m t th gì) nh VB c p phát cho m t con s ñ i di n h sơ chưa ai dùng. Ch Output trong câu ( Open "myFriends.txt" For Output As #2 ) dùng ñây ñ nói t CPU (Central Processing Unit) ta mu n "vi t ra" m t h sơ. Khi m m t h sơ ñ vi t ra ki u n y thì n u h sơ chưa có nó s ñư c d ng nên (created). N u h sơ ñã có r i thì nó s b xoá b (delete) và ñ ng th i m t h sơ tr ng và m i s ñư c d ng nên. ð ng t chuyên môn là "vi t ch ng lên" (overwrite). N u ta m m t h sơ ñ "ñ c vào" thì dùng ch "Input" thay vì "Output". Còn n u "vi t thêm" vào m t h sơ có s n (ch không overwrite h sơ y) thì dùng ch "Append" thay vì "Output". Trong trư ng h p y b n ph i ki m xem h sơ "myFriends.txt" ñã có s n chưa. B n có th vi t như sau:
If Dir("myFriends.txt") <> "" then ' N u h sơ "myFriends.txt" hi n h u Open "myFriends.txt" For Append As #2 ' M m t h sơ ñ vi t thêm và g i là c ng s 2 Else Open "myFriends.txt" For Output As #2 ' M m t h sơ ñ vi t ra và g i là c ng s 2 End If

Function Dir("myFriends.txt") dùng trên s cho ta tên c a h sơ n u h sơ hi n h u, ngư c l i nó s cho m t dòng ch tr ng (empty string), bi u hi u là "". T i ñây, n u lanh ý b n s h i h sơ "myFriends.txt" n m folder nào. Câu tr l i là không bi t ch c. N u b n chưa ch a (save) chương trình vào dĩa (vì m i vi t) thì nó n m folder c a VB6.EXE. Còn như ñã ch a chương trình r i thì có l nó n m folder c a chương trình b n. Mu n h sơ "myFriends.txt" luôn luôn ñi cùng v i chương trình, b n có th làm như sau: 12

MyLocalFolder = App.path ' L y folder c a chương trình x lý c a b n If Right(MyLocalFolder,1) <> "\" then ' N u ch cu i cùng không ph i là backslash MyLocalFolder = MyLocalFolder & "\" ' thì g n thêm m t backslash cu i End If ' M m t h sơ v i tên có folder (full pathname) ñ vi t ra và g i là c ng s 2 Open MyLocalFolder & "myFriends.txt" For Output As #2

Cu i cùng ta ñóng h sơ l i b ng câu Close #2.. T rày VB có th c p s 2 ñ làm c ng cho ch khác trong chương trình.

Default Property c a m t Control
"txtTen" ñư c dùng ñây là vi t t t cho "txtTen.text", vì Default Property c a m t TextBox là text c a nó. Default Property c a m t Control là Property ñư c VB dùng khi b n ch cho tên c a Control mà thôi. Trong khi ñó Default Property c a Label là Caption. Vì txtTen ñư c dùng như txtTen.txt ñ nói ñ n m t dòng ch , nên trong chương trình ta nh c ñ n nó y như m t variable (mã s ) dùng cho m t string. Do ñó v i qui ư c dùng ba ch ñ u "txt" cho tên c a m t Textbox giúp ta nh n di n ngay nó không ph i là m t string variable bình thư ng. Hãy lưu ý s khác bi t khi g i m t Sub trong hai trư ng h p sau:
Call CheckmyTextbox v n CheckmyTextbox dòng ch txtDiachi ' txtDiachi ñư c xem là txtDiachi.text, m t (txtDiachi) ' txtDiachi ñư c xem là Textbox tr n

Th

t

các Control trên m t Form

Trong chương trình n y ta mu n ngư i x d ng cho vào d ki n theo th t "Tên, ð a ch , Tu i". Khi m i vào, ta mu n cái d u ch p t t (cursor ) n m trong txtTen ngay ñ ngư i x d ng kh i m t công click vào Textbox y khi mu n mang cursor tr l i ñó. Ta nói là txtTen có cái Focus. Sau khi ngư i x d ng ñã cho tên vào r i, cô s ñánh nút Tab ñ di chuy n cursor qua Control ti p theo, mà ta mu n là txtDiachi. ð s p th t các Control cho s di chuy n c a cursor khi ngư i x d ng ñánh nút Tab ta edit Property TabIndex c a các Control. TabIndex b t ñ u b ng s 0. Nhi u khi ngư i x d ng thích dùng nút Enter thay vì Tab ñ di chuy n Cursor qua Control ti p theo, b n có th làm như sau cho Textbox txtTen:
Private Sub txtTen_KeyPress(KeyAscii As Integer) If KeyAscii = 13 Then ' N u nút b m là Enter SendKeys "{TAB}" ' gi m o g i nút Tab KeyAscii = 0 ' Nu t tr ng nút Enter ñ Windows không còn lo cho nó End If End Sub

Cho các Textbox khác như txtDiachi, txtTuoi b n cũng làm tương t như v y. Khi b n doubleClick txtTen l n ñ u ñ vi t mã, VB cho b n Private Sub txtTen_Change(). B n ph i click cái Combobox bên ph i, phía trên c a Code Window, cho nó m ra và ch n Event KeyPress.

13

N u b n mu n chương trình mình còn chuyên nghi p hơn, b n cho phép ngư i x d ng b m nút Alt+o (b m nút Alt xu ng trong khi b m nút o) ñ mang Cursor v txtTuoi hay Alt+d ñ mang Cursor v txtDiachi. Mu n th b n ph i thêm vào d u "&" phía trư c các ch T, D và o trong Caption c a các label lblTen, lblDiachi và lblTuoi. K ñó b n ph i cho giá tr TabIndex c a lblTen, txtTen, lblDiachi, txtDiachi, lblTuoi, txtTuoi liên ti p là 0,1,2,3,4,5. Khi ngư i x d ng ñánh Alt+o, VB s mang Cursor v nhãn lblTuoi, nhưng vì không có ch cho nó ñáp trong label nên nó ph i ñáp vào Control k ñó, t c là txtTuoi. Khi ta ñã cho TabIndex c a các Control nh ng giá tr k trên thì khi Form hi n ra Cursor s n m trong TextBox txtTen vì m c d u lblTen có TabIndex nh nh t(0), nó không ph i là ch Cursor ñáp lên ñư c, nên Cursor ph i ñáp lên textbox có TabIndex value k ñó, t c là 1. N u b n không mu n Cursor ng ng l i m t TextBox nào thì edit Property TabStop c a TextBox ñó cho b ng False. Trong trư ng h p y ngư i s d ng v n có th click vào TextBox và s a dòng ch ñó ñư c như thư ng. N u b n th t s không mu n cho phép ngư i s d ng s a gì TextBox thì edit Property Enabled b ng False hay Property Locked b ng True. Khi Enabled c a m t TextBox b ng False thì TextBox tr nên m ñi. Nhân ti n ta edit thêm d u "&" phía trư c các ch X và V trong Caption các CommandButton "Xuat" và "Viet vao dia". Sau n y ngư i s d ng có th b m Alt-X coi như tương ñương v i click nút "Xuat". N u nh trong Form b n có nhi u Textbox quá, ñ i nút Enter ra nút Tab cho t ng Textbox m t thì m t công quá. B n có th làm m t cái chung cho c Form. T c là nói r ng b n không c n bi t nút Enter v a m i ñư c ñánh TextBox nào, b n c nh m m t ñ i nó ra nút Tab. Trư c h t b n ph i ch n (select) Form r i edit Property KeyPreview c a nó thành True. B n làm vi c n y ñ d n Form gi t cái nút ngư i s d ng ñánh (keystroke) trư c khi TextBox th y. Form s tráo nút Enter thành Tab r i l ng l ng trao cho TextBox. B n có th thay th t t c các KeyPress event handler c a các TextBox b ng ño n mã như sau:
Private Sub Form_KeyPress(KeyAscii As Integer) If KeyAscii = 13 Then ' N u nút b m là Enter SendKeys "{TAB}" ' gi m o g i nút Tab KeyAscii = 0 ' Nu t tr ng nút Enter ñ Windows không còn lo cho nó End If End Sub

Khi b n doubleClick lên b t c ch nào trên Form không có Control n m, l n ñ u ñ vi t mã, VB cho b n Private Sub Form_Load(). B n ph i click cái Combobox bên ph i, phía trên c a Code Window, cho nó m ra và ch n Event KeyPress.

ðem ra trình làng
ð làm thành m t h sơ áp d ng EXE, b n dùng m nh l nh Menu File|Make MyFirstProg.exe. Cho thêm chút hương v c a cu c ñ i tôi click Form r i edit Property Icon, ch n cho nó t folder:

14

D:\Program Files\Microsoft Visual Studio\Common\Graphics\Icons\Misc m t icon hình gương m t cư i. R i b m m nh l nh Menu File|Save Project. Khi dùng Explorer ñ xem các h sơ c a MyFirstProg.vbp b n s th y như dư i ñây:

ðáng l tôi dùng m t folder khác thay vì VB98 ñ ch a d án MyFirstProg.vbp. H sơ MyFirstProg.vbw là Workspace (ch làm vi c) dành cho VB, ta không nên ñ ng t i. B n có th làm m t Shortcut cho MyFirstProg.exe v i cái icon hình gương m t cư i ñ t lên Desktop ñ ch y bên ngoài IDE c a VB. Có l b n mu n Download h sơ:MyFirstProg.zip, nén chung t t c các h sơ nói trên trong d án MyFirstProg.vbp. Bây gi ngay trong VB IDE b n có th ch y chương trình b ng cách dùng m nh l nh Menu Run|Start hay b m F5.

B n cũng có th Click lên d u tam giác ch v bên ph i (nút Play c a cassette) n m trong toolbar ngay phía dư i VB menu.

Cách nén các files trong m t folder thành m t zip file duy nh t
ð g i nhi u files b ng cách ñính kèm (attach) m t Email trên Internet ta c n ph i nén các files y thành m t file duy nh t, g i là Zip file. Trư c h t, trong Window Explorer b n ch n nh ng files b n mu n Zip chung l i. B n ch n nhi u files b ng cách ñè nút Ctrl trong khi click lên tên t ng file m t. N u b n ñè lên nút Shift, thay vì nút Ctrl, thì c m i lúc b n click, Window Explorer s select c m t d c tên các files n m gi a tên hai files b n click m i nh t. Ngoài ra b n cũng có th dùng Menu Command Edit | Select All, hay Ctrl+A ñ select t t c các files trong m t folder. ðây là trư ng h p b n s dùng khi Zip t t c c các files trong m t VB6 project ñ g i qua Th y/Cô. Sau khi ñã select các file r i, b n right click lên các file y ñ context menu pop-up. Ch n Add to Zip. N u b n không th y pop-up command Add to Zip thì là b n chưa install chương trình Winzip. Trong trư ng h p y, download Winzip t Internet và install.

15

Bây gi b n th kh i ñ ng VB6, ñi d o quanh nó ñ th bi t các ph n c a VB6 IDE, và th làm theo như bài n y. N u có th c m c gì thì h i Tutor c a b n.

Chương Ba - Form và các Controls thông thư ng

H u h t các chương trình VB6 ñ u có ít nh t m t Form. Khi ta ch y chương trình, Form n y s

hi n ra trư c h t ñ ta ra l nh nó làm chuy n gì. Cái Form tr ng không ch làm ñư c gì nhi u, nên ta ñ t lên Form nh ng controls như Textbox(h p ñ ñánh ch vào), Label(nhãn), Commandbutton(nút b m m nh l nh), .v.v.. Các controls cho ta enter các d ki n ñ chương trình dùng x lý, và các controls cũng hi n th (display) k t qu cho chúng ta xem.

S p ñ t controls lên Form
Ta hãy b t ñ u thi t k m t chương trình m i (New Project) b ng cách ch n Standard EXE, môi trư ng tri n khai l p trình (IDE) cho b n s n m t Form tên là Form1. Mu n ñ t m t Control lên Form, click hình cái Control trong Toolbox r i Drag (b m nút trái c a con chu t r i kéo cho thành hình ch nh t trư c khi buông nút trái ra) con chu t trên Form v thành c c a Control. M t cách khác ñ ñ t m t control lên Form là doubleclick cái Control trong Toolbox, m t hình control s hi n ra trên Form. K ñó b n d i control ñi ñ n ch mình mu n và resize nó. N u b t c lúc nào b n không th y Túi ñ ngh (Toolbox) n m bên trái, b n có th dùng m nh l nh Menu View|Toolbox ñ b t nó hi n ra. Có m t cách khác là click lên toolbox icon trên toolbar chính c a VB6.

Nên nh r ng Toolbox cũng là m t window như các window khác. Khi nó hi n lên r i b n có th n m (b m nút trái c a con chu t và gi như v y ch không buông ra) title nó ñ d i ñi nơi khác. B n có th ñóng nó b ng cách click lên d u x góc ph i phía trên. N u right click trên Toolbox, nó s display context sensitive menu, trong ñó có property dockable (có th ñ u b n) . N u m t window là

16

dockable, sau khi b n d i nó ñi kh i vi trí docked bình thư ng c a nó, b n có th dock nó l i như c b ng cách double click lên title c a nó.

Resize và di chuy n control
Khi b n select m t control (click lên nó), chung quanh control s hi n ra resize handle, 8 nút ñen d c theo chu vi c a control.

Click lên các nút ñen c a resize handle, b n có th resize control. Có m t cách khác ñ resize control là dùng Shift + ArrowKey. B m nút Shift trong khi b m m t arrow key, control s l n ra hay thu h p theo chi u c a ArrowKey. Lưu ý: M t s control có kích thư c t i thi u, b n không th làm cho nó nh hơn ñư c. Thí d như Combobox, nó ph i cao ñ ñ display m t hàng text. Tương t như th , b m nút Ctrl trong khi b m m t arrow key, control s di chuy n theo chi u c a ArrowKey. Ngoài ra, nên nh r ng trong lúc chương trình ch y (at run-time), trong code ta có th thay ñ i kích thư c và v trí các controls d dàng, th m chí có th làm cho chúng hi n ra hay bi n m t b ng cách s a ñ i value các property left, top, width, height và visible c a các controls.

Alignment Grid
ð giúp b n s p ñ t ngay ng n các controls trên m t form, VB6 cho b n Alignment Grid. Nó là nh ng d u ñen c a các hàng d c và xuôi trên form. B n có th làm cho các d u ñen c a grid trên form bi n m t b ng cách dùng menu command Tools | Options ñ display Option Dialog, k ñó ch n Tag General và clear checkbox "Show Grid":

17

B n cũng có th nhân d p n y thay ñ i kho ng cách chi u r ng (Width) và chi u cao (Height) c a các ch m ñen c a grid. Kích thư c nh nh t c a Width hay Height là 24. Hãy so sánh hai trư ng h p form có và không có Show Grid như dư i ñây:

Control Locking
M t khi b n ñã s p ñ t kích thư c và v trí c a các control trên form r i, r t d ta tình c thay ñ i các ñ c tính y vì vô ý click lên m t control. Do ñó VB6 cho ta Menu command Format | Lock Controls ñ khóa chúng l i. Sau khi khóa, cái hình ng khóa trên menu b chìm xu ng.

N u sau n y b n mu n thay ñ i kích thư c ho c v trí c a chúng thì nh dùng Menu command Format | Lock Controls l i. Sau khi m khóa, cái hình ng khóa trên menu hi n ra bình thư ng.

Cài ñ t các Properties c a Form
Nhi u property c a m t form nh hư ng ñ n di n m o v t lý (physical appearance) c a nó. Property Caption s quy t ñ nh text ñư c hi u th trong title. N u Property BorderStyle c a form không ph i là Sizable thì User không th resize form at run-time. Property Icon quy t ñ nh hình icon ñu c dùng trong title c a form, nh t là khi form thu nh (minimized). N u b n không mu n cho phép User minimize hay maximize form thì set value c a property MinButton, MaxButton ra False. N u property ControlBox là False thì form s không có nút minize, maximize hay close (x) trên góc ph i c a nó, ñ ng th i form cũng không display c icon bên góc trái title như trong hình dư i ñây:

18

V trí ñ u tiên (top,left) c a form có th ñư c thay ñ i trong design time b ng cách di chuy n hình nh c a nó trong window Form Layout:

Property WindowState xác ñ nh Form s có kích thư c bình thư ng (normal=0), hay minimized (=1), maximized =(2). Lưu ý là property Font c a Form s ñư c các control n m trên nó th a k . T c là khi b n ñ t m t control lên form, property Font c a control y s t ñ ng tr nên gi ng y như c a form.

Vài Event thông d ng c a Form
Nhìn t m t phương di n, Form cũng gi ng như Control. Ta có th instantiate m t form nhi u l n ñ có nhi u form tương t nhau. Trong thí d dư i ñây, ta instantiate Form2 hai l n ñ có MyForm và YourForm:
Private Sub CmdCreateForms_Click() Dim MyForm, YourForm Set MyForm = New Form2 MyForm.Caption = "This is My Form" MyForm.Show MyForm.Move 1000, 1000 Set YourForm = New Form2 YourForm.Caption = "YOUR FORM IS HERE" YourForm.Show YourForm.Move 2000, 2000 End Sub

M t Form cũng có nhi u Events r t h u d ng.

F orm_Initialize: Event n y xãy ra trư c nh t và ch m t l n thôi khi ta instantiate form ñ u tiên. Ta dùng Form_Initialize event ñ th c hi n nh ng gì c n ph i làm chung cho t t c các instances c a form n y.

F orm_Load: Event n y xãy ra m i l n ta instantiate m t form. N u ta ch dùng m t instance duy nh t c a m t form trong chương trình thì Form_Load coi như tương ñương v i Form_Initialize. Ta dùng Form_Load event ñ initialise variables, controls v.v. cho instance n y. Bên trong Form_Load b n không th dùng Setfocus cho m t control nào trên form vì form chưa

19

h n thành hình (ra ñ i). Mu n làm vi c y b n ph i delay (trì ho n) m t chút xíu b ng cách dùng Control Timer ñ ñ i cho Form_Load ñư c hoàn t t. Thí d :

Private Sub Form_Load() Timer1.Interval = 500 Timer1.Enabled = True End Sub Private Sub Timer1_Timer() Timer1.Enabled = False ' Timer1_Timer only execute once txtName.Setfocus ' Make Tab Cursor start at TextBox txtName End Sub

F orm_Activate: M i l n m t form tr nên active (current) thì nó generate m t Activate event. Ta có th dùng event n y ñ refresh display trên form.

F orm_QueryUnload: Khi User click d u x phía trên bên ph i ñ close form thì nó generate QueryUnload event. Syntax c a Sub n y như dư i ñây:

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer) End Sub

Event n y cho ta m t d p ñ cancel Close action c a form (t c là không cho User close form) b ng cách set Cancel b ng 1. UnloadMode cho ta bi t ai, task hay form nào mu n close form n y. Ngoài ra, b n cũng nên bi t r ng m t form t ñ ng Load hay tr nên active n u b n nh c ñ n nó, thí d như dùng Form2.List1. Khi m t form ñã ñư c loaded r i b n có th hide (làm cho bi n m t) nó. K ñó, khi b n show form ra tr l i thì form không có gì thay ñ i. Nhưng n u b n Unload m t form (thí d b ng cách dùng Unload Form2 ), r i sau ñó load tr l i b ng cách dùng Form2.Show ch ng h n, thì Form ph i tr i qua quá trình Form_Load, và dĩ nhiên form m t t t c nh ng gì có trư c ñây. Ngoài ra, Hide/Show m t form ñã ñư c loaded r i thì r t nhanh, còn Unload/Load thì m t thì gi hơn. Khi b n Show m t Form chưa hi n h u thì form s ñư c loaded và show. ðôi khi b n mu n Load m t form, r i làm vi c v i nó trư c khi Show, trong trư ng h p ñó b n dùng Load Form2 r i m t ch p sau dùng Form2.Show.

MDI Form
ðôi khi b n mu n có m t MDI form, t c là m t form có th ch a nhi u form con bên trong. D ng MDIform n y thư ng ñư c dùng trong các application như wordprocessor ñ có th m nhi u document cùng m t lúc, m i document ñư c hi n th trong m t form con. ð có m t MDIForm b n c n ph i dùng menu command Project | Add MDI Form. M i VB6 project ch có th có t i ña m t MDIform. Mu n m t form tr thành m t form con b n set property MDI Child c a nó thành True. At run-time b n không th hide (bi n nó thành invisible) m t MDIChild form, nhưng có th minimize nó. N u b n th t s mu n hide nó thì ph i dùng mánh l i là cho nó v trí (top,left) s âm l n hơn kích thư c nó ñ nó n m ngoài t m hi n th c a form. Trong m t chương trình dùng MDI Form, khi b n click MDI Form nó không nh y ra phía trư c và che các form con, nhưng v n luôn luôn n m dư i.

20

Controls là gì?
Controls v a có hình, v a có code ch y bên trong m t window nho nh , gi ng như m t form. Khi ta l p trình VB6 ta l p ráp các controls (là nh ng v t d ng ti n ch ) trên m t hay nhi u form ñ có m t chương trình nhanh chóng. Ta giao d ch v i m t control qua ba ñ c tính c a control:

P roperties: t p h p các ñ c tính c a control mà ta có th n ñ nh lúc design time hay run-time. Có nhi u properties v di n m o, n u ta thay ñ i at design time s th y k t qu hi n ra l p t c, thí d Font hay màu s c.

M ethods: nh ng gì control th c hi n ñu c, t c là nh ng kh năng c a nó. E vents: nh ng s c mà control s thông báo cho chúng ta bi t khi nó xãy ra v i control. Khi m t event xãy ra VB6 s x lý m t Event Handler (thí d như Sub Command1_Click()), mi n là chúng ta vi t code s n trong ñó. N u không có code thì coi như chúng ta không thèm bi t ñ n các event lo i ñó. Có m t s Events mà chúng ta thư ng x lý là:

o

C lick : xãy ra khi user click lên control. Ta thư ng dùng nó cho CommandButton và Listbox. M ouseDown, MouseUp : m i khi User b m m t mouse button là có m t MouseDown Event, khi User buông nó ra thì có m t MouseUp Event. Ta thư ng dùng MouseDown Event ñ Popup context sensitive menu hay b t ñ u m t di n bi n Drag. Thí d :

o

Private Sub Foods_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single) If Button = vbRightButton Then ' if Right button was pressed PopupMenu mnuActions ' popup a menu End If End Sub Private Sub DrinkList_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single) DrinkList.drag ' Displaying a drag icon to start the drag process End Sub

ð ý là Click không cho chúng ta thêm chi ti t gì v s c , trong khi MouseDown/MouseUp cho ta bi t v trí c a cursor, button nào c a Mouse ñư c b m và lúc y User có b m nút Shift, Ctrl hay Alt không. M i Click là ñi ñôi v i m t c p MouseDown/MouseUp. N u b n mu n x lý v a Click l n MouseDown thì ph i c n th n. Thí d b n mu n v a handle Click event v a handle Mouse Drag thì ph i làm sao phân bi t hai trư ng h p. N u không User ch mu n th y k t qu c a Click mà l i th y control b t ñ u display m t Drag icon thì s b c mình.
o

K eyPress : xãy ra khi user Press m t key. Ta thư ng dùng nó cho TextBox ñ lo i ra (filter out) các keystrokes ta không ch p nh n. KeyPress cho ta ASCII value, m t con s có giá tr t 1 ñ n 255, c a key. Trong thí d dư i ñây, m t Enter key s ñư c coi như m t TAB key:

21

Private Sub Text1_KeyPress(KeyAscii As Integer) If KeyAscii = 13 Then KeyAscii = 0 ' Swallow the character to avoid side effect SendKeys "{TAB}" ' Emulate entering a TAB End If End Sub
o

K eyDown, KeyUp : m i KeyPress event là cho ta m t c p KeyDown/KeyUp event. KeyDown/KeyUp cho ta KeyCode và Shift value. ð detect Function key ta c n dùng KeyDown event. Trong thí d dư i ñây, ta display Function key User b m:
Private Sub Text3_KeyDown(KeyCode As Integer, Shift As Integer) If (KeyCode >= 112) And (KeyCode <= 123) Then MsgBox "You pressed the Function key: F" & Trim(Str(KeyCode - 111)) End If End Sub

o

G LotFocus : Control tr nên active khi nó nh n ñư c Focus. Nó s generate m t GotFocus Event. Ta có th dùng nó ñ ñ i màu background c a m t text box như trong thí d dư i ñây:
Private Sub Text2_GotFocus() Text2.BackColor = vbYellow End Sub

o

L LostFocus : Thư ng thư ng h m t Control GotFocus thì trư c ñó có m t Control LostFocus. Ta có th dùng Event n y ñ Validate entry data hay thu x p công chuy n cho m t control v a m t Focus. Trong thí d dư i ñây, n u User không ñánh vào m t con s trong Textbox Text1 thì s ñư c thông báo và Tab Cursor s tr l i Textbox Text1.
Private Sub Text1_LostFocus() If Not IsNumeric(Text1.Text) Then MsgBox "Please enter a number!" Text1.SetFocus End If End Sub

o

r DagDrop : xãy ra khi ta drop m t cái gì lên control . Parameter Source cho ta bi t Control nào ñã ñư c Drag và Drop. Nhi u khi m t control có th nh n drop t nhi u control khác nhau. Trong trư ng h p ñó ta ph i test xem ho c Control Type, ho c Name ho c Tag value c a Source control là gì ñ tùy nghi x lý.

22

Trong thí d dư i ñây, khi User drop mouse xu ng Textbox Text2, n u Source là m t Listbox, không c n bi t Listbox nào, thì ta copy dòng ñư c ch n trong Listbox y qua Textbox Text2.
Private Sub Text2_DragDrop(Source As Control, X As Single, Y As Single) If TypeOf Source Is ListBox Then Text2.Text = Source.Text End If End Sub

TextBox
TextBox là control ñu c dùng nhi u nh t ñ display text và nh n keystroke c a Userñ s a ñ i text có s n hay cho vào text m i. Property chính và default c a Textbox là text, t c là thư ng thư ng Text2.text có th ñư c vi t t t là Text2. Ta có th disable (khi n nó b t l c, không ph n ng gì h t và không cho s a ñ i) m t text box b ng cách set Property Enable ra False (ch s b m ñi), hay Lock (không cho s a ñ i) m t text box b ng cách set Property Locked ra True (ch không b m ). Text có th ñư c Align (Alignment Property) ñ display bên trái, chính gi a hay bên ph i c a h p nó.

B n có th ch n BackColor và ForeColor cho background và text c a TextBox. Dùng Tag Palette khi ch n màu ñ có ñúng m t màu b n mu n.

Dĩ nhiên b n có th l a ch n Font và c ch cho Text v i Font Property. B n gi i h n s characters mà User có th enter cho TextBox b ng cách set MaxLength Property. N u Property Multiline là True thì User có th enter nhi u hàng. At Design time, n u b n mu n enter multiline thì ph i nh b m nút Ctrl khi press Enter m i khi xu ng hàng. N u không VB6 IDE tư ng r ng b n ñã k t thúc editing.

23

Mu n assign cho text box multiline text thì ph i nhét vào m i cu i hàng CarriageReturn và LineFeed characters. Thí d như:
Private Sub Command1_Click() Dim TextStr TextStr = "Bau ra bau lay ong cau" & vbCrLf ' Note: vbCrLf = chr(13) & chr(10) TextStr = TextStr & "Bau cau ca bong ngat dau kho tieu" Text1.Text = TextStr End Sub

N u b n mu n mách nư c cho User v cách dùng m t textbox nào ñó thì có th dùng Property ToolTipText ñ nó display mách nư c m i khi mouse cursor n m lên textbox.

Dùng Property TabIndex ñ n ñ nh th t cho Tab Cursor d ng m i khi User b m nút TAB ñ d i TAB Cursor ñ n Textbox k ti p. N u b n không mu n Tab Cursor d ng m t TextBox nào thì set Property TabStop nó thành False. Tab Cursor không d ng Textbox có Property Enabled b ng False, nhưng v n d ng Textbox có property Locked b ng True. N u b n mu n dùng Textbox làm m t Password field thì set Property PasswordChar b ng "*". Làm như th s ép bu c Textbox display m i character b ng PasswordChar, t c là "*", ñ ngư i khác không ñ c ñư c trong khi User enter m t Paswword.

Properties SelLength, SelStart và SelText N u b n mu n bi t ñư c tình hình hi n th i c a Textbox: SelText cho b n dãy ch ñang ñư c selected. SelStart cho b n v trí c a insertion point (ch cursor flashing). SelLength cho bi t con s characters ñã ñư c selected. N u b n mu n s a ñ i text trong Textbox: SelText cho b n nhét vào m t dãy ch . SelStart cho b n n

24

ñ nh v trí b t ñ u c a dãy ch b n s p select. SelLength n ñ nh s characters b n mu n ch n, b t ñ u t SelStart. Dư i ñây là m t thí d trong ñó ta highlight text tìm ñư c:
Private Sub Form_Click () Dim Search, Where ' Declare variables. ' Get search string from user. Search = InputBox("Enter text to be found:") Where = InStr(Text1.Text, Search) ' Find the given string in Text1.Text. If Where > 0 Then ' If found, Text1.SelStart = Where - 1 ' set selection start and Text1.SelLength = Len(Search) ' set selection length. Else MsgBox "String not found." ' Notify user. End If End Sub

CommandButton
CommandButton r t ti n cho ta dùng vào vi c x lý m t chuy n gì khi User click lên button. Event ta dùng thư ng nh t cho CommanButton là Click. Ta dùng Property Caption c a CommandButton ñ enter cái gì ta mu n display trên button. N u mu n cho phép User dùng ALT+E (ñè nút Atl trong lúc b m nút E) ñ generate event click thì nhét d u "&" trư c ch E trong Caption c a button. Caption s display ch E v i m t g ch dư i. Ngoài ra ta cũng có th cho thêm m t cái hình vào CommandButton b ng cách ch n m t icon cho property Picture và set Property Style ra Graphical, thay vì Standard.

Lúc Run-time b n có th thay ñ i hình hay Caption c a CommandButton. Trong thí d dư i ñây, Caption c a CommandButton CmdOperation flip-flop gi a hai values Stop và Start:
Private Sub CmdOperation_Click() If CmdOperation.Caption = "&Stop" Then CmdOperation.Caption = "St&art" Else CmdOperation.Caption = "&Stop" End If End Sub

Label
M c ñích chính c a Label là ñ display, không cho User Edit như Textbox. Do ñó ta có th dùng Property Font, ForeColor và Backcolor ñ làm cho nó ñ p. Ngoài ra Property BorderStyle có th cho Label l m xu ng n u b n set nó b ng Fixed Single. N u set property BackStyle b ng Transparent s

25

tránh trư ng h p Backcolor c a Label làm cho không ñ p. Label cũng có Property Tabindex. N u b n mu n dùng ALT key ñ mang Tab Cursor v m t Textbox, hãy ñ m t Label v i TabIndex b ng TabIndex c a TextBox tr 1. Gi s Label có Caption là "&Address" thì ALT+A s mang Tab Cursor v TextBox màu vàng như trong thí d dư i ñây:

Ngoài ra nh r ng b n có th thay ñ i Caption c a Label lúc run-time.

CheckBox
CheckBox ñư c dùng ñ User xác nh n có ñ c tính nào m t cách nhanh chóng. Property Value c a CheckBox có th là Checked (làm cho h p vuông có d u, b ng 1), Unchecked (làm cho h p vuông tr ng không, b ng 0) hay Grayed (làm cho h p vuông có d u màu nh t, b ng 2). M t khi bi t r ng CheckBox có Value b ng 1, ta có th ñ c Caption c a CheckBox ñ dùng n u c n.

B n có th dùng Property Alignment ñ làm cho Caption ñ ng bên ph i (Left Justify) hay bên trái (Right Justify) c a h p vuông.

OptionButton
OptionButton ( còn g i là RadioButton) có hình tròn v i m t ch m gi a, thay gì hình vuông v i m t g ch gi a như CheckBox. OptionButton luôn luôn ñư c qui t thành m t nhóm, ch a trong m t container. Container là m t Control có kh năng ch a các controls khác. Frame, PictureBox, hay chính Form ñ u là Container. Sau khi ñ t m t Container lên Form, n u mu n ñ m t OptionButton lên Container, trư c h t ta ph i Select container, r i k ñó ch n OptionButton. S dĩ, t t c OptionButtons ph i n m trong m t container là vì b t c lúc nào, nhi u nh t là m t OptionButton trong container có value True (vòng tròn có ch m gi a). Mu n bi t m t OptionButton có th t s n m trong m t container, b n th kéo cái container ñi ch khác. N u OptionButton b d i theo container thì nó n m trong container. M t cách khác là th kéo OptionButton ra kh i container. N u kéo ra ñư c thì nó không n m trong container.

26

Mu n di chuy n m t OptionButton t container n y sang container khác, b n Cut OptionButton r i Paste nó vô container kia.

ðôi khi m t container n m che trên m t control khác. Mu n mang m t container ra phía sau các controls khác b n Select container r i dùng Menu command Format | Order | Send to Back.

Chương B n - Vi t Code

Trong ba chương ñ u chúng ta ñã h c qua ba b
ðó là:
• • •

ph n chánh c a m t chương trình Visual Basic 6.0.

Forms là cái n n hay khung ñ ta xây d ng User Interface. Controls là nh ng viên g ch ñ ta dùng xây d ng User Interface. Event procedures là code n m phía sau nh ng hình nh, nó là ch t keo dùng ñ dán các Controls l i v i nhau ñ t o thành chương trình áp d ng c a ta.

Như ta ñã th y, t t c các code ñư c x lý (executed) khi có m t Event xãy ra. Thí d như khi User click m t CommandButton (Event Click) hay type nút Tab ñ di chuy n Cursor t Textbox n y (Event Lostfocus) qua Textbox khác (Event GotFocus). Các nhóm code x lý là :
Private Sub Command1_Click() ...

27

End Sub Private Sub Text1_LostFocus() ... End Sub và Private Sub Text2_GotFocus() ... End Sub

Trong khi l p trình, m i l n ta double click lên m t Control c a m t Form là VB6 IDE t ñ ng generate cho ta cái v t hàng Private Sub Control_Event() cho ñ n End Sub ñ chúng ta ñi n nh ng hàng code c a mình vào chính gi a.

ði u khi n th

t x lý các dòng code

Gi d ta vi t m t chương trình Vb6 ñơn gi n như trong hình n y v i hai Textbox tên txtName, txtAge và m t nút tên CmdEnter n m trong m t form tên Form1:

Thông thư ng các dòng code ñư c x lý theo th t t trên xu ng dư i. Thí d như ñ ki m xem các d ki n v a ñư c cho vào các Textbox có tương ñ i h p lý hay không, khi User click nút CmdEnter, ta x lý Sub dư i ñây:
Private Sub CmdEnter_Click() ' Make sure the Name field is not blank If txtName.Text = "" Then MsgBox "Please enter Name" Exit Sub ' Terminate this Sub End If ' Make sure a number is supplied for Age If Not IsNumeric(txtAge.Text) Then MsgBox "Please enter a number for Age" Exit Sub ' Terminate this Sub End If End Sub

Cái Sub nói trên có ch Private n m phía trư c, ý nói ch n i trong cùng m t form ch a Control CmdEnter (t c là Form1 trong trư ng h p n y) ta m i có th g i (dùng) Sub CmdEnter_Click(). Thí d ta mu n khi User b m key "Enter" trên bàn phím sau khi cho vào chi ti t Textbox txtAge thì coi như User ñã click nút CmdEnter. Ta vi t như sau:
Private Sub txtAge_KeyPress(KeyAscii As Integer) If KeyAscii = 13 Then KeyAscii = 0 ' swallow Key Enter to avoid side effect

28

CmdEnter_Click ' Call Private Sub CmdEnter_Click from the same form End If End Sub

Khi ta dùng câu CmdEnter_Click làm m t dòng code (còn g i là g i Sub CmdEnter_Click) thì coi như tương ñương v i nhét t t c 10 dòng codes gi a hai hàng Private Sub CmdEnter_Click() và End Sub t i ch câu CmdEnter_Click, như vi t l i dư i ñây:
Private Sub txtAge_KeyPress(KeyAscii As Integer) If KeyAscii = 13 Then KeyAscii = 0 ' Swallow Key Enter to avoid side effect ' Make sure the Name field is not blank If txtName.Text = "" Then MsgBox "Please enter Name" Exit Sub ' Terminate this Sub End If ' Make sure a number is supplied for Age If Not IsNumeric(txtAge.Text) Then MsgBox "Please enter a number for Age" Exit Sub ' Terminate this Sub End If End If End Sub

Có m t cách nói khác là khi execution ñi ñ n hàng CmdEnter_Click thì nó nh y vào Private Sub CmdEnter_Click() ñ execute cho ñ n h t r i nh y tr l i hàng k ti p trong Private Sub txtAge_KeyPress(KeyAscii As Integer) Trong Private Sub CmdEnter_Click() n u User không ñánh gì vào Textbox txtName thì chương trình s display message "Please enter Name" r i Exit Sub. ðây là cách nh y ngay ra kh i Sub ch không ñ i ph i execute xu ng t i hàng chót.

Dùng IF....THEN statement
Trong Private Sub CmdEnter_Click() trên ta th y có hai ch dùng IF...THEN ñ th xem m t ñi u ki n gì có ñư c th a mãn không. N u ñi u ki n là ñúng v y, t c là True thì ta th c hi n nh ng gì ñu c vi t t hàng IF...THEN cho ñ n hàng END IF. Ngư c l i, n u ñi u ki n không ñúng thì execution nh y xu ng t i dòng code n m ngay dư i dòng END IF. T c là có khi execution s ñi ngang qua, có khi không ñi ngang qua nh ng dòng code gi a câu IF...THEN và câu END IF. ði u ki n trong IF Statement là ph n n m gi a hai ch IF và THEN. Nó ñu c g i là Logical Expression. Ta có:
txtName.text = "" ' content of Textbox txtName is nothing, i.e. an empty string và NOT IsNumeric(txtAge.text) ' content of TextBox txtAge is not a number

Trong Logical Expression th nhì ta dùng Function IsNumeric ñ ñư c cho bi t r ng txtAge.text có ph i là m t con s hay không. Vì ta ch than phi n khi txtAge không ph i là m t con s nên ta ph i ñ thêm ch NOT phía tru c. T c là khi
IsNumeric(txtAge.text) = False thì NOT IsNumeric(txtAge.text) = True

N u gi a IF...THEN và END IF ch có m t dòng code b n có th nh p dòng code lên v i IF...THEN và không dùng END IF. T c là:

29

If theColorYouLike = vbRed Then MsgBox "You 're a lucky person!" End If is equivalent with If theColorYouLike = vbRed Then MsgBox "You 're a lucky person!"

M t Logical Expression có th ñơn gi n (simple) như trong các thí d trên hay r c r i hơn n u ta ráp nhi u simple Logical Expression l i v i nhau b ng cách dùng nh ng t OR và AND. Khi hai Logical Expression ñư c ráp l i b ng ch OR (HAY) thì ch c n ít nh t m t trong hai Expression là TRUE là Logical Expression t ng h p cũng là TRUE. Cái TRUE Table cho OR như sau:
A B A OR B

FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE

FALSE TRUE TRUE TRUE

Trong thí d dư i ñây n u m t ngư i 25 tu i tr lên HAY có l i t c trên 30 ngàn ñô la m t năm thì cho mư n ti n ñư c :
If (PersonAge >= 25) Or (PersonIncome >= 30000) Then LendPersonMoney End If

ð ý cách dùng các d u ngo c ñơn gi ng như trong toán ñ i s . Thông thư ng h cái gì n m trong ngo c thì mình tính trư c. N u có nhi u l p d u ngo c thì tính theo th t t trong ra ngoài. Như trong bài trên ta tính xem PersonAge >= 25 xem là TRUE hay FALSE, r i tính xem PersonIncome >= 30000 xem là TRUE hay FALSE, trư c khi tính k t qu t ng h p, d a vào cái TRUE table cho OR. Khi hai Logical Expression ñư c ráp l i b ng ch AND (Và) thì ch khi nào c hai Expression ñ u là TRUE, Logical Expression t ng h p m i là TRUE. Cái TRUE Table cho AND như sau:
A B A AND B

FALSE FALSE FALSE FALSE TRUE TRUE TRUE FALSE

FALSE FALSE TRUE TRUE

Trong thí d dư i ñây n u h c sinh 18 tu i tr lên và cha m ki m 100 ngàn tr lên m t năm thì ñăng ký h c sinh m t ñ i h c tư:
If (StudentAge >= 18) And (ParentIncome >= 100000) Then EnrollStudentAtPrivateUniversity End If

30

M t Logical Expression có th t p h p c OR l n AND như trong thí d dư i ñây n u h c sinh 18 tu i tr lên và cha m ki m 100 ngàn tr lên m t năm HAY h c sinh có Intelligent Quotient cao hơn 160 thì ñăng ký h c sinh m t ñ i h c tư:
If ((StudentAge >= 18) And (ParentIncome >= 100000)) Or (StudentIQ > 160) Then EnrollStudentAtPrivateUniversity End If

Hai d u ngo c ñơn n m bên ngoài c a:
((StudentAge >= 18 ) And (ParentIncome >= 100000))

không c n thi t vì theo qui ư c, ta tính AND expression trư c khi tính OR expression, nhưng nó giúp ta ñ c d hơn.

Dùng IF....THEN..ELSE statement
Hãy xem thí d :
If (StudentPassmark > 75) Then ' Part A EnrollStudentAtPublicSchool Else ' Part B EnrollStudentAtPrivateSchool End If

N u h c sinh ñ u v i s ñi m trên 75 thì cho h c trư ng công, N U KHÔNG thì ph i h c trư ng tư. T c là n u StudentPassmark > 75 là TRUE thì x lý ph n A, n u không thì x lý ph n B. ð ý ph n A g m nh ng dòng code n m gi a dòng If (StudentPassmark > 75) then và else. Còn ph n B g m nh ng dòng code n m gi a dòng else và end if. Ta có th ráp ch ELSE v i ch IF ñ dùng như trong thí d sau ñây: <
If (StudentPassmark > 75) Then EnrollStudentAtPublicSchool ElseIf (StudentPassmark >= 55) Then EnrollStudentAtSemipublicSchool Else EnrollStudentAtPrivateSchool End If

N u h c sinh ñ u v i s ñi m trên 75 thì cho h c trư ng công, N U t 55 ñi m ñ n 75 ñi m thì cho h c trư ng bán công, n u không (t c là ñi m ñ u dư i 55) thì ph i h c trư ng tư. N u t nh nh , không có trư ng tư, ta không có quy t ñ nh cho h c trò ñ u dư i 55 ñi m h c ñâu thì b ph n ELSE trong thí d trên. Ph n chương trình tr thành:
If (StudentPassmark > 75) Then EnrollStudentAtPublicSchool ElseIf (StudentPassmark >= 55) Then EnrollStudentAtSemipublicSchool End If

Ta có th dùng ELSEIF nhi u l n như sau:

31

If (TheColorYouLike = vbRed) Then MsgBox "You 're a lucky person" ElseIf (TheColorYouLike = vbGreen) Then MsgBox "You 're a hopeful person" ElseIf (TheColorYouLike = vbBlue) Then MsgBox "You 're a brave person" ElseIf (TheColorYouLike = vbMagenta) Then MsgBox "You 're a sad person" Else MsgBox "You 're an average person" End If

Execution ñi l n lư t t trên xu ng dư i, n u m t ñi u ki n IF là TRUE thì x lý ph n c a nó r i nh y xu ng ngay dư i dòng END IF. Ch khi m t ñi u ki n IF không ñư c th a mãn ta m i th m t ñi u ki n IF bên dư i k ñó. T c là n u b n thích màu ñ l u màu tím (magenta) thì chương trình s display "You're a lucky person", và không h bi t "You're a sad person".

Dùng SELECT CASE statement
Thí d có nhi u ELSEIF như trên có th ñư c vi t l i như sau:
Select Case TheColorYouLike Case vbRed MsgBox "You 're a lucky person" Case vbGreen MsgBox "You 're a hopeful person" Case vbBlue MsgBox "You 're a brave person" Case vbMagenta MsgBox "You 're a sad person" Else MsgBox "You 're an average person" End Select

Cách vi t n y tương ñ i d ñ c và ít nh m l n khi vi t code hơn là dùng nhi u ELSEIF. Ph n ELSE trong Select Case statement thì optional (nhi m ý), t c là có cũng ñư c, không có cũng không sao. H khi ñi u ki n c a m t Case ñư c tho mãn thì nh ng dòng code t ñó cho ñ n dòng Case k dư i hay Else ñư c x lý và ti p theo execution s nh y xu ng dòng n m ngay dư i dòng End Select. Nh là dư i cùng ta vi t End Select, ch không ph i End If. Các Expression dùng cho m i trư ng h p Case không nh t thi t ph i ñơn gi n như v y. ð bi t thêm chi ti t v cách dùng Select Case, b n highlight ch Case (doubleclick ch Case) r i b m nút F1.

Dùng FOR statement
Trong l p trình, nói v Flow Control (ñi u khi n hư ng ñi c a execution) ta dùng hai lo i statement chính: Branch statements như IF..THEN..ELSE (k c Select Case) và Iterative statements (l p ñi, l p l i) như FOR và WHILE LOOP (Vòng). Ta s nói ñ n WHILE Loop trong ph n k ti p. Trong khi Branch statement cho phép ta execute trong nhánh n y hay nhánh kia tùy theo value c a Logical Expression thì Iterative statement cho ta execute m t ph n code l p ñi, l p l i nhi u l n cho ñ n khi m t ñi u ki n ñư c th a mãn. Gi d ta vi t m t chương trình ñơn gi n ñ tính t ng s các con s gi a b t c hai con s nào (coi ch ng l n quá). Cái form c a chương trình gi ng như dư i ñây:

32

Sau khi cho hai con s From (T ) và To (Cho ñ n) ta click nút Calculate và th y k t qu hi n ra trong Textbox txtTotal. Cái Sub tính t ng s ñư c li t ra dư i ñây:
Private Sub CmdTotal_Click() Dim i, FromNo, ToNo, Total FromNo = CInt(txtFromNumber.Text) ' Convert Text string ra internal number b?ng Function CInt ToNo = CInt(txtToNumber.Text) ' Convert Text string ra internal number b?ng Function CInt Total = 0 ' Initialise Total value to zero For i = FromNo To ToNo ' Iterate from FromNo to ToNo Total = Total + i ' Add the number to the Total Next txtTotal.Text = CStr(Total) ' Convert internal number ra Text string End Sub

Trong thí d trên, FOR loop b t ñ u t dòng For i = FromNo To ToNo và ch m d t dòng Next. Khi execution b t ñ u Total b ng 0, i b ng FromNo. Execution s ñi qua h t nh ng dòng trong FOR loop r i value c a i s ñư c tăng lên 1, r i execution s b t ñ u l i ñ u loop. Trong thí d n y vì FromNo=4 và ToNo=6 nên execution s ñi qua cái FOR loop 3 l n. L n th nh t i=4, l n th nhì i=5 ,và l n th ba thì i=6. Sau ñó, khi i=7 thì nó l n hơn ToNo (=6) nên execution nh y ra kh i FOR loop. K t qu là Total=15 và ñư c display trong Textbox txtTotal, sau khi ñư c converted t internal number ra text string v i Function CStr. N u ta ch mu n c ng nh ng s ch n t 4 ñ n 16 ta có th làm cho i tăng value lên 2 (thay vì 1) m i khi ñ n cu i loop. T c là i=4,6,8 .v.v..Ta s thêm ch STEP trong FOR statement như sau:
For i = 4 To 16 Step 2 ' Iterate from 4 to 16 with Step=2 Total = Total + i ' Add the number to the Total Next

Total s b ng 4+6+8+10+12+14+16= 70. Trong thí d trên ta cũng có th dùng STEP s âm như sau:
For i = 16 To 4 Step -2 ' Iterate from 16 to 4 with Step=-2 Total = Total + i ' Add the number to the Total Next

Trong trư ng h p n y FOR loop b t ñ u v i i=16. Khi ñ n cu i loop l n th nh t value c a i b b t 2 và tr thành 14. Sau ñó i b gi m giá tr d n d n ñ n 4. K ñó i=2 thì nh hơn s cu i cùng (=4) nên execution nh y ra kh i FOR loop. Gi d ta mu n l y ra t t c nh ng blank space trong m t text string. Ta bi t con s characters trong m t text string, còn g i là chi u dài c a text string có th tính b ng cách dùng Function Len(TString). Và ñ nói ñ n character th i trong m t Text string ta dùng Mid Function.

33

Khi User click button Remove Blank Spaces chương trình s execute Sub dư i ñây:
Private Sub CmdRemoveBlankSpaces_Click() Dim i, TLen, TMess TMess = "" ' Initialise temporary String to null string For i = 1 To Len(txtOriginalString.Text) ' Iterate from the first chracter to the last character of the string ' Check if chracter is NOT a blank space If Mid(txtOriginalString.Text, i, 1) <> " " Then ' Character is not a blank space - so append it to TMess TMess = TMess & Mid(txtOriginalString.Text, i, 1) End If Next txtResultString.Text = TMess ' Disaplay TMess by assigning it to txtResultString.text End Sub

Thông thư ng, ta dùng FOR loop khi bi t trư c execution s ñi qua loop m t s l n nh t ñ nh. Nhưng th nh tho ng, khi m t ñi u ki n ñư c th a mãn ta có th ép execution nh y ra gi a ch ng kh i FOR loop, ch không ñ i cho ñ n ñ s l n ñi qua loop. Thí d như ta mu n bi t ph i c ng bao nhiêu s k ti p t 1 tr lên ñ ñư c t ng s v a l n hơn hay b ng 76.

Khi User click button Work Out, Sub dư i ñây s ñư c x lý:
Private Sub cmdWorkOut_Click() Dim i, Total, WantedTotal WantedTotal = CInt(txtWantedTotal.Text) ' Convert Text string ra internal number b?ng Function CInt Total = 0 ' Initialise Total value to zero For i = 1 To 30

34

Total = Total + i ' Add the number to the Total If Total >= WantedTotal Then Exit For ' Jump out of FOR loop Next txtActualTotal.Text = CStr(Total) ' Display the Actual Total txtUptoNumber.Text = CStr(i) ' Display the highest number End Sub

Dùng DO WHILE Loop statement
Khi ta không bi t ch c là execution s ñi qua loop bao nhiêu l n thì t t nh t là dùng DO WHILE Loop statement. Khàc v i FOR Loop, trong DO WHILE Loop ta ph i t lo initialisation (t c là m i vô ñ u i b ng bao nhiêu) và t lo tăng value c a parameter i. N u Logical Expression là True thì execute nh ng dòng code t DO WHILE cho ñ n Loop. Thí d m i v a qua có th vi t l i b ng cách dùng DO WHILE Loop như sau:
Private Sub cmdWorkOut_Click() Dim i, Total WantedTotal = CInt(txtWantedTotal.Text) ' Convert Text string ra internal number b?ng Function CInt Total = 0 ' Initialise Total value to zero i = 1 ' Intialise at the first character Do While (Total < WantedTotal) ' Logical Expression is (Total < WantedTotal) Total = Total + i ' Add the number to the Total i = i + 1 ' Increment the vakue of i Loop txtActualtotal.Text = CStr(Total) ' Display the Actual Total txtUptonumber.Text = CStr(i - 1) ' Display the highest number End Sub

TRong khi Total hãy còn nh hơn WantedTotal thì ta ti p t c ñi qua While Loop. Gi d ta có các hàng text ch a giá ti n các th có th b vào bánh mì th t v i giá như sau:
Chicken Roll Roast Beef Tomato Sauce 45c 55c 5c

Bây gi ta mu n vi t code ñ l y ra giá ti n t nh ng hàng Text string như trên. Ta s ñi t bên ph i l n l n qua trái cho ñ n khi tìm ñư c m t blank space.
Private Sub WorkOutPrice_Click() Dim i, TStr, PriceInCents, Price TStr = "Chicken Roll 45c" i = Len(TStr) ' Starting from the rightmost character of the text string ' Going from right to left, look for the first blank character Do While (Mid(TStr, i, 1) <> " ") i = i - 1 ' Keep walking to the left Loop PriceInCents = Mid(TStr, i + 1) ' String including character "c" ' Discard the rightmost character which is "c" and convert the price string to single number Price = CSng(Left(PriceInCents, Len(PriceInCents) - 1)) txtPrice.Text = CStr(Price) ' Display the highest number

35

End Sub

Dùng Function
Function là m t d ng subroutine gi ng gi ng như Sub. Ch khác ch Function cho ta m t k t qu , cho nên cách dùng Function hơi khác v i Sub. Ta vi t m t variable bên trái d u =, ñư c assigned k t qu c a m t Function. Thí d như ta dùng Trim Function ñ lo i b nh ng blank space hai ñ u c a text string TString:
ResultString = Trim(TString)

Ta ñưa cho Function Trim m t text string called TString. Sau khi Function Trim ñư c executed, ta có k t qu nhưng TString không h thay ñ i. Ngư c l i, khi ta g i m t Sub, t t c nh ng parameter ta ñưa cho Sub ñ u có th thay ñ i tr khi ta tuyên b m t parameter nào ñó là ByVal. Trong thí d sau, m t copy c a StringA ñư c ñưa cho Sub nên sau khi execute ProcessString, StringA không h b thay ñ i.
Sub ProcessString (ByVal StringA, ConditionA, ConditionB)

Public Sub và Function
Khi ta dùng ch Public (thay vì Private) phía trư c m t Sub hay Function, ta cho phép code n m m t Form hay Basic Module khác có th g i (hay dùng) Sub hay Function ñó. Thí d trong Form2 ta có ñ nh nghĩa DisplayData là:
Public Sub DisplayData .... End Sub

Trong Form1, ta g i DisplayDta như sau:
Form2.DisplayData

Chương Ba - Form và các Controls thông thư ng

H u h t các chương trình VB6 ñ u có ít nh t m t Form. Khi ta ch y chương trình, Form n y s

hi n ra trư c h t ñ ta ra l nh nó làm chuy n gì. Cái Form tr ng không ch làm ñư c gì nhi u, nên ta ñ t lên Form nh ng controls như Textbox(h p ñ ñánh ch vào), Label(nhãn), Commandbutton(nút b m m nh l nh), .v.v.. Các controls cho ta enter các d ki n ñ chương trình dùng x lý, và các controls cũng hi n th (display) k t qu cho chúng ta xem.

S p ñ t controls lên Form
Ta hãy b t ñ u thi t k m t chương trình m i (New Project) b ng cách ch n Standard EXE, môi trư ng tri n khai l p trình (IDE) cho b n s n m t Form tên là Form1. Mu n ñ t m t Control lên Form, click hình cái Control trong Toolbox r i Drag (b m nút trái c a con chu t r i kéo cho thành hình ch nh t trư c khi buông nút trái ra) con chu t trên Form v thành c c a Control. M t cách khác ñ ñ t m t control lên Form là doubleclick cái Control trong Toolbox, m t hình control s hi n ra trên Form. K ñó b n d i control ñi ñ n ch mình mu n và resize nó. N u b t c lúc nào b n không th y Túi ñ ngh (Toolbox) n m bên trái, b n có th dùng m nh l nh Menu View|Toolbox ñ b t nó hi n ra. Có m t cách khác là click lên toolbox icon trên toolbar chính c a VB6.

36

Nên nh r ng Toolbox cũng là m t window như các window khác. Khi nó hi n lên r i b n có th n m (b m nút trái c a con chu t và gi như v y ch không buông ra) title nó ñ d i ñi nơi khác. B n có th ñóng nó b ng cách click lên d u x góc ph i phía trên. N u right click trên Toolbox, nó s display context sensitive menu, trong ñó có property dockable (có th ñ u b n) . N u m t window là dockable, sau khi b n d i nó ñi kh i vi trí docked bình thư ng c a nó, b n có th dock nó l i như c b ng cách double click lên title c a nó.

Resize và di chuy n control
Khi b n select m t control (click lên nó), chung quanh control s hi n ra resize handle, 8 nút ñen d c theo chu vi c a control.

Click lên các nút ñen c a resize handle, b n có th resize control. Có m t cách khác ñ resize control là dùng Shift + ArrowKey. B m nút Shift trong khi b m m t arrow key, control s l n ra hay thu h p theo chi u c a ArrowKey. Lưu ý: M t s control có kích thư c t i thi u, b n không th làm cho nó nh hơn ñư c. Thí d như Combobox, nó ph i cao ñ ñ display m t hàng text. Tương t như th , b m nút Ctrl trong khi b m m t arrow key, control s di chuy n theo chi u c a ArrowKey. Ngoài ra, nên nh r ng trong lúc chương trình ch y (at run-time), trong code ta có th thay ñ i kích thư c và v trí các controls d dàng, th m chí có th làm cho chúng hi n ra hay bi n m t b ng cách s a ñ i value các property left, top, width, height và visible c a các controls.

Alignment Grid
ð giúp b n s p ñ t ngay ng n các controls trên m t form, VB6 cho b n Alignment Grid. Nó là nh ng d u ñen c a các hàng d c và xuôi trên form. B n có th làm cho các d u ñen c a grid trên form bi n m t b ng cách dùng menu command Tools | Options ñ display Option Dialog, k ñó ch n Tag General và clear checkbox "Show Grid":

37

B n cũng có th nhân d p n y thay ñ i kho ng cách chi u r ng (Width) và chi u cao (Height) c a các ch m ñen c a grid. Kích thư c nh nh t c a Width hay Height là 24. Hãy so sánh hai trư ng h p form có và không có Show Grid như dư i ñây:

Control Locking
M t khi b n ñã s p ñ t kích thư c và v trí c a các control trên form r i, r t d ta tình c thay ñ i các ñ c tính y vì vô ý click lên m t control. Do ñó VB6 cho ta Menu command Format | Lock Controls ñ khóa chúng l i. Sau khi khóa, cái hình ng khóa trên menu b chìm xu ng.

38

N u sau n y b n mu n thay ñ i kích thư c ho c v trí c a chúng thì nh dùng Menu command Format | Lock Controls l i. Sau khi m khóa, cái hình ng khóa trên menu hi n ra bình thư ng.

Cài ñ t các Properties c a Form
Nhi u property c a m t form nh hư ng ñ n di n m o v t lý (physical appearance) c a nó. Property Caption s quy t ñ nh text ñư c hi u th trong title. N u Property BorderStyle c a form không ph i là Sizable thì User không th resize form at run-time. Property Icon quy t ñ nh hình icon ñu c dùng trong title c a form, nh t là khi form thu nh (minimized). N u b n không mu n cho phép User minimize hay maximize form thì set value c a property MinButton, MaxButton ra False. N u property ControlBox là False thì form s không có nút minize, maximize hay close (x) trên góc ph i c a nó, ñ ng th i form cũng không display c icon bên góc trái title như trong hình dư i ñây:

V trí ñ u tiên (top,left) c a form có th ñư c thay ñ i trong design time b ng cách di chuy n hình nh c a nó trong window Form Layout:

Property WindowState xác ñ nh Form s có kích thư c bình thư ng (normal=0), hay minimized (=1), maximized =(2). Lưu ý là property Font c a Form s ñư c các control n m trên nó th a k . T c là khi b n ñ t m t control lên form, property Font c a control y s t ñ ng tr nên gi ng y như c a form.

Vài Event thông d ng c a Form
Nhìn t m t phương di n, Form cũng gi ng như Control. Ta có th instantiate m t form nhi u l n ñ có nhi u form tương t nhau. Trong thí d dư i ñây, ta instantiate Form2 hai l n ñ có MyForm và YourForm:
Private Sub CmdCreateForms_Click() Dim MyForm, YourForm Set MyForm = New Form2 MyForm.Caption = "This is My Form" MyForm.Show

39

MyForm.Move 1000, 1000 Set YourForm = New Form2 YourForm.Caption = "YOUR FORM IS HERE" YourForm.Show YourForm.Move 2000, 2000 End Sub

M t Form cũng có nhi u Events r t h u d ng.

F orm_Initialize: Event n y xãy ra trư c nh t và ch m t l n thôi khi ta instantiate form ñ u tiên. Ta dùng Form_Initialize event ñ th c hi n nh ng gì c n ph i làm chung cho t t c các instances c a form n y.

F orm_Load: Event n y xãy ra m i l n ta instantiate m t form. N u ta ch dùng m t instance duy nh t c a m t form trong chương trình thì Form_Load coi như tương ñương v i Form_Initialize. Ta dùng Form_Load event ñ initialise variables, controls v.v. cho instance n y. Bên trong Form_Load b n không th dùng Setfocus cho m t control nào trên form vì form chưa h n thành hình (ra ñ i). Mu n làm vi c y b n ph i delay (trì ho n) m t chút xíu b ng cách dùng Control Timer ñ ñ i cho Form_Load ñư c hoàn t t. Thí d :

Private Sub Form_Load() Timer1.Interval = 500 Timer1.Enabled = True End Sub Private Sub Timer1_Timer() Timer1.Enabled = False ' Timer1_Timer only execute once txtName.Setfocus ' Make Tab Cursor start at TextBox txtName End Sub

F orm_Activate: M i l n m t form tr nên active (current) thì nó generate m t Activate event. Ta có th dùng event n y ñ refresh display trên form.

F orm_QueryUnload: Khi User click d u x phía trên bên ph i ñ close form thì nó generate QueryUnload event. Syntax c a Sub n y như dư i ñây:

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer) End Sub

Event n y cho ta m t d p ñ cancel Close action c a form (t c là không cho User close form) b ng cách set Cancel b ng 1. UnloadMode cho ta bi t ai, task hay form nào mu n close form n y. Ngoài ra, b n cũng nên bi t r ng m t form t ñ ng Load hay tr nên active n u b n nh c ñ n nó, thí d như dùng Form2.List1. Khi m t form ñã ñư c loaded r i b n có th hide (làm cho bi n m t) nó.

40

K ñó, khi b n show form ra tr l i thì form không có gì thay ñ i. Nhưng n u b n Unload m t form (thí d b ng cách dùng Unload Form2 ), r i sau ñó load tr l i b ng cách dùng Form2.Show ch ng h n, thì Form ph i tr i qua quá trình Form_Load, và dĩ nhiên form m t t t c nh ng gì có trư c ñây. Ngoài ra, Hide/Show m t form ñã ñư c loaded r i thì r t nhanh, còn Unload/Load thì m t thì gi hơn. Khi b n Show m t Form chưa hi n h u thì form s ñư c loaded và show. ðôi khi b n mu n Load m t form, r i làm vi c v i nó trư c khi Show, trong trư ng h p ñó b n dùng Load Form2 r i m t ch p sau dùng Form2.Show.

MDI Form
ðôi khi b n mu n có m t MDI form, t c là m t form có th ch a nhi u form con bên trong. D ng MDIform n y thư ng ñư c dùng trong các application như wordprocessor ñ có th m nhi u document cùng m t lúc, m i document ñư c hi n th trong m t form con. ð có m t MDIForm b n c n ph i dùng menu command Project | Add MDI Form. M i VB6 project ch có th có t i ña m t MDIform. Mu n m t form tr thành m t form con b n set property MDI Child c a nó thành True. At run-time b n không th hide (bi n nó thành invisible) m t MDIChild form, nhưng có th minimize nó. N u b n th t s mu n hide nó thì ph i dùng mánh l i là cho nó v trí (top,left) s âm l n hơn kích thư c nó ñ nó n m ngoài t m hi n th c a form. Trong m t chương trình dùng MDI Form, khi b n click MDI Form nó không nh y ra phía trư c và che các form con, nhưng v n luôn luôn n m dư i.

Controls là gì?
Controls v a có hình, v a có code ch y bên trong m t window nho nh , gi ng như m t form. Khi ta l p trình VB6 ta l p ráp các controls (là nh ng v t d ng ti n ch ) trên m t hay nhi u form ñ có m t chương trình nhanh chóng. Ta giao d ch v i m t control qua ba ñ c tính c a control:

P roperties: t p h p các ñ c tính c a control mà ta có th n ñ nh lúc design time hay run-time. Có nhi u properties v di n m o, n u ta thay ñ i at design time s th y k t qu hi n ra l p t c, thí d Font hay màu s c.

M ethods: nh ng gì control th c hi n ñu c, t c là nh ng kh năng c a nó. E vents: nh ng s c mà control s thông báo cho chúng ta bi t khi nó xãy ra v i control. Khi m t event xãy ra VB6 s x lý m t Event Handler (thí d như Sub Command1_Click()), mi n là chúng ta vi t code s n trong ñó. N u không có code thì coi như chúng ta không thèm bi t ñ n các event lo i ñó. Có m t s Events mà chúng ta thư ng x lý là:

o

C lick : xãy ra khi user click lên control. Ta thư ng dùng nó cho CommandButton và Listbox. M ouseDown, MouseUp : m i khi User b m m t mouse button là có m t MouseDown Event, khi User buông nó ra thì có m t MouseUp Event. Ta thư ng dùng MouseDown Event ñ Popup context sensitive menu hay b t ñ u m t di n bi n Drag. Thí d :

o

Private Sub Foods_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single) If Button = vbRightButton Then ' if Right button was pressed PopupMenu mnuActions ' popup a menu End If

41

End Sub Private Sub DrinkList_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single) DrinkList.drag ' Displaying a drag icon to start the drag process End Sub

ð ý là Click không cho chúng ta thêm chi ti t gì v s c , trong khi MouseDown/MouseUp cho ta bi t v trí c a cursor, button nào c a Mouse ñư c b m và lúc y User có b m nút Shift, Ctrl hay Alt không. M i Click là ñi ñôi v i m t c p MouseDown/MouseUp. N u b n mu n x lý v a Click l n MouseDown thì ph i c n th n. Thí d b n mu n v a handle Click event v a handle Mouse Drag thì ph i làm sao phân bi t hai trư ng h p. N u không User ch mu n th y k t qu c a Click mà l i th y control b t ñ u display m t Drag icon thì s b c mình.
o

K eyPress : xãy ra khi user Press m t key. Ta thư ng dùng nó cho TextBox ñ lo i ra (filter out) các keystrokes ta không ch p nh n. KeyPress cho ta ASCII value, m t con s có giá tr t 1 ñ n 255, c a key. Trong thí d dư i ñây, m t Enter key s ñư c coi như m t TAB key:
Private Sub Text1_KeyPress(KeyAscii As Integer) If KeyAscii = 13 Then KeyAscii = 0 ' Swallow the character to avoid side effect SendKeys "{TAB}" ' Emulate entering a TAB End If End Sub

o

K eyDown, KeyUp : m i KeyPress event là cho ta m t c p KeyDown/KeyUp event. KeyDown/KeyUp cho ta KeyCode và Shift value. ð detect Function key ta c n dùng KeyDown event. Trong thí d dư i ñây, ta display Function key User b m:
Private Sub Text3_KeyDown(KeyCode As Integer, Shift As Integer) If (KeyCode >= 112) And (KeyCode <= 123) Then MsgBox "You pressed the Function key: F" & Trim(Str(KeyCode - 111)) End If End Sub

o

G LotFocus : Control tr nên active khi nó nh n ñư c Focus. Nó s generate m t GotFocus Event. Ta có th dùng nó ñ ñ i màu background c a m t text box như trong thí d dư i ñây:
Private Sub Text2_GotFocus() Text2.BackColor = vbYellow End Sub

42

o

L LostFocus : Thư ng thư ng h m t Control GotFocus thì trư c ñó có m t Control LostFocus. Ta có th dùng Event n y ñ Validate entry data hay thu x p công chuy n cho m t control v a m t Focus. Trong thí d dư i ñây, n u User không ñánh vào m t con s trong Textbox Text1 thì s ñư c thông báo và Tab Cursor s tr l i Textbox Text1.
Private Sub Text1_LostFocus() If Not IsNumeric(Text1.Text) Then MsgBox "Please enter a number!" Text1.SetFocus End If End Sub

o

r DagDrop : xãy ra khi ta drop m t cái gì lên control . Parameter Source cho ta bi t Control nào ñã ñư c Drag và Drop. Nhi u khi m t control có th nh n drop t nhi u control khác nhau. Trong trư ng h p ñó ta ph i test xem ho c Control Type, ho c Name ho c Tag value c a Source control là gì ñ tùy nghi x lý. Trong thí d dư i ñây, khi User drop mouse xu ng Textbox Text2, n u Source là m t Listbox, không c n bi t Listbox nào, thì ta copy dòng ñư c ch n trong Listbox y qua Textbox Text2.
Private Sub Text2_DragDrop(Source As Control, X As Single, Y As Single) If TypeOf Source Is ListBox Then Text2.Text = Source.Text End If End Sub

TextBox
TextBox là control ñu c dùng nhi u nh t ñ display text và nh n keystroke c a Userñ s a ñ i text có s n hay cho vào text m i. Property chính và default c a Textbox là text, t c là thư ng thư ng Text2.text có th ñư c vi t t t là Text2. Ta có th disable (khi n nó b t l c, không ph n ng gì h t và không cho s a ñ i) m t text box b ng cách set Property Enable ra False (ch s b m ñi), hay Lock (không cho s a ñ i) m t text box b ng cách set Property Locked ra True (ch không b m ). Text có th ñư c Align (Alignment Property) ñ display bên trái, chính gi a hay bên ph i c a h p nó.

B n có th ch n BackColor và ForeColor cho background và text c a TextBox. Dùng Tag Palette khi ch n màu ñ có ñúng m t màu b n mu n.

43

Dĩ nhiên b n có th l a ch n Font và c ch cho Text v i Font Property. B n gi i h n s characters mà User có th enter cho TextBox b ng cách set MaxLength Property. N u Property Multiline là True thì User có th enter nhi u hàng. At Design time, n u b n mu n enter multiline thì ph i nh b m nút Ctrl khi press Enter m i khi xu ng hàng. N u không VB6 IDE tư ng r ng b n ñã k t thúc editing.

Mu n assign cho text box multiline text thì ph i nhét vào m i cu i hàng CarriageReturn và LineFeed characters. Thí d như:
Private Sub Command1_Click() Dim TextStr TextStr = "Bau ra bau lay ong cau" & vbCrLf ' Note: vbCrLf = chr(13) & chr(10) TextStr = TextStr & "Bau cau ca bong ngat dau kho tieu" Text1.Text = TextStr End Sub

N u b n mu n mách nư c cho User v cách dùng m t textbox nào ñó thì có th dùng Property ToolTipText ñ nó display mách nư c m i khi mouse cursor n m lên textbox.

44

Dùng Property TabIndex ñ n ñ nh th t cho Tab Cursor d ng m i khi User b m nút TAB ñ d i TAB Cursor ñ n Textbox k ti p. N u b n không mu n Tab Cursor d ng m t TextBox nào thì set Property TabStop nó thành False. Tab Cursor không d ng Textbox có Property Enabled b ng False, nhưng v n d ng Textbox có property Locked b ng True. N u b n mu n dùng Textbox làm m t Password field thì set Property PasswordChar b ng "*". Làm như th s ép bu c Textbox display m i character b ng PasswordChar, t c là "*", ñ ngư i khác không ñ c ñư c trong khi User enter m t Paswword.

Properties SelLength, SelStart và SelText N u b n mu n bi t ñư c tình hình hi n th i c a Textbox: SelText cho b n dãy ch ñang ñư c selected. SelStart cho b n v trí c a insertion point (ch cursor flashing). SelLength cho bi t con s characters ñã ñư c selected. N u b n mu n s a ñ i text trong Textbox: SelText cho b n nhét vào m t dãy ch . SelStart cho b n n ñ nh v trí b t ñ u c a dãy ch b n s p select. SelLength n ñ nh s characters b n mu n ch n, b t ñ u t SelStart. Dư i ñây là m t thí d trong ñó ta highlight text tìm ñư c:
Private Sub Form_Click () Dim Search, Where ' Declare variables. ' Get search string from user. Search = InputBox("Enter text to be found:") Where = InStr(Text1.Text, Search) ' Find the given string in Text1.Text. If Where > 0 Then ' If found, Text1.SelStart = Where - 1 ' set selection start and Text1.SelLength = Len(Search) ' set selection length. Else MsgBox "String not found." ' Notify user. End If End Sub

CommandButton
CommandButton r t ti n cho ta dùng vào vi c x lý m t chuy n gì khi User click lên button. Event ta dùng thư ng nh t cho CommanButton là Click. Ta dùng Property Caption c a CommandButton ñ enter cái gì ta mu n display trên button. N u mu n cho phép User dùng ALT+E (ñè nút Atl trong lúc b m nút E) ñ generate event click thì nhét d u "&" trư c ch E trong Caption c a button. Caption s display ch E v i m t g ch dư i. Ngoài ra ta cũng có th cho thêm m t cái hình vào CommandButton b ng cách ch n m t icon cho property Picture và set Property Style ra Graphical, thay vì Standard.

45

Lúc Run-time b n có th thay ñ i hình hay Caption c a CommandButton. Trong thí d dư i ñây, Caption c a CommandButton CmdOperation flip-flop gi a hai values Stop và Start:
Private Sub CmdOperation_Click() If CmdOperation.Caption = "&Stop" Then CmdOperation.Caption = "St&art" Else CmdOperation.Caption = "&Stop" End If End Sub

Label
M c ñích chính c a Label là ñ display, không cho User Edit như Textbox. Do ñó ta có th dùng Property Font, ForeColor và Backcolor ñ làm cho nó ñ p. Ngoài ra Property BorderStyle có th cho Label l m xu ng n u b n set nó b ng Fixed Single. N u set property BackStyle b ng Transparent s tránh trư ng h p Backcolor c a Label làm cho không ñ p. Label cũng có Property Tabindex. N u b n mu n dùng ALT key ñ mang Tab Cursor v m t Textbox, hãy ñ m t Label v i TabIndex b ng TabIndex c a TextBox tr 1. Gi s Label có Caption là "&Address" thì ALT+A s mang Tab Cursor v TextBox màu vàng như trong thí d dư i ñây:

Ngoài ra nh r ng b n có th thay ñ i Caption c a Label lúc run-time.

CheckBox
CheckBox ñư c dùng ñ User xác nh n có ñ c tính nào m t cách nhanh chóng. Property Value c a CheckBox có th là Checked (làm cho h p vuông có d u, b ng 1), Unchecked (làm cho h p vuông tr ng không, b ng 0) hay Grayed (làm cho h p vuông có d u màu nh t, b ng 2). M t khi bi t r ng CheckBox có Value b ng 1, ta có th ñ c Caption c a CheckBox ñ dùng n u c n.

46

B n có th dùng Property Alignment ñ làm cho Caption ñ ng bên ph i (Left Justify) hay bên trái (Right Justify) c a h p vuông.

OptionButton
OptionButton ( còn g i là RadioButton) có hình tròn v i m t ch m gi a, thay gì hình vuông v i m t g ch gi a như CheckBox. OptionButton luôn luôn ñư c qui t thành m t nhóm, ch a trong m t container. Container là m t Control có kh năng ch a các controls khác. Frame, PictureBox, hay chính Form ñ u là Container. Sau khi ñ t m t Container lên Form, n u mu n ñ m t OptionButton lên Container, trư c h t ta ph i Select container, r i k ñó ch n OptionButton. S dĩ, t t c OptionButtons ph i n m trong m t container là vì b t c lúc nào, nhi u nh t là m t OptionButton trong container có value True (vòng tròn có ch m gi a). Mu n bi t m t OptionButton có th t s n m trong m t container, b n th kéo cái container ñi ch khác. N u OptionButton b d i theo container thì nó n m trong container. M t cách khác là th kéo OptionButton ra kh i container. N u kéo ra ñư c thì nó không n m trong container. Mu n di chuy n m t OptionButton t container n y sang container khác, b n Cut OptionButton r i Paste nó vô container kia.

ðôi khi m t container n m che trên m t control khác. Mu n mang m t container ra phía sau các controls khác b n Select container r i dùng Menu command Format | Order | Send to Back.

47

Chương B n - Vi t Code

Trong ba chương ñ u chúng ta ñã h c qua ba b
ðó là:
• • •

ph n chánh c a m t chương trình Visual Basic 6.0.

Forms là cái n n hay khung ñ ta xây d ng User Interface. Controls là nh ng viên g ch ñ ta dùng xây d ng User Interface. Event procedures là code n m phía sau nh ng hình nh, nó là ch t keo dùng ñ dán các Controls l i v i nhau ñ t o thành chương trình áp d ng c a ta.

Như ta ñã th y, t t c các code ñư c x lý (executed) khi có m t Event xãy ra. Thí d như khi User click m t CommandButton (Event Click) hay type nút Tab ñ di chuy n Cursor t Textbox n y (Event Lostfocus) qua Textbox khác (Event GotFocus). Các nhóm code x lý là :
Private Sub Command1_Click() ... End Sub Private Sub Text1_LostFocus() ... End Sub và Private Sub Text2_GotFocus() ... End Sub

Trong khi l p trình, m i l n ta double click lên m t Control c a m t Form là VB6 IDE t ñ ng generate cho ta cái v t hàng Private Sub Control_Event() cho ñ n End Sub ñ chúng ta ñi n nh ng hàng code c a mình vào chính gi a.

ði u khi n th

t x lý các dòng code

Gi d ta vi t m t chương trình Vb6 ñơn gi n như trong hình n y v i hai Textbox tên txtName, txtAge và m t nút tên CmdEnter n m trong m t form tên Form1:

48

Thông thư ng các dòng code ñư c x lý theo th t t trên xu ng dư i. Thí d như ñ ki m xem các d ki n v a ñư c cho vào các Textbox có tương ñ i h p lý hay không, khi User click nút CmdEnter, ta x lý Sub dư i ñây:
Private Sub CmdEnter_Click() ' Make sure the Name field is not blank If txtName.Text = "" Then MsgBox "Please enter Name" Exit Sub ' Terminate this Sub End If ' Make sure a number is supplied for Age If Not IsNumeric(txtAge.Text) Then MsgBox "Please enter a number for Age" Exit Sub ' Terminate this Sub End If End Sub

Cái Sub nói trên có ch Private n m phía trư c, ý nói ch n i trong cùng m t form ch a Control CmdEnter (t c là Form1 trong trư ng h p n y) ta m i có th g i (dùng) Sub CmdEnter_Click(). Thí d ta mu n khi User b m key "Enter" trên bàn phím sau khi cho vào chi ti t Textbox txtAge thì coi như User ñã click nút CmdEnter. Ta vi t như sau:
Private Sub txtAge_KeyPress(KeyAscii As Integer) If KeyAscii = 13 Then KeyAscii = 0 ' swallow Key Enter to avoid side effect CmdEnter_Click ' Call Private Sub CmdEnter_Click from the same form End If End Sub

Khi ta dùng câu CmdEnter_Click làm m t dòng code (còn g i là g i Sub CmdEnter_Click) thì coi như tương ñương v i nhét t t c 10 dòng codes gi a hai hàng Private Sub CmdEnter_Click() và End Sub t i ch câu CmdEnter_Click, như vi t l i dư i ñây:
Private Sub txtAge_KeyPress(KeyAscii As Integer) If KeyAscii = 13 Then KeyAscii = 0 ' Swallow Key Enter to avoid side effect ' Make sure the Name field is not blank If txtName.Text = "" Then MsgBox "Please enter Name" Exit Sub ' Terminate this Sub End If ' Make sure a number is supplied for Age

49

If Not IsNumeric(txtAge.Text) Then MsgBox "Please enter a number for Age" Exit Sub ' Terminate this Sub End If End If End Sub

Có m t cách nói khác là khi execution ñi ñ n hàng CmdEnter_Click thì nó nh y vào Private Sub CmdEnter_Click() ñ execute cho ñ n h t r i nh y tr l i hàng k ti p trong Private Sub txtAge_KeyPress(KeyAscii As Integer) Trong Private Sub CmdEnter_Click() n u User không ñánh gì vào Textbox txtName thì chương trình s display message "Please enter Name" r i Exit Sub. ðây là cách nh y ngay ra kh i Sub ch không ñ i ph i execute xu ng t i hàng chót.

Dùng IF....THEN statement
Trong Private Sub CmdEnter_Click() trên ta th y có hai ch dùng IF...THEN ñ th xem m t ñi u ki n gì có ñư c th a mãn không. N u ñi u ki n là ñúng v y, t c là True thì ta th c hi n nh ng gì ñu c vi t t hàng IF...THEN cho ñ n hàng END IF. Ngư c l i, n u ñi u ki n không ñúng thì execution nh y xu ng t i dòng code n m ngay dư i dòng END IF. T c là có khi execution s ñi ngang qua, có khi không ñi ngang qua nh ng dòng code gi a câu IF...THEN và câu END IF. ði u ki n trong IF Statement là ph n n m gi a hai ch IF và THEN. Nó ñu c g i là Logical Expression. Ta có:
txtName.text = "" ' content of Textbox txtName is nothing, i.e. an empty string và NOT IsNumeric(txtAge.text) ' content of TextBox txtAge is not a number

Trong Logical Expression th nhì ta dùng Function IsNumeric ñ ñư c cho bi t r ng txtAge.text có ph i là m t con s hay không. Vì ta ch than phi n khi txtAge không ph i là m t con s nên ta ph i ñ thêm ch NOT phía tru c. T c là khi
IsNumeric(txtAge.text) = False thì NOT IsNumeric(txtAge.text) = True

N u gi a IF...THEN và END IF ch có m t dòng code b n có th nh p dòng code lên v i IF...THEN và không dùng END IF. T c là:
If theColorYouLike = vbRed Then MsgBox "You 're a lucky person!" End If is equivalent with If theColorYouLike = vbRed Then MsgBox "You 're a lucky person!"

M t Logical Expression có th ñơn gi n (simple) như trong các thí d trên hay r c r i hơn n u ta ráp nhi u simple Logical Expression l i v i nhau b ng cách dùng nh ng t OR và AND. Khi hai Logical Expression ñư c ráp l i b ng ch OR (HAY) thì ch c n ít nh t m t trong hai Expression là TRUE là Logical Expression t ng h p cũng là TRUE. Cái TRUE Table cho OR như sau:
A B A OR B

FALSE FALSE FALSE FALSE TRUE TRUE

50

TRUE TRUE

FALSE TRUE TRUE TRUE

Trong thí d dư i ñây n u m t ngư i 25 tu i tr lên HAY có l i t c trên 30 ngàn ñô la m t năm thì cho mư n ti n ñư c :
If (PersonAge >= 25) Or (PersonIncome >= 30000) Then LendPersonMoney End If

ð ý cách dùng các d u ngo c ñơn gi ng như trong toán ñ i s . Thông thư ng h cái gì n m trong ngo c thì mình tính trư c. N u có nhi u l p d u ngo c thì tính theo th t t trong ra ngoài. Như trong bài trên ta tính xem PersonAge >= 25 xem là TRUE hay FALSE, r i tính xem PersonIncome >= 30000 xem là TRUE hay FALSE, trư c khi tính k t qu t ng h p, d a vào cái TRUE table cho OR. Khi hai Logical Expression ñư c ráp l i b ng ch AND (Và) thì ch khi nào c hai Expression ñ u là TRUE, Logical Expression t ng h p m i là TRUE. Cái TRUE Table cho AND như sau:
A B A AND B

FALSE FALSE FALSE FALSE TRUE TRUE TRUE FALSE

FALSE FALSE TRUE TRUE

Trong thí d dư i ñây n u h c sinh 18 tu i tr lên và cha m ki m 100 ngàn tr lên m t năm thì ñăng ký h c sinh m t ñ i h c tư:
If (StudentAge >= 18) And (ParentIncome >= 100000) Then EnrollStudentAtPrivateUniversity End If

M t Logical Expression có th t p h p c OR l n AND như trong thí d dư i ñây n u h c sinh 18 tu i tr lên và cha m ki m 100 ngàn tr lên m t năm HAY h c sinh có Intelligent Quotient cao hơn 160 thì ñăng ký h c sinh m t ñ i h c tư:
If ((StudentAge >= 18) And (ParentIncome >= 100000)) Or (StudentIQ > 160) Then EnrollStudentAtPrivateUniversity End If

Hai d u ngo c ñơn n m bên ngoài c a:
((StudentAge >= 18 ) And (ParentIncome >= 100000))

không c n thi t vì theo qui ư c, ta tính AND expression trư c khi tính OR expression, nhưng nó giúp ta ñ c d hơn.

Dùng IF....THEN..ELSE statement
Hãy xem thí d :
If (StudentPassmark > 75) Then ' Part A

51

EnrollStudentAtPublicSchool Else ' Part B EnrollStudentAtPrivateSchool End If

N u h c sinh ñ u v i s ñi m trên 75 thì cho h c trư ng công, N U KHÔNG thì ph i h c trư ng tư. T c là n u StudentPassmark > 75 là TRUE thì x lý ph n A, n u không thì x lý ph n B. ð ý ph n A g m nh ng dòng code n m gi a dòng If (StudentPassmark > 75) then và else. Còn ph n B g m nh ng dòng code n m gi a dòng else và end if. Ta có th ráp ch ELSE v i ch IF ñ dùng như trong thí d sau ñây: <
If (StudentPassmark > 75) Then EnrollStudentAtPublicSchool ElseIf (StudentPassmark >= 55) Then EnrollStudentAtSemipublicSchool Else EnrollStudentAtPrivateSchool End If

N u h c sinh ñ u v i s ñi m trên 75 thì cho h c trư ng công, N U t 55 ñi m ñ n 75 ñi m thì cho h c trư ng bán công, n u không (t c là ñi m ñ u dư i 55) thì ph i h c trư ng tư. N u t nh nh , không có trư ng tư, ta không có quy t ñ nh cho h c trò ñ u dư i 55 ñi m h c ñâu thì b ph n ELSE trong thí d trên. Ph n chương trình tr thành:
If (StudentPassmark > 75) Then EnrollStudentAtPublicSchool ElseIf (StudentPassmark >= 55) Then EnrollStudentAtSemipublicSchool End If

Ta có th dùng ELSEIF nhi u l n như sau:
If (TheColorYouLike = vbRed) Then MsgBox "You 're a lucky person" ElseIf (TheColorYouLike = vbGreen) Then MsgBox "You 're a hopeful person" ElseIf (TheColorYouLike = vbBlue) Then MsgBox "You 're a brave person" ElseIf (TheColorYouLike = vbMagenta) Then MsgBox "You 're a sad person" Else MsgBox "You 're an average person" End If

Execution ñi l n lư t t trên xu ng dư i, n u m t ñi u ki n IF là TRUE thì x lý ph n c a nó r i nh y xu ng ngay dư i dòng END IF. Ch khi m t ñi u ki n IF không ñư c th a mãn ta m i th m t ñi u ki n IF bên dư i k ñó. T c là n u b n thích màu ñ l u màu tím (magenta) thì chương trình s display "You're a lucky person", và không h bi t "You're a sad person".

52

Dùng SELECT CASE statement
Thí d có nhi u ELSEIF như trên có th ñư c vi t l i như sau:
Select Case TheColorYouLike Case vbRed MsgBox "You 're a lucky person" Case vbGreen MsgBox "You 're a hopeful person" Case vbBlue MsgBox "You 're a brave person" Case vbMagenta MsgBox "You 're a sad person" Else MsgBox "You 're an average person" End Select

Cách vi t n y tương ñ i d ñ c và ít nh m l n khi vi t code hơn là dùng nhi u ELSEIF. Ph n ELSE trong Select Case statement thì optional (nhi m ý), t c là có cũng ñư c, không có cũng không sao. H khi ñi u ki n c a m t Case ñư c tho mãn thì nh ng dòng code t ñó cho ñ n dòng Case k dư i hay Else ñư c x lý và ti p theo execution s nh y xu ng dòng n m ngay dư i dòng End Select. Nh là dư i cùng ta vi t End Select, ch không ph i End If. Các Expression dùng cho m i trư ng h p Case không nh t thi t ph i ñơn gi n như v y. ð bi t thêm chi ti t v cách dùng Select Case, b n highlight ch Case (doubleclick ch Case) r i b m nút F1.

Dùng FOR statement
Trong l p trình, nói v Flow Control (ñi u khi n hư ng ñi c a execution) ta dùng hai lo i statement chính: Branch statements như IF..THEN..ELSE (k c Select Case) và Iterative statements (l p ñi, l p l i) như FOR và WHILE LOOP (Vòng). Ta s nói ñ n WHILE Loop trong ph n k ti p. Trong khi Branch statement cho phép ta execute trong nhánh n y hay nhánh kia tùy theo value c a Logical Expression thì Iterative statement cho ta execute m t ph n code l p ñi, l p l i nhi u l n cho ñ n khi m t ñi u ki n ñư c th a mãn. Gi d ta vi t m t chương trình ñơn gi n ñ tính t ng s các con s gi a b t c hai con s nào (coi ch ng l n quá). Cái form c a chương trình gi ng như dư i ñây:

Sau khi cho hai con s From (T ) và To (Cho ñ n) ta click nút Calculate và th y k t qu hi n ra trong Textbox txtTotal. Cái Sub tính t ng s ñư c li t ra dư i ñây:
Private Sub CmdTotal_Click() Dim i, FromNo, ToNo, Total FromNo = CInt(txtFromNumber.Text) ' Convert Text string ra internal number b?ng Function CInt ToNo = CInt(txtToNumber.Text) ' Convert Text string ra internal number b?ng Function CInt

53

Total = 0 ' Initialise Total value to zero For i = FromNo To ToNo ' Iterate from FromNo to ToNo Total = Total + i ' Add the number to the Total Next txtTotal.Text = CStr(Total) ' Convert internal number ra Text string End Sub

Trong thí d trên, FOR loop b t ñ u t dòng For i = FromNo To ToNo và ch m d t dòng Next. Khi execution b t ñ u Total b ng 0, i b ng FromNo. Execution s ñi qua h t nh ng dòng trong FOR loop r i value c a i s ñư c tăng lên 1, r i execution s b t ñ u l i ñ u loop. Trong thí d n y vì FromNo=4 và ToNo=6 nên execution s ñi qua cái FOR loop 3 l n. L n th nh t i=4, l n th nhì i=5 ,và l n th ba thì i=6. Sau ñó, khi i=7 thì nó l n hơn ToNo (=6) nên execution nh y ra kh i FOR loop. K t qu là Total=15 và ñư c display trong Textbox txtTotal, sau khi ñư c converted t internal number ra text string v i Function CStr. N u ta ch mu n c ng nh ng s ch n t 4 ñ n 16 ta có th làm cho i tăng value lên 2 (thay vì 1) m i khi ñ n cu i loop. T c là i=4,6,8 .v.v..Ta s thêm ch STEP trong FOR statement như sau:
For i = 4 To 16 Step 2 ' Iterate from 4 to 16 with Step=2 Total = Total + i ' Add the number to the Total Next

Total s b ng 4+6+8+10+12+14+16= 70. Trong thí d trên ta cũng có th dùng STEP s âm như sau:
For i = 16 To 4 Step -2 ' Iterate from 16 to 4 with Step=-2 Total = Total + i ' Add the number to the Total Next

Trong trư ng h p n y FOR loop b t ñ u v i i=16. Khi ñ n cu i loop l n th nh t value c a i b b t 2 và tr thành 14. Sau ñó i b gi m giá tr d n d n ñ n 4. K ñó i=2 thì nh hơn s cu i cùng (=4) nên execution nh y ra kh i FOR loop. Gi d ta mu n l y ra t t c nh ng blank space trong m t text string. Ta bi t con s characters trong m t text string, còn g i là chi u dài c a text string có th tính b ng cách dùng Function Len(TString). Và ñ nói ñ n character th i trong m t Text string ta dùng Mid Function.

Khi User click button Remove Blank Spaces chương trình s execute Sub dư i ñây:
Private Sub CmdRemoveBlankSpaces_Click() Dim i, TLen, TMess TMess = "" ' Initialise temporary String to null string For i = 1 To Len(txtOriginalString.Text) ' Iterate from the first chracter to the last character of the string ' Check if chracter is NOT a blank space

54

If Mid(txtOriginalString.Text, i, 1) <> " " Then ' Character is not a blank space - so append it to TMess TMess = TMess & Mid(txtOriginalString.Text, i, 1) End If Next txtResultString.Text = TMess ' Disaplay TMess by assigning it to txtResultString.text End Sub

Thông thư ng, ta dùng FOR loop khi bi t trư c execution s ñi qua loop m t s l n nh t ñ nh. Nhưng th nh tho ng, khi m t ñi u ki n ñư c th a mãn ta có th ép execution nh y ra gi a ch ng kh i FOR loop, ch không ñ i cho ñ n ñ s l n ñi qua loop. Thí d như ta mu n bi t ph i c ng bao nhiêu s k ti p t 1 tr lên ñ ñư c t ng s v a l n hơn hay b ng 76.

Khi User click button Work Out, Sub dư i ñây s ñư c x lý:
Private Sub cmdWorkOut_Click() Dim i, Total, WantedTotal WantedTotal = CInt(txtWantedTotal.Text) ' Convert Text string ra internal number b?ng Function CInt Total = 0 ' Initialise Total value to zero For i = 1 To 30 Total = Total + i ' Add the number to the Total If Total >= WantedTotal Then Exit For ' Jump out of FOR loop Next txtActualTotal.Text = CStr(Total) ' Display the Actual Total txtUptoNumber.Text = CStr(i) ' Display the highest number End Sub

Dùng DO WHILE Loop statement
Khi ta không bi t ch c là execution s ñi qua loop bao nhiêu l n thì t t nh t là dùng DO WHILE Loop statement. Khàc v i FOR Loop, trong DO WHILE Loop ta ph i t lo initialisation (t c là m i vô ñ u i b ng bao nhiêu) và t lo tăng value c a parameter i. N u Logical Expression là True thì execute nh ng dòng code t DO WHILE cho ñ n Loop. Thí d m i v a qua có th vi t l i b ng cách dùng DO WHILE Loop như sau:
Private Sub cmdWorkOut_Click() Dim i, Total WantedTotal = CInt(txtWantedTotal.Text) ' Convert Text string ra internal number b?ng Function

55

CInt Total = 0 ' Initialise Total value to zero i = 1 ' Intialise at the first character Do While (Total < WantedTotal) ' Logical Expression is (Total < WantedTotal) Total = Total + i ' Add the number to the Total i = i + 1 ' Increment the vakue of i Loop txtActualtotal.Text = CStr(Total) ' Display the Actual Total txtUptonumber.Text = CStr(i - 1) ' Display the highest number End Sub

TRong khi Total hãy còn nh hơn WantedTotal thì ta ti p t c ñi qua While Loop. Gi d ta có các hàng text ch a giá ti n các th có th b vào bánh mì th t v i giá như sau:
Chicken Roll Roast Beef Tomato Sauce 45c 55c 5c

Bây gi ta mu n vi t code ñ l y ra giá ti n t nh ng hàng Text string như trên. Ta s ñi t bên ph i l n l n qua trái cho ñ n khi tìm ñư c m t blank space.
Private Sub WorkOutPrice_Click() Dim i, TStr, PriceInCents, Price TStr = "Chicken Roll 45c" i = Len(TStr) ' Starting from the rightmost character of the text string ' Going from right to left, look for the first blank character Do While (Mid(TStr, i, 1) <> " ") i = i - 1 ' Keep walking to the left Loop PriceInCents = Mid(TStr, i + 1) ' String including character "c" ' Discard the rightmost character which is "c" and convert the price string to single number Price = CSng(Left(PriceInCents, Len(PriceInCents) - 1)) txtPrice.Text = CStr(Price) ' Display the highest number End Sub

Dùng Function
Function là m t d ng subroutine gi ng gi ng như Sub. Ch khác ch Function cho ta m t k t qu , cho nên cách dùng Function hơi khác v i Sub. Ta vi t m t variable bên trái d u =, ñư c assigned k t qu c a m t Function. Thí d như ta dùng Trim Function ñ lo i b nh ng blank space hai ñ u c a text string TString:
ResultString = Trim(TString)

Ta ñưa cho Function Trim m t text string called TString. Sau khi Function Trim ñư c executed, ta có k t qu nhưng TString không h thay ñ i. Ngư c l i, khi ta g i m t Sub, t t c nh ng parameter ta ñưa cho Sub ñ u có th thay ñ i tr khi ta tuyên b m t parameter nào ñó là ByVal. Trong thí d sau, m t copy c a StringA ñư c ñưa cho Sub nên sau khi execute ProcessString, StringA không h b thay ñ i.
Sub ProcessString (ByVal StringA, ConditionA, ConditionB)

Public Sub và Function

56

Khi ta dùng ch Public (thay vì Private) phía trư c m t Sub hay Function, ta cho phép code n m m t Form hay Basic Module khác có th g i (hay dùng) Sub hay Function ñó. Thí d trong Form2 ta có ñ nh nghĩa DisplayData là:
Public Sub DisplayData .... End Sub

Trong Form1, ta g i DisplayDta như sau:
Form2.DisplayData

Chương Ba - Form và các Controls thông thư ng

H u h t các chương trình VB6 ñ u có ít nh t m t Form. Khi ta ch y chương trình, Form n y s

hi n ra trư c h t ñ ta ra l nh nó làm chuy n gì. Cái Form tr ng không ch làm ñư c gì nhi u, nên ta ñ t lên Form nh ng controls như Textbox(h p ñ ñánh ch vào), Label(nhãn), Commandbutton(nút b m m nh l nh), .v.v.. Các controls cho ta enter các d ki n ñ chương trình dùng x lý, và các controls cũng hi n th (display) k t qu cho chúng ta xem.

S p ñ t controls lên Form
Ta hãy b t ñ u thi t k m t chương trình m i (New Project) b ng cách ch n Standard EXE, môi trư ng tri n khai l p trình (IDE) cho b n s n m t Form tên là Form1. Mu n ñ t m t Control lên Form, click hình cái Control trong Toolbox r i Drag (b m nút trái c a con chu t r i kéo cho thành hình ch nh t trư c khi buông nút trái ra) con chu t trên Form v thành c c a Control. M t cách khác ñ ñ t m t control lên Form là doubleclick cái Control trong Toolbox, m t hình control s hi n ra trên Form. K ñó b n d i control ñi ñ n ch mình mu n và resize nó. N u b t c lúc nào b n không th y Túi ñ ngh (Toolbox) n m bên trái, b n có th dùng m nh l nh Menu View|Toolbox ñ b t nó hi n ra. Có m t cách khác là click lên toolbox icon trên toolbar chính c a VB6.

Nên nh r ng Toolbox cũng là m t window như các window khác. Khi nó hi n lên r i b n có th n m (b m nút trái c a con chu t và gi như v y ch không buông ra) title nó ñ d i ñi nơi khác. B n có th ñóng nó b ng cách click lên d u x góc ph i phía trên. N u right click trên Toolbox, nó s display context sensitive menu, trong ñó có property dockable (có th ñ u b n) . N u m t window là dockable, sau khi b n d i nó ñi kh i vi trí docked bình thư ng c a nó, b n có th dock nó l i như c b ng cách double click lên title c a nó.

Resize và di chuy n control
Khi b n select m t control (click lên nó), chung quanh control s hi n ra resize handle, 8 nút ñen d c theo chu vi c a control.

57

Click lên các nút ñen c a resize handle, b n có th resize control. Có m t cách khác ñ resize control là dùng Shift + ArrowKey. B m nút Shift trong khi b m m t arrow key, control s l n ra hay thu h p theo chi u c a ArrowKey. Lưu ý: M t s control có kích thư c t i thi u, b n không th làm cho nó nh hơn ñư c. Thí d như Combobox, nó ph i cao ñ ñ display m t hàng text. Tương t như th , b m nút Ctrl trong khi b m m t arrow key, control s di chuy n theo chi u c a ArrowKey. Ngoài ra, nên nh r ng trong lúc chương trình ch y (at run-time), trong code ta có th thay ñ i kích thư c và v trí các controls d dàng, th m chí có th làm cho chúng hi n ra hay bi n m t b ng cách s a ñ i value các property left, top, width, height và visible c a các controls.

Alignment Grid
ð giúp b n s p ñ t ngay ng n các controls trên m t form, VB6 cho b n Alignment Grid. Nó là nh ng d u ñen c a các hàng d c và xuôi trên form. B n có th làm cho các d u ñen c a grid trên form bi n m t b ng cách dùng menu command Tools | Options ñ display Option Dialog, k ñó ch n Tag General và clear checkbox "Show Grid":

B n cũng có th nhân d p n y thay ñ i kho ng cách chi u r ng (Width) và chi u cao (Height) c a các ch m ñen c a grid. Kích thư c nh nh t c a Width hay Height là 24. Hãy so sánh hai trư ng h p form có và không có Show Grid như dư i ñây:

58

Control Locking
M t khi b n ñã s p ñ t kích thư c và v trí c a các control trên form r i, r t d ta tình c thay ñ i các ñ c tính y vì vô ý click lên m t control. Do ñó VB6 cho ta Menu command Format | Lock Controls ñ khóa chúng l i. Sau khi khóa, cái hình ng khóa trên menu b chìm xu ng.

N u sau n y b n mu n thay ñ i kích thư c ho c v trí c a chúng thì nh dùng Menu command Format | Lock Controls l i. Sau khi m khóa, cái hình ng khóa trên menu hi n ra bình thư ng.

Cài ñ t các Properties c a Form
Nhi u property c a m t form nh hư ng ñ n di n m o v t lý (physical appearance) c a nó. Property Caption s quy t ñ nh text ñư c hi u th trong title. N u Property BorderStyle c a form không ph i là Sizable thì User không th resize form at run-time. Property Icon quy t ñ nh hình icon ñu c dùng trong title c a form, nh t là khi form thu nh (minimized). N u b n không mu n cho phép User minimize hay maximize form thì set value c a property MinButton, MaxButton ra False. N u property ControlBox là False thì form s không có nút minize, maximize hay close (x) trên góc ph i c a nó, ñ ng th i form cũng không display c icon bên góc trái title như trong hình dư i ñây:

V trí ñ u tiên (top,left) c a form có th ñư c thay ñ i trong design time b ng cách di chuy n hình nh c a nó trong window Form Layout:

59

Property WindowState xác ñ nh Form s có kích thư c bình thư ng (normal=0), hay minimized (=1), maximized =(2). Lưu ý là property Font c a Form s ñư c các control n m trên nó th a k . T c là khi b n ñ t m t control lên form, property Font c a control y s t ñ ng tr nên gi ng y như c a form.

Vài Event thông d ng c a Form
Nhìn t m t phương di n, Form cũng gi ng như Control. Ta có th instantiate m t form nhi u l n ñ có nhi u form tương t nhau. Trong thí d dư i ñây, ta instantiate Form2 hai l n ñ có MyForm và YourForm:
Private Sub CmdCreateForms_Click() Dim MyForm, YourForm Set MyForm = New Form2 MyForm.Caption = "This is My Form" MyForm.Show MyForm.Move 1000, 1000 Set YourForm = New Form2 YourForm.Caption = "YOUR FORM IS HERE" YourForm.Show YourForm.Move 2000, 2000 End Sub

M t Form cũng có nhi u Events r t h u d ng.

F orm_Initialize: Event n y xãy ra trư c nh t và ch m t l n thôi khi ta instantiate form ñ u tiên. Ta dùng Form_Initialize event ñ th c hi n nh ng gì c n ph i làm chung cho t t c các instances c a form n y.

F orm_Load: Event n y xãy ra m i l n ta instantiate m t form. N u ta ch dùng m t instance duy nh t c a m t form trong chương trình thì Form_Load coi như tương ñương v i Form_Initialize. Ta dùng Form_Load event ñ initialise variables, controls v.v. cho instance n y. Bên trong Form_Load b n không th dùng Setfocus cho m t control nào trên form vì form chưa h n thành hình (ra ñ i). Mu n làm vi c y b n ph i delay (trì ho n) m t chút xíu b ng cách dùng Control Timer ñ ñ i cho Form_Load ñư c hoàn t t. Thí d :

60

Private Sub Form_Load() Timer1.Interval = 500 Timer1.Enabled = True End Sub Private Sub Timer1_Timer() Timer1.Enabled = False ' Timer1_Timer only execute once txtName.Setfocus ' Make Tab Cursor start at TextBox txtName End Sub

F orm_Activate: M i l n m t form tr nên active (current) thì nó generate m t Activate event. Ta có th dùng event n y ñ refresh display trên form.

F orm_QueryUnload: Khi User click d u x phía trên bên ph i ñ close form thì nó generate QueryUnload event. Syntax c a Sub n y như dư i ñây:

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer) End Sub

Event n y cho ta m t d p ñ cancel Close action c a form (t c là không cho User close form) b ng cách set Cancel b ng 1. UnloadMode cho ta bi t ai, task hay form nào mu n close form n y. Ngoài ra, b n cũng nên bi t r ng m t form t ñ ng Load hay tr nên active n u b n nh c ñ n nó, thí d như dùng Form2.List1. Khi m t form ñã ñư c loaded r i b n có th hide (làm cho bi n m t) nó. K ñó, khi b n show form ra tr l i thì form không có gì thay ñ i. Nhưng n u b n Unload m t form (thí d b ng cách dùng Unload Form2 ), r i sau ñó load tr l i b ng cách dùng Form2.Show ch ng h n, thì Form ph i tr i qua quá trình Form_Load, và dĩ nhiên form m t t t c nh ng gì có trư c ñây. Ngoài ra, Hide/Show m t form ñã ñư c loaded r i thì r t nhanh, còn Unload/Load thì m t thì gi hơn. Khi b n Show m t Form chưa hi n h u thì form s ñư c loaded và show. ðôi khi b n mu n Load m t form, r i làm vi c v i nó trư c khi Show, trong trư ng h p ñó b n dùng Load Form2 r i m t ch p sau dùng Form2.Show.

MDI Form
ðôi khi b n mu n có m t MDI form, t c là m t form có th ch a nhi u form con bên trong. D ng MDIform n y thư ng ñư c dùng trong các application như wordprocessor ñ có th m nhi u document cùng m t lúc, m i document ñư c hi n th trong m t form con. ð có m t MDIForm b n c n ph i dùng menu command Project | Add MDI Form. M i VB6 project ch có th có t i ña m t MDIform. Mu n m t form tr thành m t form con b n set property MDI Child c a nó thành True. At run-time b n không th hide (bi n nó thành invisible) m t MDIChild form, nhưng có th minimize nó. N u b n th t s mu n hide nó thì ph i dùng mánh l i là cho nó v trí (top,left) s âm l n hơn kích thư c nó ñ nó n m ngoài t m hi n th c a form. Trong m t chương trình dùng MDI Form, khi b n click MDI Form nó không nh y ra phía trư c và che các form con, nhưng v n luôn luôn n m dư i.

Controls là gì?

61

Controls v a có hình, v a có code ch y bên trong m t window nho nh , gi ng như m t form. Khi ta l p trình VB6 ta l p ráp các controls (là nh ng v t d ng ti n ch ) trên m t hay nhi u form ñ có m t chương trình nhanh chóng. Ta giao d ch v i m t control qua ba ñ c tính c a control:

P roperties: t p h p các ñ c tính c a control mà ta có th n ñ nh lúc design time hay run-time. Có nhi u properties v di n m o, n u ta thay ñ i at design time s th y k t qu hi n ra l p t c, thí d Font hay màu s c.

M ethods: nh ng gì control th c hi n ñu c, t c là nh ng kh năng c a nó. E vents: nh ng s c mà control s thông báo cho chúng ta bi t khi nó xãy ra v i control. Khi m t event xãy ra VB6 s x lý m t Event Handler (thí d như Sub Command1_Click()), mi n là chúng ta vi t code s n trong ñó. N u không có code thì coi như chúng ta không thèm bi t ñ n các event lo i ñó. Có m t s Events mà chúng ta thư ng x lý là:

o

C lick : xãy ra khi user click lên control. Ta thư ng dùng nó cho CommandButton và Listbox. M ouseDown, MouseUp : m i khi User b m m t mouse button là có m t MouseDown Event, khi User buông nó ra thì có m t MouseUp Event. Ta thư ng dùng MouseDown Event ñ Popup context sensitive menu hay b t ñ u m t di n bi n Drag. Thí d :

o

Private Sub Foods_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single) If Button = vbRightButton Then ' if Right button was pressed PopupMenu mnuActions ' popup a menu End If End Sub Private Sub DrinkList_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single) DrinkList.drag ' Displaying a drag icon to start the drag process End Sub

ð ý là Click không cho chúng ta thêm chi ti t gì v s c , trong khi MouseDown/MouseUp cho ta bi t v trí c a cursor, button nào c a Mouse ñư c b m và lúc y User có b m nút Shift, Ctrl hay Alt không. M i Click là ñi ñôi v i m t c p MouseDown/MouseUp. N u b n mu n x lý v a Click l n MouseDown thì ph i c n th n. Thí d b n mu n v a handle Click event v a handle Mouse Drag thì ph i làm sao phân bi t hai trư ng h p. N u không User ch mu n th y k t qu c a Click mà l i th y control b t ñ u display m t Drag icon thì s b c mình.
o

K eyPress : xãy ra khi user Press m t key. Ta thư ng dùng nó cho TextBox ñ lo i ra (filter out) các keystrokes ta không ch p nh n. KeyPress cho ta ASCII value, m t con s có giá tr t 1 ñ n 255, c a key. Trong thí d dư i ñây, m t Enter key s ñư c coi như m t TAB key:
Private Sub Text1_KeyPress(KeyAscii As Integer)

62

If KeyAscii = 13 Then KeyAscii = 0 ' Swallow the character to avoid side effect SendKeys "{TAB}" ' Emulate entering a TAB End If End Sub
o

K eyDown, KeyUp : m i KeyPress event là cho ta m t c p KeyDown/KeyUp event. KeyDown/KeyUp cho ta KeyCode và Shift value. ð detect Function key ta c n dùng KeyDown event. Trong thí d dư i ñây, ta display Function key User b m:
Private Sub Text3_KeyDown(KeyCode As Integer, Shift As Integer) If (KeyCode >= 112) And (KeyCode <= 123) Then MsgBox "You pressed the Function key: F" & Trim(Str(KeyCode - 111)) End If End Sub

o

G LotFocus : Control tr nên active khi nó nh n ñư c Focus. Nó s generate m t GotFocus Event. Ta có th dùng nó ñ ñ i màu background c a m t text box như trong thí d dư i ñây:
Private Sub Text2_GotFocus() Text2.BackColor = vbYellow End Sub

o

L LostFocus : Thư ng thư ng h m t Control GotFocus thì trư c ñó có m t Control LostFocus. Ta có th dùng Event n y ñ Validate entry data hay thu x p công chuy n cho m t control v a m t Focus. Trong thí d dư i ñây, n u User không ñánh vào m t con s trong Textbox Text1 thì s ñư c thông báo và Tab Cursor s tr l i Textbox Text1.
Private Sub Text1_LostFocus() If Not IsNumeric(Text1.Text) Then MsgBox "Please enter a number!" Text1.SetFocus End If End Sub

o

r DagDrop : xãy ra khi ta drop m t cái gì lên control . Parameter Source cho ta bi t Control nào ñã ñư c Drag và Drop. Nhi u khi m t control có th nh n drop t nhi u control khác nhau. Trong trư ng h p ñó ta ph i test xem ho c Control Type, ho c Name ho c Tag value c a Source control là gì ñ tùy nghi x lý. Trong thí d dư i ñây, khi User drop mouse xu ng Textbox Text2, n u Source là m t Listbox, không c n bi t Listbox nào, thì ta copy dòng ñư c ch n trong Listbox y qua Textbox Text2.

63

Private Sub Text2_DragDrop(Source As Control, X As Single, Y As Single) If TypeOf Source Is ListBox Then Text2.Text = Source.Text End If End Sub

TextBox
TextBox là control ñu c dùng nhi u nh t ñ display text và nh n keystroke c a Userñ s a ñ i text có s n hay cho vào text m i. Property chính và default c a Textbox là text, t c là thư ng thư ng Text2.text có th ñư c vi t t t là Text2. Ta có th disable (khi n nó b t l c, không ph n ng gì h t và không cho s a ñ i) m t text box b ng cách set Property Enable ra False (ch s b m ñi), hay Lock (không cho s a ñ i) m t text box b ng cách set Property Locked ra True (ch không b m ). Text có th ñư c Align (Alignment Property) ñ display bên trái, chính gi a hay bên ph i c a h p nó.

B n có th ch n BackColor và ForeColor cho background và text c a TextBox. Dùng Tag Palette khi ch n màu ñ có ñúng m t màu b n mu n.

Dĩ nhiên b n có th l a ch n Font và c ch cho Text v i Font Property. B n gi i h n s characters mà User có th enter cho TextBox b ng cách set MaxLength Property. N u Property Multiline là True thì User có th enter nhi u hàng. At Design time, n u b n mu n enter multiline thì ph i nh b m nút Ctrl khi press Enter m i khi xu ng hàng. N u không VB6 IDE tư ng r ng b n ñã k t thúc editing.

64

Mu n assign cho text box multiline text thì ph i nhét vào m i cu i hàng CarriageReturn và LineFeed characters. Thí d như:
Private Sub Command1_Click() Dim TextStr TextStr = "Bau ra bau lay ong cau" & vbCrLf ' Note: vbCrLf = chr(13) & chr(10) TextStr = TextStr & "Bau cau ca bong ngat dau kho tieu" Text1.Text = TextStr End Sub

N u b n mu n mách nư c cho User v cách dùng m t textbox nào ñó thì có th dùng Property ToolTipText ñ nó display mách nư c m i khi mouse cursor n m lên textbox.

Dùng Property TabIndex ñ n ñ nh th t cho Tab Cursor d ng m i khi User b m nút TAB ñ d i TAB Cursor ñ n Textbox k ti p. N u b n không mu n Tab Cursor d ng m t TextBox nào thì set Property TabStop nó thành False. Tab Cursor không d ng Textbox có Property Enabled b ng False, nhưng v n d ng Textbox có property Locked b ng True. N u b n mu n dùng Textbox làm m t Password field thì set Property PasswordChar b ng "*". Làm như th s ép bu c Textbox display m i character b ng PasswordChar, t c là "*", ñ ngư i khác không ñ c ñư c trong khi User enter m t Paswword.

Properties SelLength, SelStart và SelText N u b n mu n bi t ñư c tình hình hi n th i c a Textbox: SelText cho b n dãy ch ñang ñư c selected. SelStart cho b n v trí c a insertion point (ch cursor flashing). SelLength cho bi t con s characters ñã ñư c selected. N u b n mu n s a ñ i text trong Textbox: SelText cho b n nhét vào m t dãy ch . SelStart cho b n n ñ nh v trí b t ñ u c a dãy ch b n s p select. SelLength n ñ nh s characters b n mu n ch n, b t ñ u

65

t SelStart. Dư i ñây là m t thí d trong ñó ta highlight text tìm ñư c:
Private Sub Form_Click () Dim Search, Where ' Declare variables. ' Get search string from user. Search = InputBox("Enter text to be found:") Where = InStr(Text1.Text, Search) ' Find the given string in Text1.Text. If Where > 0 Then ' If found, Text1.SelStart = Where - 1 ' set selection start and Text1.SelLength = Len(Search) ' set selection length. Else MsgBox "String not found." ' Notify user. End If End Sub

CommandButton
CommandButton r t ti n cho ta dùng vào vi c x lý m t chuy n gì khi User click lên button. Event ta dùng thư ng nh t cho CommanButton là Click. Ta dùng Property Caption c a CommandButton ñ enter cái gì ta mu n display trên button. N u mu n cho phép User dùng ALT+E (ñè nút Atl trong lúc b m nút E) ñ generate event click thì nhét d u "&" trư c ch E trong Caption c a button. Caption s display ch E v i m t g ch dư i. Ngoài ra ta cũng có th cho thêm m t cái hình vào CommandButton b ng cách ch n m t icon cho property Picture và set Property Style ra Graphical, thay vì Standard.

Lúc Run-time b n có th thay ñ i hình hay Caption c a CommandButton. Trong thí d dư i ñây, Caption c a CommandButton CmdOperation flip-flop gi a hai values Stop và Start:
Private Sub CmdOperation_Click() If CmdOperation.Caption = "&Stop" Then CmdOperation.Caption = "St&art" Else CmdOperation.Caption = "&Stop" End If End Sub

Label
M c ñích chính c a Label là ñ display, không cho User Edit như Textbox. Do ñó ta có th dùng Property Font, ForeColor và Backcolor ñ làm cho nó ñ p. Ngoài ra Property BorderStyle có th cho Label l m xu ng n u b n set nó b ng Fixed Single. N u set property BackStyle b ng Transparent s tránh trư ng h p Backcolor c a Label làm cho không ñ p.

66

Label cũng có Property Tabindex. N u b n mu n dùng ALT key ñ mang Tab Cursor v m t Textbox, hãy ñ m t Label v i TabIndex b ng TabIndex c a TextBox tr 1. Gi s Label có Caption là "&Address" thì ALT+A s mang Tab Cursor v TextBox màu vàng như trong thí d dư i ñây:

Ngoài ra nh r ng b n có th thay ñ i Caption c a Label lúc run-time.

CheckBox
CheckBox ñư c dùng ñ User xác nh n có ñ c tính nào m t cách nhanh chóng. Property Value c a CheckBox có th là Checked (làm cho h p vuông có d u, b ng 1), Unchecked (làm cho h p vuông tr ng không, b ng 0) hay Grayed (làm cho h p vuông có d u màu nh t, b ng 2). M t khi bi t r ng CheckBox có Value b ng 1, ta có th ñ c Caption c a CheckBox ñ dùng n u c n.

B n có th dùng Property Alignment ñ làm cho Caption ñ ng bên ph i (Left Justify) hay bên trái (Right Justify) c a h p vuông.

OptionButton
OptionButton ( còn g i là RadioButton) có hình tròn v i m t ch m gi a, thay gì hình vuông v i m t g ch gi a như CheckBox. OptionButton luôn luôn ñư c qui t thành m t nhóm, ch a trong m t container. Container là m t Control có kh năng ch a các controls khác. Frame, PictureBox, hay chính Form ñ u là Container. Sau khi ñ t m t Container lên Form, n u mu n ñ m t OptionButton lên Container, trư c h t ta ph i Select container, r i k ñó ch n OptionButton. S dĩ, t t c OptionButtons ph i n m trong m t container là vì b t c lúc nào, nhi u nh t là m t OptionButton trong container có value True (vòng tròn có ch m gi a). Mu n bi t m t OptionButton có th t s n m trong m t container, b n th kéo cái container ñi ch khác. N u OptionButton b d i theo container thì nó n m trong container. M t cách khác là th kéo OptionButton ra kh i container. N u kéo ra ñư c thì nó không n m trong container. Mu n di chuy n m t OptionButton t container n y sang container khác, b n Cut OptionButton r i Paste nó vô container kia.

67

ðôi khi m t container n m che trên m t control khác. Mu n mang m t container ra phía sau các controls khác b n Select container r i dùng Menu command Format | Order | Send to Back.

Chương Năm - Các lo i d

ki n

Công vi c chính c a t t c các chương trình VB6 chúng ta vi t là ch bi n các d ki n ñ trình bày. Thí d m t th y giáo dùng m t chương trình ñ tính ñi m trung bình c a h c sinh trong m t môn thi. Th y tu n t cho ñi m c a t ng h c sinh vào và sau cùng b m m t nút b o chuơng trình tính ñi m trung bình cho c l p. Chương trình s display ñi m thi c a t ng h c sinh bên c nh tên c a h c sinh y, t ng s h c sinh, t ng s ñi m, ñi m th p nh t, ñi m cao nh t và ñi m trung bình: Tên h Lê Quang Vinh Tr n văn Thành Nguy n Th Hương Võ T Cư ng Ph m Văn Khá Cao Xuân Tiên Ði m 15.50 16.00 17.50 14.00 18.00 13.00 T ng s h c sinh: 6

68

T ng s ñi m: 94.00 Ði m th p nh t: 13.00 Ði m cao nh t: 18.00 Ði m trung bình: 15.66 Ta có th t m chia quá trình x lý c a m t chương trình ra làm ba giai ño n: 1. Ti p nh n d ki n: Ðây là giai ño n ta cho d ki n vào chương trình (Input data) ho c b ng cách ñi n vào m t form, ho c ñ c d ki n t m t cơ s d ki n (Database) ho c nh n d ki n qua ñư ng dây vi n thông, .v.v.. 2. Ch bi n d ki n: M t khi ñã có d ki n ñ y ñ r i ta s s p x p, c ng, tr , nhân, chia theo cách ñã ñ nh trư c ñ ñi ñ n k t qu . 3. Trình bày, báo cáo: K t qu c n ph i ñư c display trên màn nh cách g n gh , th t hay ñư c in ra, ta còn g i là Report. Như v y trong m i giai ño n c a chương trình ta ñ u làm vi c v i d ki n. Trong thí d nói trên ta làm vi c v i hai lo i d ki n: "dòng ch " (text string) cho tên h c sinh và "s " (number) cho các ñi m. S dĩ ta ph i phân bi t các data types vì m i lo i data có nh ng ch c năng riêng c a nó. Thí d ta không th c ng hai text string l i v i nhau như hai con s , nhưng ta có th ghép hai text string l i v i nhau, thí d như ghép ch house v i ch wife thành ra ch housewife. Ch c n a ta s bàn thêm v data types, nhưng bây gi ta th tìm hi u data ñư c ch a trong computer như th nào. D ki n ñư c ch a theo quy ư c R t cu c l i, t t c data ñ u ñư c ch a dư i d ng các con s . M i con s ñ i di n cho m t th gì ñó, tùy theo quy ư c c a ngư i dùng. Chúng ta bi t b trí nh (memory) c a computer ch a nh ng byte data, thí d như computer c a b n có 32MB, t c là kho ng hơn 32 tri u bytes. Th t ra m t byte g m có 8 bits, m i bit ñ i di n m t trong hai tr s : 1 và 0, hay Yes và No , dòng ñi n ch y qua ñư c hay không ñư c .v.v.. Bit là ñơn v trí nh nh nh t c a memory. M t byte có th ch a m t con s t 0 ñ n 255, t c là 2^8 -1 (2 lũy th a 8 b t 1) . Khi dùng bits ta ñ m các s trong h th ng nh phân. N u b n chưa bi t nhi u thì hãy ñ c bài H th ng s nh phân. Thí d , khi b n n nút A trên keyboard, keyboard s g i v computer con s 65 (01000001 trong nh phân) . N u b n ñang dùng m t Notepad ch ng h n, b n s th y ch A hi n ra. B n h i t i sao letter A ñư c bi u di n b ng s 65? Xin tr l i r ng ñó là quy ư c qu c t . Quy ư c ñu c áp d ng cho t t c các keys c a bàn phím ñu c g i là ASCII. Theo quy ư c n y digit "1" ñư c bi u di n b ng con s 48 (00110001) và nút Enter b ng s 13 (00010011). Ch c có l b n ñã ñoán ra r ng theo quy ư c ASCII, m i pattern (d ng) c a 8 bits (1 byte) s bi u di n m t text character. Bây gi ta th tính xem các m u t alphabet và digits s chi m bao nhiêu patterns trong s 256 patterns ta có th bi u di n b ng 1 byte. T A ñ n Z có 26 characters. Nhân ñôi ñ tính cho lowercase (ch thư ng) và uppercase (ch hoa) thành ra 52. C ng v i 10 digits t 0 ñ n 9 thành ra 62. C ng thêm ch ng ba mươi ngoài các symbols ta dùng ch ñ n ch ng 100 patterns mà thôi. T c là nói m t cách khác n u s patterns ta dùng dư i 128 thì ch c n 7 bits (ch không ñ n 8 bits) cũng ñ r i. Th t ra t nãy gi ta ch nói ñ n các characters có th display hay in ra ñu c (printable characters). Các con s ASCII t 1 ñ n 31 không in ra ñu c nhưng ñu c dùng m t cách ñ c bi t, thí d như 7 là BELL (ti ng bíp), 12 là qua trang m i, 10 là xu ng hàng, 13 là Enter/CarriageReturn, .v.v.. Chúng ñu c g i là các Control Characters.

69

Khi xem qua các Font ch trong Windows, b n s th y cho cùng m t con s 65, không ph i Font nào cũng display ch A. Thí d như Font Symbol nó display ñ th d u hi u. Ði m n y nh c chúng ta l i r ng m i liên h gi a m t con s bên trong (internal number) và m t d u hi u ñư c display ch ng qua là m t quy ư c mà thôi. Gi s chúng ta dùng nh ng con s ASCII còn tr ng ñ bi u di n các ch Vi t Nam có d u và ch u khó ng i v thêm các Vietnamese characters c n thi t trong Font thì ta có th display ch Vi t ñu c. Ðúng v y, ñó là cách các khoa h c gia Vi t Nam ñã dùng ñ display ti ng Vi t trong MSWindows, ñi n hình là VPS, VISCII. Không ph i memory c a computer ch ch a data thư ng mà thôi. Nó còn ch a chính chương trình, g i là executable code trong machine language (ngôn ng c a máy). Ngày xưa, khi memory c a computer còn ít, ngư i ta có th cho vào t ng byte c a code m t chương trình. H l p trình b ng Assembly language. M i hàng code trong Assembly language có th ñu c d ch th ng ra code trong machine language. CPU c a m i manufacturer có m t assembly language khác nhau. Các công ty Computer n i ti ng ngày xưa là IBM, Digital, CDC. Ð n th i bu i Microcomputer ta có Motorola, Intel, nhưng t u trung, n u không bi t trư c code c a machine language nào, ta không th nh n ra gì c khi nhìn vào memory dump (in ra snapshot c a memory) c a m t computer. Text String N u ta ghép nhi u characters l i v i nhau ta có m t Text String. Trong VB6, Text String ñư c vi t thành m t dãy ch v i d u ngo c kép hai ñ u, thí d : "Hello, world" Tư ng tư ng ta ghép ba m u t alphabet ñ u tiên l i v i nhau: ABC, trong memory Text String n y ñư c bi u di n b ng con s 010000010100001001000011 (trong binary) hay 414243 (trong Hex, m i nhóm 4 bits tương ñuơng v i m t Hex digit). VB6 cho ta nh ng Function r t ti n l i ñ làm vi c v i Text String. Ð ghép hai Text String l i v i nhau ta dùng operator &. Thí d : FirstWord = "Hello" SecondWord = "World" Greeting = FirstWord & SecondWord ' Greeting bây gi là "HelloWorld" n u mu n có m t blank space gi a hai ch trên ta vi t như sau: Greeting = FirstWord & " " & SecondWord Mu n bi t m t Text String ñang ch a bao nhiêu characters ta dùng Function Len. Thí d : Greeting = "Hi John!" iLen = Len(Greeting) ' iLen bây gi b ng 8 Ð trích ra m t ph n c a Text String (t c là trích ra m t SubString) ta dùng các Functions Left, Right và Mid. Today = "24/05/2001" ' L y ra 2 characters t bên trái c a String Today StrDay = Left(Today,2) ' StrDay bây gi b ng "24" ' L y ra 4 characters t bên ph i c a String Today StrYear = Right(Today,4) ' StrYear bây gi b ng "2001" ' L y ra 2 characters b t ñ u t character th tư c a String Today, character ñ u tiên t bên trái là th nh t StrMonth = Mid(Today,4,2) ' StrMonth bây gi b ng "05"

70

' L y ra ph n còn l i b t ñ u t character th tư c a String Today StrMonthYear = Mid(Today,4) ' StrMonthYear bây gi b ng 05/2001" Trong t t c các trư ng h p trên Text String Today không h b thay ñ i, ta ch trích ra m t SubString c a nó mà thôi. N u ta mu n thay ñ i chính Text String Today ta có th assign value m i cho nó hay dùng Function Mid bên trái d u Assign (=), thí d : Today = "24/05/2001" ' Thay th character th 3 c a Today b ng "-" Mid(Today,3,1) = "-" ' Thay th 2 characters b t ñ u t character th 4 c a Today b ng "10" Mid(Today,4,2) = "10" ' Thay th character th 6 c a Today b ng "-" Mid(Today,6,1) = "-" ' Today bây gi b ng "24-10-2001" Ta cũng có th ñ t ñư c k t qu như trên b ng cách l p trình như sau: Today = "24/05/2001" Today = Left(Today,2) & "-10-" & Right(Today,4) Ngoài ra có hai Function r t thông d ng cho Text String là Instr và Replace. Instr cho ta v trí (position) c a m t pattern trong m t Text String. Thí d ta mu n bi t có d u * trong m t Text String hay không: myString = "The *rain in Spain mainly..." Position = Instr(myString,"*") ' Position s là 5 N u trong myString không có d u "*" thì Position s b ng 0 Bây gi ta th tách ra Key và Value trong thí d sau: KeyValuePair = "BeatlesSong=Yesterday" Pos = Instr(KeyValuePair, "=") Key = Left(KeyValuePair, Pos-1) Value = Mid(KeyValuePair, Pos+1) Mu n thay ñ i t t c d u "/" thành d u "-" trong m t Text String ta có th dùng Function Replace như sau: Today = "24/05/2001" Today = Replace (Today, "/", "-") Mu n bi t tr s ASCII c a m t character ta dùng Function Asc và ngư c l i ñ có m t Text Character v i m t tr s ASCII nào ñó ta dùng Function Chr. ASCIINumberA = Asc("A") ' ASCIINumberA bây gi b ng 65 LineFeedChar = Chr(10) StrFive = Chr(Asc("0") + 5) ' ta có digit "5" Text String trong VB6 dùng m t byte cho m i ASCII character. Sau n y khi ta l p trình trong VB7, m t character có th là Unicode character, trong trư ng h p ñó nó ñư c bi u di n b ng 2 bytes. VB6 không support Unicode nên không ph i là môi trư ng thích h p ñ l p trình cho Unicode ti ng Vi t. Trong VB7 m i lo i Text String có Encoding method riêng c a nó ñ y m tr Unicode n u c n.

71

Các lo i s T nãy gi ta ch bàn v Text String và cách ch a c a nó trong memory. Nên nh r ng "123" là m t Text String và nó ñư c bi u di n trong memory b ng con s 001100010011001000110011 trong Binary hay 313233 trong Hex. Như v y có cách nào bi u di n con s 123 mà không dùng Text String không? Dĩ nhiên là ñư c. Con s 123 là 7B trong Hex hay 01111011 trong Binary, và ta có th ch a con s n y v a ti n l i ñ làm toán, v a ít t n memory hơn là ch a Text String "123". Nh là ta c n Text String ñ display hay in ra, còn khi làm toán c ng, tr , nhân, chia ta l i c n cái d ng raw number hay internal number c a nó. Ð convert m t Text String ra Internal number ta có th dùng các Functions Val, CInt(ra Integer) hay CSng(ra Single). Ngư c l i, ñ convert t internal number ra Text String ta có th dùng Function CStr. Dollars = "500" ExchangeRatePerDollar = "7000" tempValue= Val(Dollars) * Val(ExchangeRatePerDollar) VNDong = CStr(tempValue) MsgBox "Amount in VN Dong is " & VNDong Th t ra VB6 support nhi u lo i data ñ dùng ch a nh ng con s . Trư c h t ta có s nguyên (Integer và Long). Cùng là s nguyên nhưng Integer dùng 2 bytes trong memory ñ ch a m t con s nguyên t -32768 ñ n 32767. Ð ý là 32768 = 2^15 (2 lũy th a 15) , t c là trong memory các con s t 32768 ñ n 65535 ñư c dùng ñ bi u di n các s âm. M t l n n a, nh r ng m t con s trong memory ñ bi u di n m t th gì ch ng qua ch là theo quy ư c mà thôi. Còn Long dùng 4 byte ñ ñ ch a m t con s nguyên t -2147483648 ñ n 2147483647. N u b n dùng Integer mà b Oveflow error khi làm toán nhân thì assign các con s vào m t Long variable (s c t nghĩa variable sau n y) TRƯ C KHI làm toán nhân ch ñ ng ñ k t qu m t bài toán nhân quá l n trư c khi Assign nó vào m t Long variable. Thí d : ' Thay gì vi t Dim Result as Long Result = 30345 * 100 ' s b overflow error ' Hãy vi t như sau: Dim Result as Long Result = 30345 Result = Result * 100 ' không b overflow error

Ð tính toán cho chính xác ta c n m t lo i data có th ch a s sau decimal point. VB6 cho ta Single và Double. Single dùng 4 bytes, Double dùng 8 bytes. Thông thư ng, b n s hi m khi c n nh c ñ n Double. Khi display m t s Single hay Double b n c n dùng Function Format ñ convert t Single ra Text String m t cách uy n chuy n. Thí d Dollars = "500.0" ExchangeRatePerDollar = "7000.0" 'Dùng Function CSng ñ convert String ra Single tempValue= CSng(Dollars) * CSng(ExchangeRatePerDollar) 'Dùng Function Format ñ có các d u ph y ngàn và tri u và ph i có 2 digits sau decimal point. VNDong = Format (tempValue, "#,###,###.00") MsgBox "Amount in VN Dong is " & VNDong

72

VB6 cho ta hai cách chia, ñó là / dùng cho Single/Double và \ dùng cho Integer. 5 / 3 cho ta 1.6666666 5 \ 3 cho ta 1

Function Round ñu c dùng ñ b b t các con s n m phía sau decimal point. Thí d : Round ( 12.3456789, 4 ) ch gi l i 4 con s sau decimal point và cho ta 12.3457

Numeric data type Currency ch ch a nh t ñ nh 4 s sau decimal point. Nó không có ích l i ñ c bi t gì. Variable Variable là nh ng ch ch a data t m th i trong memory ñ ta dùng trong quá trình bi n ch data c a chương trình. Khi ta Declare (khai báo) m t variable lo i data gì là ta dành ra m t ch trong memory ñ ch a m t mi ng data lo i y. Nh là tùy theo lo i data ta s c n nhi u hay ít memory, m t Interger ch c n 2 bytes, còn m t Single c n ñ n 4 bytes, trong khi m t String thì c n nhi u memory hơn n a. Thí d như: Dim strFullName as String Dim ICount as Integer Dim sRate as Single

Khi b n tìm cách cho hai data type khác nhau làm vi c, thí d như làm toán chia m t Text String b i m t con s thì có th b Mixed mode error. Tuy nhiên n u Text String y g m nh ng digits thì có th VB6 s t ñ ng convert Text String ra m t con s trư c khi dùng nó trong m t bài toán. Ngư c l i, dĩ nhiên ta không th ghép m t con s vào m t Text String, nhưng VB6 có th convert con s ra m t Text String of digits trư c khi ghép Text String y vào String kia. M c d u VB6 r t t nh trong vi c ñoán ra ý ñ nh c a chúng ta trong khi coding nhưng ta ph i th n tr ng trong cách dùng Data type ñ tránh g p ph i nh ng b t ng . V n ñ ñ t tên cho variable r t quan tr ng. B n nên ñ t tên variable và các Function, Sub như th nào ñ khi ñ c code ta th y d hi u như ñ c m t bài lu n văn. Thư ng thư ng, ñ d nh n di n data type c a m t variable ngư i ta g n phía trư c tên variable các prefix như str cho String, I cho Integer, s cho Single ..v.v.. Khi ráp nhi u ch r i thành tên m t variable, thư ng thư ng ngư i ta làm cho letter ñ u tiên c a m i ch thành ra Hoa (Capital), thí d như TotalSalesOfTheMonth. Có m t Tip nho nh là ñ ng ng i ñ t tên variable quá dài. Khi ñánh máy n a ch ng tên c a m t variable b n có th ñánh Ctrl-Space ñ IDE ñánh n t ph n còn l i c a tên variable, n u không có s trùng h p v i m t tên variable/Sub/Function nào khác. N u công tác l p trình gi ng như n u ăn, b n có th nghĩ ñ n variable như các cái r , thau ta c n có ñ vi c chu n b th c ăn ñư c ti n l i. Trư c khi b t tay vào công tác ta xin v i ch nhà cho mình bao nhiêu cái r , thau, thún .v.v..(ñó là Declare variables). Ta ñ m i lo i th c ăn vào m t r hay thau khác nhau, ch không ñ th t chung v i rau c i (cũng như không th c ng Text String v i con s ). Khi ta b thêm m t trái cà vào r cà thì s trái cà trong r tăng lên 1. M t lát sau ta l y ra vài trái cà ñ dùng thì s trái cà trong r b gi m ñi. Khi không c n dùng n a ta b hay c t m y trái cà còn l i r i d p cái r ñi ch khác.

73

Tr giá c a m t variable thư ng hay thay ñ i trong quá trình x lý data. Ð n m t lúc nào ñó variable không còn hi n h u. Ph m vi ho t ñ ng c a m t variable ñư c g i là scope. N u code n m ngoài ph m vi c a m t variable thì không th dùng ñ n variable y ñư c. Dư i ñây là listing c a m t chương trình VB6 ng n: Option Explicit Dim iCount As Integer Dim X As Integer Dim Y As Integer Private Sub CmdIncreX_Click() iCount = iCount + 1 X=X+1 If X = 80 Then X=0 Y=Y+1 End If End Sub Private Sub CmdIncreY_Click() Dim Y iCount = iCount + 1 Y=Y+1 End Sub Trong listing trên Scope c a iCount, X, Y là toàn b listing, t c là ñâu cũng có th nói ñ n, dùng, th y các variables ñó. Tuy nhiên trong Sub CmdIncreY-Click() có declare m t variable Y. Scope c a variable n y là ch n i b , t c là bên trong Sub CmdIncreY-Click() mà thôi. Ch ng nh ng th , cái local (ñ a phương) variable Y n y còn che cái global variable Y n a, t c là bên trong Sub CmdIncreY-Click() ta ch th y local variable Y mà không th y global variable Y. M t khi execution trong Sub CmdIncreY-Click() ñã k t thúc thì local variable Y cũng bi n m t luôn. N u b n mu n khi tr l i execute Sub CmdIncreY-Click() mà local variable Y v n còn y nguyên v i giá tr gì nó có t trư c, b n nên Declare r ng nó Static, như: Static Y as Integer Nói tóm l i, Local variable c a Sub hay Function ch ho t ñ ng và hi n h u bên trong Sub/Function. Global variable c a m t Form hay Module thì áp d ng cho c Form/Module tr khi b che l i b i m t local variable có cùng tên bên tron m t Sub/Function. Ngoài ra khi ta Declare m t Global variable là Public thì các Form/Module khác cũng th y và dùng nó ñư c luôn. Theo nguyên t c c a Software Engineering thì vì lý do an ninh ta ch cho phép ngư i khác th y cái gì c n th y thôi. Do ñó, ta không nên Declare các variable Public b a bãi, nh khi có m t variable b thay ñ i value m t cách bí m t mà ta không ñoán ñu c th ph m là ai. Nh r ng Declare Public cũng gi ng như ñ nhà không ñóng c a v y. Ngoài ra, câu Option Explicit ñ u Listing ñư c dùng ñ tuyên b r ng t t c m i variables dùng trong Form/Module ñ u c n ph i ñư c Declare. Nh là VB6 không ñòi h i ta ph i Declare m t variable trư c khi dùng nó. Thư ng thư ng, tùy theo tình hu ng, VB6 có th ñoán ra ñư c Data Type c a variable khi ta dùng nó l n ñ u tiên. N u code ñòi h i value c a m t variable khi nó ñu c dùng l n

74

ñ u thì VB6 t ñ ng coi nó như m t Empty String (String không có character nào c , vi t là "" ) n u nó là Text String Data type hay con s 0 n u nó là m t con s . Ði u n y r t là ti n l i. Tuy nhiên, n u ta sơ ý ñánh v n l n m t variable thì VB6 t ñ ng initialise nó ra Empty String hay 0. Ðây có th không ph i là ñi u ta mu n. N u có dùng Option Explicit thì vi c n y s b l t y ngay vì t t c m i variable ñ u ph i ñu c tuyên b chính th c. Do ñó, ñã là VB6 programmer, b n hãy xem vi c dùng Option Explicit như là m t ñi u răn c a Chúa, hãy vâng gi cách trung tín. Ngày và Gi Có m t lo i data type ñu c dùng ñ ch c ngày l n gi , ñó là Date. Ta có th bi t hi n th i là ngày nào, m y gi b ng cách g i Function Now. Sau ñó ta dùng các Function Day, Month và Year ñ l y ra ngày, tháng và năm như sau: Private Sub CmdCheckDate_Click() Dim dDate As Date If IsDate(txtDate.Text) Then ' eg: txtDate = "26/12/01" dDate = CVDate(txtDate.Text) ' convert a Text String to internal Date using Function CVDate ' Day, Month and Year are automatically converted to String MsgBox "Day = " & Day(dDate) & ", Month = " & Month(dDate) & ", Year = " & Year(dDate) Else MsgBox "Invalid date. Please try again." End If End Sub Trong Listing trên ta dùng Function IsDate ñ ki m xem txtDate.text có h p l không. Lưu ý là IsDate không phân bi t ngày theo M (d ng mm/dd/yy) hay theo Âu Châu (d ng dd/mm/yy), do ñó dùng IsDate trong công vi c ki m soát n y không an toàn l m. Ð display ngày gi theo ñúng cách mình mu n b n có th dùng Function Format như sau:

MsgBox "NOW IS " & Format (Now, "ddd dd-mmm-yyyy hh:nn:ss") ' will display NOW IS Fri 08-Jun-2001 22:10:53 B n có th dùng mm ñ display tháng b ng m t con s . S dĩ ta dùng nn thay vì mm cho phút là vì mm ñã ñư c dùng cho tháng. Ta có th thêm b t các ñơn v c a ngày, tháng, v.v. b ng cách dùng Function DateAdd. Thí d :

Private Sub CmdNextMonth_Click() txtDate.Text = Format(Now, "dd/mm/yy") ' 08/06/01

75

txtNextMonth.Text = DateAdd("m", 1, CVDate(txtDate.Text)) ' txtNextMonth.text will show 8/07/2001 End Sub

Dư i ñây là cách tính ra ngày cu i c a tháng n y:

Private Sub CmdLastDayOfMonth_Click() Dim dNextMonthDate, dFirstDayNextMonth dNextMonthDate = DateAdd("m", 1, Now) ' Add one month to get same day next month ' Get first day of next month dFirstDayNextMonth = 1 & "/" & Month(dNextMonthDate) & "/" & Year(dNextMonthDate) ' Subtract one day to get Last day of this month txtLastDayOfMonth.Text = DateAdd("d", -1, CVDate(dFirstDayNextMonth)) End Sub

Ta có th tính kho ng cách gi a hai ngày theo ñơn v ngày, tháng v.v.. b ng cách dùng Function DateDiff. K t qu có th là âm, dương hay 0 tùy theo ngày nào tr hơn. Thí d kho ng cách gi a hai ngày theo ñơn v tháng:

DateDiff("m", Now, CVDate(dNextMonthDate))

Trong chương t i ta s h c v Data types Boolean, Variant và Data Array.

Chương Sáu - Dùng d

ki n

Trong chương 5 ta h c qua các ñi m căn b n v vi c dùng variables. Vì công vi c chính c a m t chương trình là x lý data ch a trong variables, cho nên n u VB6 cho ta càng nhi u phương ti n ñ làm vi c v i variables thì càng ti n l i. Trong chương n y ta s h c:
• • • • •

Boolean variable, t i sao nó h u d ng Variant variable, cách làm vi c v i nó. Cách bi n ñ i (convert) t lo i data type n y qua lo i data khác Arrays c a variables và Arrays c a controls Cách t o m t data type theo ý mình

Boolean Variables

76

Boolean là lo i data ch có th l y m t trong hai values: True hay False. Khi h c v Statement IF...THEN trong chương 4, ta ñã nói sơ qua v Boolean data type. Cái ph n gi a hai ch IF và THEN ñư c g i là Logical Expression và k t qu c a m t Logical Expression là m t Boolean value. N u ñi u ki n ñu c th a mãn thì value là True, n u không thì là False. B n h i n u m t variable ch có th có hai values, t i sao ta không th dùng Integer và gi i h n cách dùng trong vòng hai values 1 và 0 thôi, c n gì ph i ñ t ra Boolean data type. Làm như v y cũng ñư c, nhưng cái khác bi t chính là khi ta operate trên 2 variables ta ph i bi t rõ r ng ñ làm vi c v i Integer ta dùng +, -, *, \ trong khi v i Boolean ta dùng OR, AND, NOT, XOR. Th xem thí d dư i ñây: ' Use Integer with values 1 or 0 Dim IAnumber As Integer Dim IBnumber As Integer Dim IAge As Integer Dim sPersonalWorth As Single If (IAge >= 18) Then IAnumber = 1 Else IAnumber = 0 End If If (sPersonalWorth > 1000000) Then IBnumber = 1 Else IBnumber = 0 End If If (IAnumber = 1) And (IBnumber = 1) Then StandForTheElection End If '================================== ' Use Boolean Dim bAdult As Boolean Dim bRich As Boolean Dim IAge As Integer Dim sPersonalWorth As Single bAdult = (IAge >= 18) bRich = (sPersonalWorth > 1000000) If bAdult And bRich Then StandForTheElection End If Trong thí d trên, ta l p trình ñ n u m t ngư i th a mãn hai ñi u ki n: v a trư ng thành (18 tu i tr lên) , v a giàu có (có trên 1 tri u b c) thì có th ra ng c N u ta dùng Integer, th nh t chương trình ñ c khó hi u, th hai cái Logical Expression c a IF statement v n phài làm vi c v i operator AND. Trong khi ñó n u dùng Boolean thì chương trình có v t nhiên và d ñ c như ti ng Anh thông thư ng.

77

Variant Variables Variant variable có th ch a Text String, Number, Date, th m chí c m t Array (m t lo t nhi u variables cùng data type). Nhìn thoáng qua nó r t ti n d ng, nhưng khi m t Variant variable ñư c dùng nhi u ch , trong nhi u tình hu ng khác nhau, b n ph i th n tr ng. Lý do là vì variant variable có th ch a nh ng lo i data types khác nhau, nên khi b n operate hai variable có data type khác nhau, Visual Basic 6 c g ng bi n ñ i m t trong hai variable thành data type c a variable kia ñ làm vi c, k t qu là th nh tho ng b n s b k t. Các tay Software Engineers thu n túy r t ghét l p trình v i data không ñu c Declare rõ ràng. H không mu n b h vì vô tình. Thà r ng ñ Language Compiler b t g p trư c nh ng trư ng h p b n vô tình operate trên hai variables có data type khác nhau. Có khi ta b c mình vì Compiler khó tánh, nhưng s tránh b nh ng surprise (ng c nhiên) t n kém sau n y. Các ngôn ng l p trình g t gao y ñu c g i là strongly typed languages, ch ng h n như Pascal, C++, Java .v.v.. Sau n y n u ta dùng .NET thì các ngôn ng C#, VB.NET (VB7) ñ u là strongly typed. Trong VB7, Microsoft cho lưu ñài bi t tích Variant variables c a VB6. Công vi c Declare m t Variant variable cũng gi ng như Declare m t data type khác. Ch có ñi u ta có th bi t data type th t s ñang ñư c ch a bên trong m t Varaint variable b ng cách dùng Function VarType như dư i ñây: Private Sub cmdShowDataTypes_Click() Dim sMess As String Dim vVariant As Variant vVariant = "Nguoi Tinh khong chan dung" ' Assign a String to vVariant sMess = VarType(vVariant) & vbCrLf ' use vbCrLF to display the next string on a new line vVariant = 25 ' Assign an Integer to vVariant sMess = sMess & VarType(vVariant) & vbCrLf vVariant = True ' Assign an Boolean value to vVariant sMess = sMess & VarType(vVariant) & vbCrLf ' Assign an Date to vVariant vVariant = #1/1/2001# ' enclose a Date string with #, instead of " as for normal Text String sMess = sMess & VarType(vVariant) MsgBox sMess End Sub Khi ta click button ShowDataTypes chương trình s display giá tr c a các Data Types trong m i trư ng h p:

78

Sau ñây là b ng li t kê nh ng VarTypes thông d ng:

Giá tr VarType 0-vbEmpty 1-vbNull 2-vbInteger 4-vbSingle 7-vbDate 8-vbString 9-vbObject 11-vbBoolean

Chú thích Không có gì trong variant Không có valid (h p l ) data trong variant Variant ch a Integer Variant ch a Single Variant ch a Date/Time Variant ch a String Variant ch a m t Object Variant ch a Boolean

Ð làm vi c v i ñ lo i VarTypes b n có th dùng Select Case như sau: Private Sub Process_Click() Select Case VarType(vVariant) Case vbString ' ... Case vbBoolean ' ... Case vbInteger ' ... Case vbDate ' ... End Select End Sub Constants (H ng s )

79

Variables r t ti n d ng ñ chúng ta dùng ch a các data có th bi n ñ i value trong su t quá trình x lý c a chương trình. Nhưng ñôi khi chúng ta mu n có m t lo i variable mà value không bao gi thay ñ i, VB6 cho ta Constant ñ dùng vào vi c n y. Thí d như thay gì dùng tr c ti p môt con s hay m t Text String nhi u ch trong chương trình, ta ñ t tên Constant và cho nó m t value t i m t ch nh t ñ nh. Thí d ta vi t chương trình cho 5 chi c xe ch y ñua. Ð kh i hành các chi c xe ta dùng m t FOR...LOOP ñơn gi n như: For ICar = 1 To 5 Call StartCar (ICar) Next Tương t như v y nhi u nơi khác trong chương trình, m i l n nói ñ n con s các xe ta dùng s 5. N u sau n y mu n thay ñ i con s các xe thành ra 10, ta ph i tìm và thay ñ i t t c các con s 5 n y thành ra 10. N u không th n tr ng ta có th thay ñ i m t con s 5 dùng cho chuy n gì khác, ch không ph i cho con s các xe, thành ra 10 - như v y ta vô tình t o ra m t bug. Ð tránh v n ñ n y ta có th dùng Constant như sau: Const NUMBER_OF_CARS = 10 For ICar = 1 To NUMBER_OF_CARS Call StartCar (ICar) Next Sau n y mu n thay ñ i con s các xe, ta ch c n edit value c a Constant. Trong kh p chương trình, ni nào nh c ñ n con s các xe ta dùng ch NUMBER_OF_CARS, v a d hi u, v a tránh l m l n. Bi n ñ i (convert) t lo i data type n y qua lo i data khác

Nhi u lúc ta c n ph i convert data type c a m t variable t lo i n y qua lo i khác, VB6 cho ta m t s các Functions dư i ñây. Xin lưu r ng khi call các Functions n y, n u b n ñưa m t data value b t h p l thì có th b error.

Conversion Function CBool () CByte () CDate () CDbl () CInt () CSng () CStr ()

Chú thích Ð i parameter ra True hay False. N u Integer value khác 0 thì ñư c ñ i thành True Ð i parameter ra m t con s t 0 ñ n 255 n u có th ñư c, n u không ñư c thì là 0. Ð i parameter ra Date Ð i parameter ra Double precision floating point number Ð i parameter ra Integer Ð i parameter ra Single precision floating point number Ð i parameter ra String

Ngoài các Function nói trên b n cũng có th dùng Function Val ñ convert m t String ra Number. Lưu ý là khi Function Val process m t String n u nó g p m t character nào không ph i là digit hay decimal point thì nó không process ti p n a. Do ñó n u Input String là "$25.50" thì Val returns con s 0 vì $ không ph i là m t digit. N u Input String là "62.4B" thì Val returns 62.4. CDbl là Function dùng ñ convert m t String ra s an toàn nh t. Input String có th ch a các d u , và .

80

(thí d : 1,234,567.89) tùy theo nơi b n trên th gi i (thí d như Âu Châu hay M ). CSng cũng làm vi c gi ng như CDbl nhưng n u con s l n hơn 1 tri u nó có th b bug. Cái bug b c mình nh t c a CSng là n u Input String không có gì c (t c là InputString="") thì Function CSng cho b n Type Mismatch Error. Do ñó ñ kh c ph c cái khuy t ñi m n y b n có th vi t cho mình m t Function t m ñ t tên là CSingle ñ dùng th cho CSng như sau: Function CSingle(strNumber) As Single If Trim(strNumber) = "" Then CSingle = 0# Else CSingle = CSng(strNumber) End If End Function Arrays Khi b n có nhi u variables tương t nhau, thí d như ñi m thi c a 10 h c sinh, n u ph i ñ t tên khác nhau cho t ng variable (thí d : HoaMark, TaiMark, SonMark, TamMark, NgaMark, HuongMark .v.v..) thì th t là c c nh c và b t ti n. B n có th dùng Array ñ có m t tên chung cho c nhóm, r i nói ñ n ñi m c a t ng ngư i m t b ng cách dùng m t con s g i là ArrayIndex. B n s Declare như sau: Dim myStudentMarks(10) as Integer K ñó b n nói ñ n ñi m c a m i h c sinh b ng cách vi t myStudentMarks(i), mà i là ArrayIndex. Gi d ta mu n tính t ng s ñi m: Sub CmdCalculateTotal_Click() Dim myStudentMarks(10) As Integer ' Declare array, assuming students' marks are Integers Dim TotalMark As Integer ' Use this variable to accumulate the marks Dim i As Integer ' Use i as ArrayIndex myStudentMarks(1) = 6 ' First student's mark myStudentMarks(2) = 7 ' Second student's mark myStudentMarks(3) = 5 myStudentMarks(4) = 9 myStudentMarks(5) = 6 myStudentMarks(6) = 8 myStudentMarks(7) = 9 myStudentMarks(8) = 10 myStudentMarks(9) = 6 myStudentMarks(10) = 7 TotalMark = 0 ' This statement is not required as VB6 initialises TotalMark to 0 ' Go through all students and add each student's mark to the Total For i = 1 To 10 TotalMark = TotalMark + myStudentMarks(i) Next txtTotal.Text = CStr(TotalMark) ' Convert to String for display by assigning to

81

Textbox txtTotal End Sub

Khi ta Declare Dim myStudentMarks(10) as Integer th t ra ra ta có m t Array v i 11 Array Elements ch không ph i 10, vì Array b t ñ u v i ArrayIndex value=0. Có ñi u trong thí d trên ta c ý không nh c ñ n ArrayElement 0. N u th t s mu n có chính xác 10 Elements thôi, ta có th Declare như sau: Dim myStudentMarks (1 To 10 ) As Integer Lo i Array ta v a dùng qua là Single Dimention. N u trong thí d trên ta mu n tính ñi m c a h c sinh trong 3 l p h c, ta có th Declare Double Dimention Array như sau: ' Four classes, each has up to 6 students Dim myStudentMarks(3, 5) As Integer ' Note that each dimension starts at 0 ' or ' Three classes, each has up to 5 students Dim myStudentMarks(1 To 3, 1 To 5) As Integer Nhân ti n nói chuy n v Array cho variables, ta cũng có th dùng Array cho controls cùng m t lo i trong m t Form. N u ta có nhi u Label controls (hay Textbox controls ) v i nh ng ch c năng gi ng nhau trong chương trình, ta có th dùng cùng m t tên cho các controls, nhưng khác Property Index value c a chúng. B n có th create m t Array of Labels b ng cách Copy cái Label r i Paste nó lên Form. VB6 s h i n u b n mu n có m t Array of controls. N u b n tr l i Yes, VB6 s t ñ ng cho Label th nh t Index value=0 và Label m i v a ñư c Pasted Index value=1. Sau ñó n u b n ti p t c Paste cái Label ñã có Index r i thì VB6 không h i n a và vui v tăng Index value lên cho các Labels sau. Do ñó n u b n g i Label th nh t là lblClass r i Copy và Paste nó 2 l n b n s có m t Array of 3 Labels tên lblClass và các Index values 0, 1, 2. Trong thí d sau ñây, ta create m t Array of Labels tên lblClass và m t Array of Textboxes tên txtClassMark. Trong Sub Form_Load ta generate Captions c a các Labels. Private Sub Form_Load() Dim i As Integer For i = 0 To 2 ' Label Index starts at 0, but Class number starts at 1 lblClass(i) = "Mark of Class " & CStr(i + 1) Next End Sub Sub CmdCalculateTotal_Click() ' Three classes, each has up to 5 students

82

Dim myStudentMarks(1 To 3, 1 To 5) As Integer Dim TotalMark As Integer Dim ClassMark As Integer Dim i As Integer ' Use as ArrayIndex for Class Dim j As Integer ' Use as ArrayIndex for StudentMark ' Students' marks of first class myStudentMarks(1, 1) = 6 myStudentMarks(1, 2) = 7 myStudentMarks(1, 3) = 5 myStudentMarks(1, 4) = 9 myStudentMarks(1, 5) = 6 ' Students' marks of second class myStudentMarks(2, 1) = 8 myStudentMarks(2, 2) = 8 myStudentMarks(2, 3) = 6 ' Students' marks third class myStudentMarks(3, 1) = 5 myStudentMarks(3, 2) = 7 myStudentMarks(3, 3) = 8 myStudentMarks(3, 4) = 6 For i = 1 To 3 ClassMark = 0 ' Intialise ClassMark of class i to 0 ' Now go through each Student in Class i For j = 1 To 5 ClassMark = ClassMark + myStudentMarks(i, j) ' Accumulate ClassMark of class i TotalMark = TotalMark + myStudentMarks(i, j) Next ' Display ClassMark of class i. Note that txtClassMark Index starts at 0, NOT 1 txtClassMark(i - 1).Text = CStr(ClassMark) Next txtTotal.Text = CStr(TotalMark) ' Display TotalMark End Sub Ghi chú: N u b n có m t Array of Textboxes g m ch có 2 Textboxes, r i sau ñó b n Delete m t Textbox và mu n dùng Textbox còn l i làm cái Textbox duy nh t, b n v n ph i refer (nh c ñ n nó) b ng cách dùng Index (thí d : txtClassMark(0) ), dù r ng bây gi nó là Textbox duy nh t mang tên y. N u b n mu n d p cái v Index thì b n ph i vào Properties Window ñ Delete cái Index value c a ArrayTextbox. N u b n không lưu ý ñi m n y thì có khi b n s b t tóc không hi u t i sao mình dùng ñúng tên mà VB6 v n nh t ñ nh r ng cái Textbox b n nói ñ n không hi n h u, vì VB6 c n Index value c a Textbox.

83

Th nh tho ng, khi Declare Array b n không bi t rõ mình s c n bao nhiêu Elements cho m i dimension. Trong trư ng h p y b n có th dùng Dynamic Arrays và Declare m t Array như sau: Private myStudentMarks() As Integer Vì b n không ñ m t con s gi a hai d u ngo c ñơn nên VB6 bi t là b n mu n dùng Dynamic Array và dimension c a nó có th s thay ñ i trong tương lai. Khi nào mu n thay ñ i dimension c a Dynamic Array b n dùng ReDim keyword: ReDim myStudentMarks(10) ReDim Preserve myStudentMarks(10) C hai statements trên ñ u ñ i dimension c a Array myStudentMarks thành 11 (t Element 0 ñ n Element 10), nhưng trong statement th nhì ch Preserve gi nguyên values c a các Elements c a Array. Khi làm vi c v i Array th nh tho ng b n c n bi t các Elements th p nh t và cao nh t b ng cách dùng LBound và UBound. Private MyArray(10 to 20) As String LowestNum = LBound(MyArray) ' LBound returns 10 HighestNum = UBound(MyArray) ' UBound returns 20 Private YourArray( 2 to 5, 10 to 15) As Integer LowestNumOfFirstDimension = LBound(YourArray,1) ' LBound returns 2 HighestNumOfSecondDimension = UBound(YourArray,2) ' UBound returns 15 Ngoài ra n u dùng Dynamic Array, b n có th assign m t Array n y cho m t Array khác, thay vì ph i dùng FOR ...LOOP ñ copy t ng Array Element. MyArray = HisArray

Data Type c a b n B n có th gom các m nh Data c a cùng m t v t nào ñó thành m t nhóm và ñ t tên cho lo i Data Type y như sau: Type EmployeeRec ' EmployeeRec as name of this new Data Type Firstname As String Surname As String

84

Salary As Single DateOfBirth As Date End Type ' Now declare a variable of the new data type Dim MyEmployee As EmployeeRec MyEmployee.Firstname = "David" MyEmployee.Surname = "Smith" MyEmployee.Salary = 25000 MyEmployee.DateOfBirth = #14/6/1963# Trong Software Engineering, ngư i ta g i lo i Data Type n y là Structured Data Type ñ phân bi t nó v i các lo i Simple Data Type như Integer, Boolean, Single .v.v.. B n ñ ý cách nói ñ n m t m nh data, MyEmployee.Firstname, gi ng như là Property Firstname c a m t control tên MyEmployee. Có m t cách vi t khác ñ tránh typing nhi u l n ch MyEmployee b ng cách dùng keyword With như sau: With MyEmployee .Firstname = "David" .Surname = "Smith" .Salary = 25000 .DateOfBirth = #14/6/1963# End With M c d u ñ nh nghĩa và dùng Structured Data Type cách n y r t ti n l i, nhưng sau n y ta có th dùng Class ñ ñ t ñư c cùng m t m c tiêu mà còn h u hi u hơn n a. Trong Class ch ng nh ng ta ñ nh nghĩa nh ng m nh data mà còn ñ ra cách x lý chúng n a.

Chương B y - Dùng List Controls
Có hai lo i List controls dùng trong VB6. Ðó là Listbox và Combobox. C hai ñ u display m t s hàng ñ ta có th l a ch n. Listbox chi m m t khung ch nh t, n u chi u ngang nh thì có khi không display ñ y ñ m t hàng, n u chi u dài không ñ ñ display t t c m i hàng thì Listbox t ñ ng cho ta m t vertical scroll bar ñ cho bi t còn có nhi u hàng b che và ta có th xem các hàng y b ng cách dùng vertical scroll bar. Combobox thư ng thư ng ch display m t hàng, nhưng ta có th ch n display b t c hàng nào khác. Combobox gi ng như m t t p h p c a m t Textbox n m phía trên và m t Listbox n m phía dư i.

Listbox có r t nhi u công d ng vì nó r t uy n chuy n. Trong chương n y ta s h c qua các áp d ng sau c a Listbox:

85

• • • • • • •

Display nhi u s l a ch n ñ User selects b ng cách click hay drag-drop Nh ng cách dùng Property Sorted Cách dùng Multiselect Dùng ñ display Events Dùng ñ Search hay process text Cách dùng Itemdata song song v i các Items c a List Dùng làm Queue

Listbox

Display nhi u s l a ch n
Ta hãy b t ñ u vi t m t chương trình g m có m t Listbox tên lstNames n m trong m t Form. Trong lstNames ta ñánh vào tên c a b y ngư i, m i l n xu ng hàng nh ñánh Ctrl-Enter, thay vì ch Enter, n u không VB6 tư ng ta ñã ñánh xong nên close property List. Các tên n y là nh ng hàng s hi n ra trong Listbox khi ta b t ñ u ch y program.

Ngoài lstNames ta cho thêm m t Label v i Caption STUDENTS ñ trang hoàng, và m t Label khác tên lblName. M i khi User click lên hàng tên nào ta mu n display hàng tên y trong lblName. Sau cùng ta cho vào m t CommandButton tên CmdExit ñ cho User phương ti n Stop cái program. Ta s có chương trình như sau: Private Sub lstNames_Click() ' Assign the selected line of Listbox lstNames to Caption of Label lblName lblName.Caption = lstNames.List(lstNames.ListIndex) ' or = lstNames.text End Sub Private Sub CmdExit_Click() End End Sub Gi s ta click vào tên John Smith trên Listbox, ta s th y tên y cũng ñu c display trong Label lblName.

86

Trong thí d n y, Listbox lstNames có 7 hàng ( Items). Con s Items n y là Property ListCount c a Listbox. Các Items c a Listbox ñư c ñ m t 0 ñ n ListCount-1. Trong trư ng h p n y là t 0 ñ n 6. Khi User click lên m t hàng, Listbox s generate Event lstNames_Click. Lúc b y gi ta có th bi t ñư c User v a m i Click hàng nào b ng cách h i Property ListIndex c a lstNames, nó s có value t 0 ñ n ListCount-1. Lúc program m i ch y, chưa ai Click lên Item nào c a Listbox thì ListIndex = -1. Nhũng Items trong Listbox ñư c xem như m t Array c a String. Array n y ñư c g i là List. Do ñó, ta nói ñ n Item th nh t c a Listbox lstNames b ng cách vi t lstNames.List(0) , và tương t như v y, Item cu i cùng là lstNames.List( lstNames.ListCount-1). Ta có th nói ñ n item v a ñư c Clicked b ng hai cách: ho c là lstNames.List(lstNames.ListIndex), ho c là lstNames.text.

Save content c a Listbox
Bây gi ñ lưu tr content c a lstNames, ta thêm m t CommandButton tên CmdSave. Ta s vi t code ñ khi User click nút CmdSave program s m m t Output text file và vi t m i items c a lstNames vào ñó: Private Sub CmdSave_Click() Dim i, FileName, FileNumber ' Obtain Folder where this program's EXE file resides FileName = App.Path ' Make sure FileName ends with a backslash If Right(FileName, 1) <> "\" Then FileName = FileName & "\" FileName = FileName & "MyList.txt" ' name output text file MyList.txt ' Obtain an available filenumber from the operating system FileNumber = FreeFile ' Open the FileName as an output file , using FileNumber as FileHandle Open FileName For Output As FileNumber ' Now iterate through each item of lstNames For i = 0 To lstNames.ListCount - 1 ' Write the List item to file. Make sure you use symbol # in front of FileNumber Print #FileNumber, lstNames.List(i) Next Close FileNumber ' Close the output file End Sub

87

App là m t Object ñ c bi t ñ i di n cho chính cái program ñang ch y. ñây ta dùng Property Path ñ bi t lúc program ñang ch y thì execute module EXE c a nó n m ñâu. Lý do là thư ng thư ng ta ñ các files liên h c n thi t cho program l n qu n ho c ngay trong folder c a program hay trong m t subfolder, ch ng h n như data, logs, .v.v.. App còn có m t s Properties khác cũng r t h u d ng như PrevInstance, Title, Revision ..v.v. N u m i started m t program mà th y App.PrevInstance = True thì lúc b y gi cũng có m t copy khác c a program ñang ch y. N u c n ta End program n y ñ tránh ch y 2 copies c a program cùng m t lúc. App.Title và App.Revision cho ta tin t c v Title và Revision c a program ñang ch y. Ð vi t ra m t Text file ta c n ph i Open nó trong mode Output và tuyên b t rày tr ñi s dùng m t con s (FileNumber) ñ ñ i di n cái File thay vì dùng chính FileName. Ð tránh dùng m t FileNumber ñã hi n h u, t t nh t ta h i xin Operating System cung c p cho mình m t con s chưa ai dùng b ng cách g i Function FreeFile. Con s FileNumber n y còn ñu c g i là FileHandle (Handle là tay c m). Sau khi ta Close FileNumber con s n y tr nên FREE và Operating System s có th dùng nó l i. Do ñó b n ph i tránh g i FreeFile liên ti p hai l n, vì OS s cho b n cùng m t con s . T c là, sau khi g i FreeFile ph i dùng nó ngay b ng cách Open m t File r i m i g i FreeFile l n k ñ có m t con s khác. Ð ý cách dùng ch Input, Output cho files là relative (tương ñ i) v i v trí c a program (nó n m trong memory c a computer). Do ñó t trong memory vi t ra hard disk thì nói là Output. Ngư c l i ñ c t m t Text file n m trên hard disk vào memory cho program ta thì g i là Input.

Load m t Text file vào Listbox
Trong bài n y, thay vì ñánh các Items c a Listbox vào Property List c a lstNames ta có th populate (làm ñ y) lstNames b ng cách ñ c các Items t m t Text file. Ta th thêm m t CommandButton tên CmdLoad. Ta s vi t code ñ khi User click nút CmdLoad program s m m t Input text file và ñ c t ng hàng ñ b vào lstNames: Private Sub CmdLoad_Click() Dim i, FileName, FileNumber, anItem ' Obtain Folder where this program's EXE file resides FileName = App.Path ' Make sure FileName ends with a backslash If Right(FileName, 1) <> "\" Then FileName = FileName & "\" FileName = FileName & "MyList.txt" ' Obtain an available filenumber from the operating system FileNumber = FreeFile ' Open the FileName as an input file , using FileNumber as FileHandle Open FileName For Input As FileNumber lstNames.Clear ' Clear the Listbox first ' Now read each line until reaching End-Of-File, i.e. no more data Do While NOT EOF(FileNumber) Line Input #FileNumber, anItem ' Read a line from the Text file into variable anItem lstNames.AddItem anItem ' Add this item to the bottom of lstNames Loop Close FileNumber ' Close the input file End Sub

88

Ð ñ c t m t Text file ta c n ph i Open nó trong mode Input. Trư c khi populate lstNames ta c n ph i delete t t c m i items có s n bên trong. Ð th c hi n vi c ñó ta dùng method Clear c a Listbox. Sau ñó ta dùng method AddItem ñ cho thêm t ng hàng vào trong Listbox. By default, n u ta không nói nhét vào ch hàng nào thì AddItem nhét Item m i vào dư i chót c a Listbox. N u mu n nhét hàng m i vào ngay trư c item th 5 (ListIndex = 4), ta vi t: lstNames.AddItem newItemString, 4 ' newItemString contains "Ross Close", for example ' To insert a new Item at the beginning of the Listbox, write: lstNames.AddItem newItemString, 0 Nh là m i l n b n Add m t Item vào Listbox thì ListCount c a Listbox increment by 1. Mu n delete m t item t Listbox ta dùng method RemoveItem, thí d như mu n delete item th ba (ListIndex=2) c a lstNames, ta vi t: lstNames.RemoveItem 2 M i l n b n RemoveItem t Listbox the ListCount c a Listbox decrement by 1. Do ñó n u b n dùng cái Test d a vào ListCount c a m t ListBox ñ nh y ra kh i m t Loop thì ph i coi ch ng tránh làm cho value ListCount thay ñ i trong Loop vì AddItem hay RemoveItem. Ta ñ c t ng hàng c a m t Text file b ng cách dùng Line Input #FileNumber. Khi ñ c ñ n cu i File, system d cho ta value EOF(FileNumber) = True. Ta dùng value y ñ cho program nh y ra kh i While.. Loop. Câu Do While NOT EOF(FileNumber) có nghĩa Trong khi chưa ñ n End-Of-File c a Text File ñ i di n b i FileNumber thì ñ c t hàng và b vào Listbox. Gi ng như "Trong khi chưa tr h t n nhà v thì ph i ti p t c r ".

Drag-Drop
Ta ñã h c qua Click Event c a Listbox. Bây gi ñ dùng Drag-Drop cho Listbox b n hãy ñ t 2 Labels m i lên Form. Cái th nh t tên gì cũng ñư c nhưng có Caption là Room A. Hãy g i Label th hai là lblRoom và cho Property BorderStyle c a nó b ng Fixed Single. K ñ n select c hai Labels (Click a Label then hold down key Ctrl while clicking the second Label) r i click copy và paste lên Form. VB6 s cho b n Array c a hai lblRoom labels. Ð cho lstNames m t DragIcon, b n click lstNames, click Property DragIcon ñ pop-up m t dialog cho b n ch n m t dragdrop icon t folder C:\Program Files\Microsoft Visual Studio\Common\Graphics\Icons\Dragdrop, ch ng h n như DRAG2PG.ICO:

Ta s dùng Event MouseDown c a lstNames ñ pop-up DragIcon hình 2 trang gi y cho User Drag nó qua bên ph i r i b xu ng lên m t trong hai lblRoom. Khi DragIcon rơi lên lblRoom, lblRoom s generate Event DragDrop. Ta s dùng Event DragDrop n y ñ assign property Text c a Source (t c là lstNames, cái control t nó phát xu t Drag action) vào Property Caption c a lblRoom. Lưu ý vì

89

ñây ta dùng cùng m t tên cho c hai lblRoom nên ch c n vi t code DragDrop.

m t ch ñ handle Event

Private Sub lstNames_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single) ' Start Pop-up DragIcon and start Drag action lstNames.Drag End Sub Private Sub lblRoom_DragDrop(Index As Integer, Source As Control, X As Single, Y As Single) ' Assign Property Text of Source (i.e. lstNames) to Label's Caption lblRoom(Index).Caption = Source.Text End Sub K t qu sau khi Drag hai tên t Listbox qua Labels là như sau:

Dùng Property Sorted
Trong thí d trên ta có th quy t ñ nh v trí c a m t Item m i khi ta nhét nó vào Listbox. Ðôi khi ta mu n các Items c a Listbox ñư c t ñ ng s p theo th t Alphabet. B n có th set Property Sorted = True ñ th c hi n chuy n n y. Có m t gi i h n là b n ph i cho Property Sorted m t value (True hay False) trong lúc design, ch trong khi ch y program b n không th làm cho Property Sorted c a Listbox thay ñ i. Gi d ta mu n sort các Items c a m t Listbox khi c n. V y thì ta làm sao? Gi i pháp r t ñơn gi n. B n t o m t Listbox tên lstTemp ch ng h n. Cho nó Property Visible= False (ñ không ai th y nó) và Property Sorted=True. Khi c n sort lstNames ch ng h n, ta copy content c a lstNames b vào lstTemp, ño n Clear lstNames r i copy content (ñã ñư c sorted) c a lstTemp tr l i lstNames. Lưu ý là ta có th AddItem vào m t Listbox v i Property Sorted=True, nhưng không th xác ñ nh nhét Item vào trư c hàng nào, vì v trí c a các Items do Listbox quy t ñ nh khi nó sort các Items. Ta hãy cho thêm vào Form m t CommandButton m i tên CmdSort và vi t code cho Event Click c a nó như sau: Private Sub CmdSort_Click() Dim i lstTemp.Clear ' Clear temporary Listbox ' Iterate though every item of lstNames For i = 0 To lstNames.ListCount - 1

90

' Add the lstNames item to lstTemp lstTemp.AddItem lstNames.List(i) Next lstNames.Clear ' Clear lstNames ' Iterate though every item of lstTemp For i = 0 To lstTemp.ListCount - 1 ' Add the lstTemp item to lstNames lstNames.AddItem lstTemp.List(i) Next lstTemp.Clear ' Tidy up - clear temporary Listbox End Sub Nhân ti n, ta mu n có option ñ sort các tên theo FirstName hay Surname. Vi c n y hơi r c r i hơn m t chút, nhưng nguyên t c v n là dùng cái sorted Listbox vô hình tên lstTemp. B n hãy ñ t lên phía trên lstName hai cál Labels m i tên lblFirstName và lblSurName và cho chúng Caption "FirstName" và "SurName". T ñây ta Load file "MyList.txt" vào lstNames b ng cách Click button CmdLoad ch không Edit Property List c a lstNames ñ enter Items lúc design n a. Ngoài ra ta dùng d u ph y (,) ñ tách FirstName kh i SurName trong m i tên ch a trong file MyList.txt. Content c a file MyList.txt bây gi tr thành như sau: Peter,Jones Kevin,White Sue,Rose John,Smith Trevor,Kennedy Alan,Wright Ron,Bruno Ta s s a code trong Sub CmdLoad_Click l i ñ khi nhét tên vào lstNames, FirstName và SurName m i th chi m 10 characters. Ð các ch trong Items c a lstNames s p hàng ngay ng n ta ñ i Font c a lstNames ra Courier New. Courier New là m t lo i Font mà chi u ngang c a ch m b ng ch i, trong khi h u h t các Fonts khác như Arial, Times Roman ..v.v. là Proportional Spacing, có nghĩa là ch m r ng hơn ch i. Listing m i c a Sub CmdLoad_Click tr thành như sau: Private Sub CmdLoad_Click() Dim i, Pos Dim FileName, FileNumber, anItem Dim sFirstName As String * 10 ' fixed length string of 10 characters Dim sSurName As String * 10 ' fixed length string of 10 characters ' Obtain Folder where this program's EXE file resides FileName = App.Path ' Make sure FileName ends with a backslash If Right(FileName, 1) <> "\" Then FileName = FileName & "\" FileName = FileName & "MyList.txt" ' Obtain an available filenumber from the operating system

91

FileNumber = FreeFile ' Open the FileName as an input file , using FileNumber as FileHandle Open FileName For Input As FileNumber lstNames.Clear ' Clear the Listbox first ' Now read each line until reaching End-Of-File, i.e. no more data Do While Not EOF(FileNumber) Line Input #FileNumber, anItem ' Read a line from the Text file ' Now separate FirstName from SurName Pos = InStr(anItem, ",") ' Locate the comma "," ' The part before "," is FirstName sFirstName = Left(anItem, Pos - 1) sFirstName = Trim(sFirstName) ' Trim off any unwanted blank spaces ' The part after "," is SurName sSurName = Mid(anItem, Pos + 1) sSurName = Trim(sSurName) ' Trim off any unwanted blank spaces lstNames.AddItem sFirstName & sSurName ' Add this item to the bottom of lstNames Loop Close FileNumber ' Close the input file End Sub Vì FirstName n m bên trái c a m i Item nên sort theo FirstName cũng gi ng như sort c Item. Vi c y ta ñã làm b ng Sub CmdSort_Click r i, do ñó khi User click Label lblFirstName ta ch c n g i CmdSort_Click như sau: Private Sub lblFirstName_Click() CmdSort_Click End Sub Ð sort theo SurName ta c n ph i t m th i ñ SurName qua bên trái c a Item trư c khi b vào lstTemp. Ta th c hi n chuy n n y b ng cách hoán chuy n v trí c a FirstName và SurName trong Item trư c khi b vào lstTemp. Sau ñó, khi copy các Items t lstTemp ñ b vô l i lstNames ta l i nh hoán chuy n FirstName và SurName ñ chúng n m ñúng l i v trí. T c là, cái mánh c a ta là mu n bi t Item nào ph i n m ñâu trong lstNames, ch dĩ nhiên khi display m i Item ñ u có FisrtName bên trái. Code ñ sort tên theo SurName cũng gi ng như CmdSort_Add nhưng thêm th t chút ít như sau: Private Sub lblSurName_Click() Dim i, anItem Dim sFirstName As String * 10 ' fixed length string of 10 characters Dim sSurName As String * 10 ' fixed length string of 10 characters lstTemp.Clear ' Clear temporary Listbox ' Iterate though every item of lstNames For i = 0 To lstNames.ListCount - 1 anItem = lstNames.List(i) ' Identify FistName and SurName sFirstName = Left(anItem, 10)

92

sSurName = Mid(anItem, 11) ' Swap FirstName/SurName positions before adding to lstTemp lstTemp.AddItem sSurName & sFirstName Next lstNames.Clear ' Clear lstNames ' Iterate though every item of lstTemp For i = 0 To lstTemp.ListCount - 1 anItem = lstTemp.List(i) ' Identify FistName and SurName sSurName = Left(anItem, 10) ' SurName now is on the left sFirstName = Mid(anItem, 11) ' Add FirstName/SurName in correct positions to lstNames lstNames.AddItem sFirstName & sSurName Next lstTemp.Clear ' Tidy up - clear temporary Listbox End Sub Các Items trong lstNames sorted theo SurName hi n ra như sau:

Nhân ti n ñây ta s a cái Sub CmdSave_Click l i m t chút ñ Save Items theo sorted order m i n u c n: Private Sub CmdSave_Click() Dim i, FileName, FileNumber, anItem ' Obtain Folder where this program's EXE file resides FileName = App.Path ' Make sure FileName ends with a backslash If Right(FileName, 1) <> "\" Then FileName = FileName & "\" ' Call Output filename "MyList.txt" FileName = FileName & "MyList.txt" ' Obtain an available filenumber from the operating system FileNumber = FreeFile ' Open the FileName as an output file , using FileNumber as FileHandle

93

Open FileName For Output As FileNumber ' Now iterate through each item of lstNames For i = 0 To lstNames.ListCount - 1 anItem = lstNames.List(i) anItem = Trim(Left(anItem, 10)) & "," & Trim(Mid(anItem, 11)) ' Write the List item to file. Make sure you use symbol # in front of FileNumber Print #FileNumber, anItem Next Close FileNumber ' Close the output file End Sub Trong bài t i ta s h c thêm các áp d ng khác c a ListBox. Listbox

Cách dùng MultiSelect
Cho ñ n gi User click vào Listbox ñ ch n ch m t Item. Khi m t Item ñư c ch n thì hàng y tr nên highlighted v i background màu xanh ñ m. N u k ñó ta click m t hàng khác thì hàng cũ ñư c display tr l i bình thư ng và hàng m i ñu c selected s tr nên highlighted. Listbox cho ta có th select nhi u Items cùng m t lúc b ng cách set Property MultiSelect = Extended

Ð i v i MultiSelected Listbox, ta ch n m t nhóm Items liên t c b ng cách click Item ñ u r i nh n nút Shift trong khi click Item cu i. Ta cũng có th ti p t c Select/Deselect thêm b ng cách n nút Ctrl trong khi click các Items. N u ta click m t Item chưa ñư c selected thì nó s tr nên selected (highlighted màu xanh), n u ta click m t Item ñã ñư c selected r i thì nó s tr nên deselected (không còn màu xanh n a). Thí d trong program b n click "Peter Jones", k ñó n nút Shift trong khi click "Sue Rose", k ñó buông nút Shift ra ñ n nút Ctrl trong khi click "Kevin White", b n s có nh ng selected Items như trong hình dư i ñây:

94

Ngoài ra b n cũng có th MultiSelect nhi u Items trong m t Listbox b ng cách dùng mouse ñ drag, t c là b n click lên Item ñ u r i ti p t c ñè mousebutton trong khi kéo mousepointer ñ n Item cu i cùng m i buông mousebutton ra.

Cái Bug ác ôn
Bây gi gi s ta mu n delete t t c nh ng Items v a ñư c selected (highlighted). B n hãy ñ t m t CommandButton m i tên CmdDeleteSelectedItems vào Form. Ta s dùng Event Click c a Button n y ñ delete nh ng selected Items. M t selected Item c a lstNames s có property Selected c a nó b ng True. T c là n u Item th ba (ListIndex=2) ñư c selected thì ta có lstNames.Selected(2) = True. Ta có ý ñ nh s iterate through m i Items c a lstNames, ñ xem Item nào ñư c selected thì mình s delete nó b ng cách dùng method RemoveItem. Ta s vi t code cho Sub CmdDeleteSelectedItems_Click() như sau: Private Sub CmdDeleteSelectedItems_Click() Dim i For i = 0 To lstNames.ListCount - 1 If lstNames.Selected(i) = True Then lstNames.RemoveItem i End If Next End Sub B n hãy ch y chương trình, click Load ñ populate lstNames v i các tên ñ c t text file, r i MultiSelect các tên như trong hình phía trên. K ñó click button DeleteSelectedItems. Program s té (crash) và có hình như sau:

95

N u b n click nút Debug, program s ng ng t i dòng code g p error và highlight nó v i background màu vàng. Ð mousepointer lên trên ch i c a lstNames.Selected(i), VB6 s popup message nho nh i = 4.

B n ñ ý th y trong hình lúc n y lstNames ch còn có 4 Items (Ron, Trevor, John và Alan), vì các Items kia ñã b removed. B n có bi t t i sao program crashed không? Ðó là vì program ñang refer ñ n property Selected c a Item th năm ( ArrayIndex i = 4) c a lstNames trong khi lstNames bây gi ch còn có 4 Items. Vì v y program crashed v i message "Runtime error '381': Invalid property array index". Th ph m c a cái Bug ác ôn n y là statement For i = 0 To lstNames.ListCount - 1. VB6 ch tính value c a lstNames.ListCount -1 m t l n lúc kh i s For..Loop mà thôi (t c là lstNames.ListCount -1 = 6), nó không lưu ý là ListCount gi m value m i l n m t Item b Removed. Ngoài ra ta th y tên "Trevor Kennedy" cũng không b removed, t c là nó b l t s n u ta dùng For..Loop theo cách n y. Lý do là sau khi ta Remove "Peter Jones" (Item th hai), "Trevor Kennedy" b ñ y lên và tr thành Item th hai m i. K ñó ta increment value c a i thành 2 r i process Item th ba, t c là "Sue Rose", nên "Trevor Kennedy" không h ñư c processed.

Sub CmdDeleteSelectedItems_Click c n ph i ñư c vi t l i ñ dùng While ... Loop, thay vì For...Loop. Trong While...Loop, lstNames.ListCount - 1 ñư c evaluated (tính) ñ test m i iteration. Khi nào ta Remove m t Item thì ta không increment i, vì Item ngay dư i removed Item ñư c ñ y lên. Listing m i như sau: Private Sub CmdDeleteSelectedItems_Click() Dim i i = 0 ' Initialise value of i to start from first Item ' Note that lstNames.ListCount is evaluated freshly at each iteration Do While i <= (lstNames.ListCount - 1) If lstNames.Selected(i) = True Then lstNames.RemoveItem i ' No need to increment i here because the item below is pushed up Else i = i + 1 ' increment i to process the next item End If Loop End Sub

96

Dùng Listbox ñ display Event Log
Trong thí d sau ñây ta mu n display input t m t serial COM port (Ð ñ c data th t qua serial COM port ta ph i dùng control MsCOMM có hình telephone màu vàng trong ToolBox). Nhưng ñ ti n vi c bi u di n, thay vì ñ c m t message t m t serial COM port, ta s emulate nó b ng cách dùng m t ComboBox. Khi user select m t hàng t ComboBox cboInput thì ta xem cboInput.text như data ñ c t serial COM port. L p t c lúc y ta s display input message trong hai d ng: ASCII và HEX. M i hàng input message ñư c prefix v i ngày và gi trư c khi ñư c cho vào hai Listboxes lstASCII và lstHexadecimal. Hình dư i ñây cho th y Form ñang display trong ASCII mode.

N u b n click button Display in HEX thì caption c a button ñ i thành Display in ASCII, lstASCII tr nên vô hình và lstHexadecimal s hi n ra như sau:

Dư i ñây là listing c a Function HexDisplay ñ convert t ASCII string ra Hexadecimal string. Function HexDisplay(InASCII) As String ' Convert an ASCII string to HEX string Dim InLen, i, msg, HexStr InLen = Len(InASCII) ' Get length of input string ' Convert each ASCII character to Hex For i = 1 To InLen HexStr = Hex(Asc(Mid(InASCII, i, 1))) ' If HEX has only one digit then prefix it with 0 If Len(HexStr) = 1 Then HexStr = "0" & HexStr msg = msg + HexStr & " " Next i HexDisplay = msg ' Return result string for Function End Function Trong program n y, khi Listbox ñ t ñ n 1000 items thì m i l n m t hàng m i ñư c thêm vào, hàng cũ nh t s b removed. Ð cho hàng m i nh t không b d u ta ph i nh cho ListIndex c a Listbox b ng

97

Listcount-1 ñ Listbox t ñ ng scrollup và highlight hàng cu i. M i khi ta thêm m t hàng vào Listbox lstHexadecimal, ta cũng ñ ng th i vi t nó vào m t LogFile. Tên c a LogFile n y d a vào ngày l y t Computer System và có d ng như Hex30Jun01.log. T c là ta s dùng m t LogFile khác cho m i ngày. M i khi qua ngày m i, program t ñ ng dùng m t LogFile m i. Nh là khi mu n vi t vào m t text file theo tên gì ñó, n u file chưa hi n h u thì ta ph i create nó và vi t vào, n u file ñã hi n h u r i ta ch c n append hàng m i vào cu i file (ph i c n th n ch n y, vì n u không, ta vô ý overwrite cái file và m t h t nh ng gì nó ch a trư c ñây). Sub DisplayInHEX(inString) Dim Mess, LogFileName ' Convert ASCII to Hex Mess = HexDisplay(inString) ' Prefix with date and time and add it to the bottom of Listbox lstHexadecimal.AddItem Format(Now, "dd/mm/yyyy hh:nn:ss") & " " & Mess ' Keep only the latest 1000 events If lstHexadecimal.ListCount >= 1000 Then ' Remove the first Item, i.e. the oldest item lstHexadecimal.RemoveItem 0 End If ' Highlight the lattest item in the Listbox lstHexadecimal.ListIndex = lstHexadecimal.ListCount - 1 ' Use different log file each day. Filename has format like Hex15Jun01.log LogFileName = "Hex" & Format(Now, "ddmmmyy") & ".log" ' Log to file including Date and Time LogEvent LogFileName, Mess, False, 2 End Sub

In ra content c a Listbox
Dư i ñây là m t áp d ng c a Listbox MutiSelect ñ in ra c Listbox hay ch nh ng hàng ñư c selected. Sub PrintList nh n:
• • •

Listbox mà ta mu n in m t Boolean value mà n u True thì in c Listbox Title c a Printout

Sub PrintList(theList As ListBox, PrintAll as Boolean, Title As String) ' Print the whole lot or only selected lines in a listbox ' PrintAll = True means printing the whole content of the listbox Const MaxLinesPerPage = 50 Dim msg, i, j, PageNo, NumLines, HasSome, Margin HasSome = False ' Flag indicating existence of data Margin = Space(10) ' Make a margin of 5 characters Title = vbLf & vbLf & Title + vbCrLf & vbLf

98

NumLines = 0 ' Init number of lines on this page PageNo = 1 ' init Page number msg = Title ' Msg will contain everything starting with Title Printer.FontName = "Courier New" ' Initialise Printer Fontname Printer.FontSize = 10 ' Initialise Printer FontSize Screen.MousePointer = vbHourglass ' Change mousepointer shape to Hourglass. If theList.ListCount > 0 Then ' get here if the listbox is not empty For i = 0 To theList.ListCount - 1 ' Go thru each line of text in the listbox If theList.Selected(i) Or PrintAll Then ' print a line of text if it's selected or PrinAll is true DoEvents ' Let other processes have a chance to run HasSome = True NumLines = NumLines + 1 ' Increment count of lines If Left(theList.List(i), 1) = "'" Then ' if first character is "'" then use this as an indication to force a new page If NumLines > 0 Then ' Add extra blank lines to make up a page before inserting page number For j = NumLines - 1 To MaxLinesPerPage msg = msg & vbCrLf Next j ' Insert Page number at end of page msg = msg & Space$(35) & "Page-" & CStr(PageNo) Printer.Print msg Printer.NewPage ' Send new page. NumLines = 1 ' reset Number of lines, counting this current line PageNo = PageNo + 1 ' Increment Page number msg = Title ' Reset Msg to contain Title for new page ' Append this current line, ignoring character "'" msg = msg & Margin & Mid(theList.List(i), 2) & vbCrLf Else ' Blank page so far - so just appending this line, ignoring character "'" msg = msg & Margin & Mid(theList.List(i), 2) & vbCrLf End If Else ' Normal line - just keep appending it to Msg msg = msg + Margin & theList.List(i) & vbCrLf End If theList.Selected(i) = False ' Clear highlight of selected line, ie. deselect it If NumLines > MaxLinesPerPage Then ' Start new page if page already full If PageNo > 1 Then ' Insert page number at the bottom, except for first page

99

msg = msg + vbCrLf & Space$(35) & "Page-" & CStr(PageNo) End If Printer.Print msg ' Output all data of this page Printer.NewPage ' Send new page. NumLines = 0 PageNo = PageNo + 1 msg = Title End If End If Next i End If ' Get here after going thru all lines in the listbox If NumLines > 0 Then ' complete the last page by inserting page number For i = NumLines To MaxLinesPerPage msg = msg & vbCrLf Next i If PageNo > 1 Then msg = msg + vbCrLf & Space$(35) & "Page-" & Str$(PageNo) End If Printer.Print msg ' Output all data of this page End If If HasSome Then Printer.EndDoc ' Initiate the actual Print. Else Beep MsgBox "Nothing to print, try selecting a range of lines first" End If Screen.MousePointer = vbDefault ' Change mousepointer shape back to normal End Sub Ta g i PrintList ñ in nh ng Items ñã ñư c selected trong Listbox lstNames như sau: Private Sub CmdPrint_Click() PrintList lstHexadecimal, True, "*** EVENT LOG IN HEX ***" End Sub

Thêm Horizontal Scrollbar vào Listbox
Có l b n ñ ý th y c hai Listboxes lstASCII và lstHexadecimal ñ u có Horizontal Scrollbar phía dư i. By default, Listbox không có Horizontal Scrollbar. Mu n t o ra nó b n ph i thêm hai câu dư i ñây vào m t Basic module: Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long Global Const LB_SETHORIZONTALEXTENT = &H194

100

K ñó trong Sub Form_Load g i Function SendMessage qua Application Programming Interface (API) ñ yêu c u Listbox cho hi n ra Horizontal Scrollbar. Dim VLong As Long ' make a horizontal scrollbar for both Listboxes VLong = SendMessage(lstAscii.hwnd, LB_SETHORIZONTALEXTENT, lstAscii.Width, ByVal 0) VLong = SendMessage(lstHexadecimal.hwnd, LB_SETHORIZONTALEXTENT, lstHexadecimal.Width, ByVal 0) B n có th download source code c a program Eventlog.zip n y ñ có ñ y ñ . Trong bài t i ta s h c thêm các áp d ng còn l i c a ListBox. Listbox

Search trong Text File
Ta bi t r ng ListBox có th ch a r t nhi u hàng text (con s hàng t i ña là 65535). Ta ñã quen v i vi c hi n th content c a m t text file trong m t Listbox. Ta ñã dùng ListBox ñ display các Events (s c ) xãy ra trong real-time. Gi d , ta ghi l i t t c m i Events xãy ra trong real-time c a m t h th ng an ninh, t c là ta bi t ai ra, vào c a nào, lúc m y gi . Các Events n y v a ñu c log xu ng m t Text file, v a ñư c cho vào m t ListBox ñ luôn luôn hi n th Event m i nh t cu i ListBox. Khi ñã có m i Events n m trong ListBox, ta có th Search (tìm ki m) xem m t ngư i nào ñã ñi qua nh ng c a nào c a building b ng cách iterate qua t ng hàng trong ListBox và nh n di n m t Text Pattern hàng v i Function InStr. Trong bài m u dư i ñây, ta ñánh tên c a m t ngư i vào trong TextBox r i click nút Find và sau ñó Find Next ñ highlight nh ng Events trong ListBox cho th y nh ng lúc tên ngư i ñó xu t hi n. Trong khi tìm ki m m t Text Pattern ta có th cho phép c ch Hoa , l n ch Thư ng b ng cách covert m i text ra Uppercase trư c khi làm vi c v i chúng.

101

Listing c a Sub Find_Click như sau: Private Sub CmdFind_Click() Dim i, ALine, FText ' Get out if the Listbox is empty If EventList.ListCount = 0 Then MsgBox "There 's no text available" Exit Sub End If ' Check if user has entered the Text Pattern If Trim(txtFind) = "" Then MsgBox "Please enter the Text Pattern to search for" Exit Sub End If ' Clear all selected lines For i = 0 To EventList.ListCount - 1 EventList.Selected(i) = False Next ' Convert the Text Pattern to Uppercase FText = UCase(txtFind.Text) ' Iterate through every line in the ListBox For i = 0 To EventList.ListCount - 1 ' Convert this line to Uppercase ALine = UCase(EventList.List(i)) ' If pattern exists in this line then highlight it If InStr(ALine, FText) > 0 Then EventList.Selected(i) = True ' Highlight the line ' Mark Current line as the Starting line for FindNext operation If i < EventList.ListCount - 1 Then CurrentLine = i + 1 ' get out Exit Sub End If Next ' Only get here if Not found MsgBox "Not found!" End Sub Trong bài n y ta có dùng m t DriveListBox ñ cho User ch n m t Disk drive, m t DirListBox ñ user ch n m t Folder/Directory và m t FileListBox ñ hi n th tên c a nh ng Files trong m t Folder. C ba lo i ListBoxes n y liên k t nhau ñ cho ta th y s thay ñ i ăn nh p m i khi User ñ i t Disk Drive n y qua Disk Drive khác, hay t Folder n y qua Folder khác. Các hàng codes th c hi n vi c n y r t ñơn gi n như sau: Private Sub Drive1_Change()

102

' Make Path of Folder same as new Drive Dir1.Path = Drive1.Drive End Sub Private Sub Dir1_Change() ' Make Path of FileList same as new Path of Folder ' The filenames in the Folder will be displayed automatically in FileListBox FileList.Path = Dir1.Path End Sub

Ta có th ch n l a ch nh ng Filenames có m t Extension nào ó (thí d nh log) b ng cách cho Property Pattern c a FileListBox value "*.log". M i khi User click lên tên c a m t File, program s load content c a File y vào ListBox EventList bên ph i. Sau khi selected m t s hàng r i, User có th ho c Print chúng ra b ng cách Click nút Print, ho c Copy chúng vào Clipboard b ng cách Click nút Copy. Dùng ItemData
N u Property List c a ListBox ñư c xem như m t Text Array thì ItemData là m t Number Array, và List1.ItemData(i) ñi c p v i List1.List(i). T c là trong khi List1.List(i) hi n th như m t trư c c a m t t m b n thì List1.ItemData(i) ñư c coi như n m m t sau c a t m b n y. Khi m t List item thay ñ i v trí trong Listbox vì có s bi n ñ i trong ListBox (thí d Items b removed hay ñư c cho thêm vào) thì ItemData c a List item ñó cũng ñi theo v i nó. Ta th xem thí d sau. Cho vào m t Sorted Listbox tên c a các nhân viên trong s . Ngay sau khi tên m t nhân viên ñư c cho vào Listbox thì Property NewIndex ch a v trí c a item m i ñư c cho vào y trong ListBox. Ta dùng giá tr NewIndex ñ assign ItemData v i S nhân viên ID. Khi User clicks lên m t tên trong Listbox, program s hi n th c S nhân viên ID l n tên nhân viên. Ð th thí d n y, b n có th Paste ph n code dư i ñây vào ph n Declaration c a m t Form có ch a m t Listbox và m t Label. Nh set property Sorted c a List1 ra True.

Private Sub Form_Load() ' Fill List1 and ItemData array with ' corresponding items in sorted order. List1.AddItem "John Green" ' Add an employee name ' Use NewIndex to synchronise with Employee ID ' Assign Employee ID to ItemData of the List Item

103

List1.ItemData(List1.NewIndex) = 62310 List1.AddItem "Tran The Tam" List1.ItemData(List1.NewIndex) = 42859 List1.AddItem "Alan Bradshaw" List1.ItemData(List1.NewIndex) = 63732 List1.AddItem "Peter Costello" List1.ItemData(List1.NewIndex) = 34127 End Sub Private Sub List1_Click() ' Fetch the employee number Msg = List1.ItemData(List1.ListIndex) & " " ' Concatenate it with the employee name. Msg = Msg & List1.List(List1.ListIndex) ' Assign string to Label to display Label1.Caption = Msg End Sub

Dùng ListBox làm Queue
Khi ñi coi hát, ta thư ng ph i ñ ng s p hàng ñ mua vé. Cái hàng ñó g i là Queue. M c ñích c a vi c dùng Queue là ñ cho s ngư i ñông c n m t d ch v s ñư c ph c v l n lư t theo th t ai ñ n trư c s ñư c gi i quy t trư c. Nguyên t c c a Queue như th ñư c g i là First-In-First-Out ( vào trư c nh t, ra trư c nh t). Ngư c l i, n u ai cũng mu n ñư c ph c v trư c nh t ta s có s náo lo n, và r t cu c có th ch ng có ai ñư c gi i quy t. Thí d ta có m t Form tên frmServer, mà trong ñó có m t Listbox tên List1. N u có nhi u Forms khác trong cùng m t chương trình mu n nh frmServer ph c v m t chuy n gì, chúng s Queue b ng cách Add m t Item vào cu i List1. Trong Item có ch a nh ng chi ti t mà frmServer s c n bi t ñ ph c v . Private Sub CmdAddToQueue_Click() Dim myRequest As String Dim PersonId As String * 5 Dim PersonName As String * 20 ' Assign PersonId to fixed length text PersonId = txtPersonId.Text ' Assign PersonName to fixed length text PersonName = txtPersonName.Text ' Concatenate Id and Name myRequest = PersonId & PersonName ' Queue the request frmServer.List1.AddItem myRequest End Sub Bên frmServer, c m i 3 giây nó s Remove Item trên h t ( t c là Index=0) trong List1 và x lý Item y. Trong bài n y ta ch Remove Item 0 r i Add nó vào List2.

104

Private Sub Timer1_Timer() Dim Item If List1.ListCount > 0 Then ' Look at the item at the head of the queue Item = List1.List(0) ' Process Item - just add it to List2 here List2.AddItem Item ' Remove item from queue List1.RemoveItem 0 End If End Sub

CheckBox Listbox
N u b n ch n value c a Property Style c a Listbox là CheckBox thay vì Standard thì m i items trong Listbox s có m t h p vuông phía trư c ñ User có th ch n lúc ch y program. H p vuông c a item nào ñư c checked (ñánh d u) thì Item y ñư c Selected. Gi s ta có m t Listbox List1 v i Style Checkbox và có nhi u Items ñ mua trong siêu th . Khi ch y progarm user ch n m t s items r i click nút Process, program s hi n th các item ñã ñư c ch n. Listing c a Sub CmdProcess_Click như sau: Private Sub CmdProcess_Click() Dim Mess As String ' get out if there's nothing in the list If List1.ListCount = 0 Then Exit Sub ' Iterate through every item of the checkBox Listbox For i = 0 To List1.ListCount - 1 ' If item is selected then include it in the shopping list If List1.Selected(i) Then ' Append Item and a Carriage Return-LineFeed Mess = Mess & List1.List(i) & vbCrLf End If Next

105

' Display shopping list MsgBox Mess, vbInformation, "Selected Shopping Items" End Sub

Listbox v i nhi u c t
Listbox có m t Property g i là Columns. Bình thư ng, Property Columns có giá tr 0. Nhưng n u b n cho nó b ng 3 ch ng h n, thì Listbox s c g ng hi n th 4 c t trong ph m vi chi u ngang c a Listbox. N u như th v n không ñ hi n th h t m i Items trong Listbox thì s có m t Horizontal Scrollbar hi n ra, và khi b n click nó qua bên ph i Listbox s cho hi n th thêm các columns còn l i.

Combobox Combobox r t gi ng như Listbox. Nó là t p h p c a m t Textbox n m phía trên ñ User cho vào data và m t Listbox ch a các items mà User có th l a ch n khi m nó ra. Combo box cũng có nh ng methods như Clear, AddItem và RemoveItem. Tuy nhiên, Combobox không có Property Selected, vì khi User ch n Item nào thì Item y ñư c hi n th trong Textbox phía trên. Combobox có 3 styles. Drop-down Combo Style là thông d ng nh t. Nó cho User nhi m ý ho c ch n m t Item t List ho c ñánh data vào Textbox. Trong hình dư i ñây User ñánh vào ch Elephant thay vì ch n t các Items có s n.

106

Drop-down List b t bu c User ph i ch n m t trong nh ng Item n m trong List, ch không ñư c ñánh data m i vào Textbox. Ngay c trong lúc ch y program (at run-time) b n cũng không th Assign m t value vào property Text c a Combobox lo i n y. Nhưng b n có th làm cho Combobox hi n th Item th 3 ch ng h n b ng cách set property ListIndex c a Combo b ng 2

Chương Tám - T

t o Object

T trư c ñ n gi , ta l p trình VB6 b ng cách thi t k các Forms r i vi t codes ñ x lý các Events c a nh ng controls trên Form khi Users click m t Button hay Listbox, .v.v.. Nói chung, cách y cũng h u hi u ñ tri n khai, nhưng n u ta có th hư ng ñư c các l i ích sau ñây thì càng t t hơn n a: 1. 2. 3. 4. Dùng l i ñư c code ñã vi t trư c ñây trong m t d án khác D nh n di n ñư c m t l i (error) phát xu t t ñâu D tri n khai m t d án l n b ng cách phân ph i ra thành nhi u d án nh D b o trì

M i l n dùng l i code, n u ñ y nguyên xi con là lý tư ng. Vi c y ñư c g i là Reusability. Nói cho ñúng ra, dùng l i ñư c th t s là khi ta ch c n dùng object code, ñó là code ñã ñư c compiled r i, t c là hoàn toàn không ñ ng ñ n source code. Vì h cho phép User s a source code là t o cơ h i cho bugs xu t hi n, r i l i ph i debug m t l n n a. S thách ñ chính c a vi c tri n khai m t d án ph n m m l n là th c hi n ñúng th i h n (on time), không l tài khóa (within budget) và d b o trì (ease of maintenance). Mu n ñ t ñư c các m c tiêu y, ta ph i tri n khai nhanh và làm sao cho chương trình ít có bugs, d b o trì. Gi d b n ñ ng ra t ch c m t ñám cư i. Th tư ng tư ng bi t bao nhiêu chuy n ph i làm: t danh sách quan khách, thi p m i, m th c, xe c , ch p hình, quay phim, văn ngh cho ñ n th t c nghi l , ti p tân, ho t náo viên ..v.v.. N u ch m t mình b n lo th t không bi t làm sao nh cho h t. Cũng may là nhà hàng s ñ m trách luôn c vi c in n thi p m i, ban nh c văn ngh và c ho t náo viên. Th t c nghi l thì không ai qua ñư c bác Sáu ð t, và bác ñã nh n l i mua quà cáp, lo v ti p tân, xe c và th t c, nghi l . Bác cũng s liên l c v i M c sư ch l ñ d n ch nhà th và s p ñ t ng ơi gi t chuông và ngư i ñàn. Anh Tư Thông có ngư i b n làm ch ti m hình, nên anh nh n trách nhi m mư n ngư i lo ch p hình, quay phim. Như th vi c b n t ch c cái ñám cư i nay rút l i ch còn so n danh sách quan khách, các bài di n văn, s p ch ng i và d n ch cho c p v ch ng m i ñi hư ng tu n trăng m t. S dĩ b n c m th y trách nhi m t ch c không n ng n vì nhà hàng, bác Sáu ð t và anh Tư Thông t lo gánh vác các khâu r c r i. Cái hay ñây là nh ng ngư i n y t lo quy t ñ nh m i chi ti t c a nh ng gì c n ph i làm trong khâu c a h . Ch khi nào c n l m, h m i liên l c ñ l y ý ki n c a b n. H gi ng như nh ng ngư i th u c a b n. Ch c b n ñã lưu ý r ng cái thí d t ch c ñám cư i n y cho th y nói chung mu n tri n khai d án l n nào ta c n ph i nh nh ng ngư i th u giúp ñ . Qu th t, ñó là cách các qu n tr viên nh ng công trình ñã làm t xưa ñ n nay. Bây gi tr l i chuy n l p trình, ph i chi ta có th t ch c cách tri n khai d án ph n m m gi ng như t ch c cái ñám cư i nói trên thì t t quá. Th t ra, không ph i các lý thuy t gia ph n m m không nghĩ

107

ñ n chuy n y trư c ñây, nhưng ñ th c hi n ñư c vi c y ngư i ta c n tri n khai các phương ti n, d ng c thích h p. Ch trong vòng 15 năm tr l i ñây, vi c y m i tr nên c th qua các Operating Systems tinh vi, nh t là dùng Windows, và các ngôn ng l p trình như Eiffel, SmallTalk, C++ .v.v.. L p trình theo hư ng ñ i tư ng (Object Oriented Programming) Nói m t cách nôm na, l p trình theo hư ng ñ i tư ng là thi t k các b ph n ph n m m c a chương trình, g i là Objects sao cho m i b ph n có th t lo li u công tác c a nó gi ng như m t ngư i th u ngoài ñ i v y. Ch c có l b n s h i th thì các Sub hay Function mà b n ñã t ng vi t ñ x lý t ng giai ño n trong chương trình có th ñ m trách vai trò c a m t th u không? Ngư i th u ch ng nh ng có th làm ñư c công tác (Subs và Functions) gì mà còn ch u trách nhi m luôn c m i th v t d ng c n thi t (data) cho vi c y n a. Có m t cách ñ nh nghĩa khác cho Object là m t Object g m có data structure và các Subs/Functions làm vi c trên các data y. Thông thư ng, khi ta dùng Objects ít khi giám th chúng, ngư c l i n u khi có s c gì thì ta mu n chúng báo cáo cho ta bi t. Trong VB6, các Forms, Controls hay ActiveX là nh ng Objects mà ta v n dùng lâu nay. L y thí d như Listbox. M t Listbox t qu n lý các items hi n th bên trong nó. Ta bi t listbox List1 ñang có bao nhiêu items b ng cách h i List1.ListCount. Ta bi t item nào v a m i ñư c selected b ng cách h i List1.ListIndex. Ta thêm m t item vào listbox b ng cách g i method AddItem c a List1, ..v.v.. Nói cho ñúng ra, Object là m t th c th c a m t Class. N u Listbox là m t Class thì List1, List2 là các th c th c a Listbox. Cũng gi ng như Bà Tư Cháo Lòng và Dì Sáu Bánh T m là các th c th c a Class ð u B p. Ngay c m t form tên frmMyForm mà ta vi t trong VB6 ch ng h n, nó cũng là m t Class. Thư ng thư ng ta dùng th ng frmMyForm như sau: frmMyForm.Show Trong trư ng h p n y th t ra frmMyForm tuy là m t Class nhưng ñư c dùng y như m t Object. Ch n u mu n, ta có th t o ra hai, ba Objects c a Class frmMyForm cùng m t lúc như trong thí d sau:

Dim firstForm As frmMyForm Dim secondForm As frmMyForm Set firstForm = New frmMyForm Set secondForm = New frmMyForm firstForm.Show secondForm.Show Trong thí d trên ta declare firstForm và secondForm là nh ng Objects c a Class frmMyForm. Sau ñó ta làm nên (instantiate) các Objects firstForm và secondForm b ng statements Set... = New... firstForm và secondForm còn ñư c g i là các instances c a Class frmMyForm. Class gi ng như cái khuôn, còn Objects gi ng như nh ng cái bánh làm t khuôn y. Ch c b n ñã ñ ý th y trong VB6 t dùng hai t Class và Object l n l n nhau. ð u n y cũng không quan tr ng, mi n là b n n m v ng ý nghĩa c a chúng.

108

VB6 có y m tr Class mà ta có th tri n khai và instantiate các Objects c a nó khi dùng. M t Class trong VB6 có ch a data riêng c a nó, có nh ng Subs và Functions mà ta có th g i. Ngoài ra Class còn có th Raise Events, t c là báo cho ta bi t khi chuy n gì xãy ra bên trong nó. Cũng gi ng như Event Click c a CommandButton, khi User clicks lên button thì nó Raise Event Click ñ cho ta x lý trong Sub myCommandButton_Click(), ch ng h n. Classtrong VB6 không có h tr Visual components, t c là không có ch a nh ng controls như TextBox, Label .v.v.. Tuy nhiên, ta có th l y nh ng control có s n t bên ngoài r i ñưa cho Object c a Class dùng. Bây gi chúng ta hãy b t ñ u vi t m t Class. B n hãy m m t Project m i lo i Standard EXE Visual Basic. Sau ñó dùng Menu Command ch n Add Class Module:

Khi Add Class Module dialog hi n ra ch n Class Module và click Open.

B n s th y m ra m t khung tr ng và Project Explorer v i Properties Window. Trong Properties Window, hãy s a Name property c a Class thành clsBox như dư i ñây:

109

K ñó ñánh vào nh ng dòng code dư i ñây, trong ñó có bi u di n cách dùng Class clsBox. Option Explicit Private mX As Integer Private mY As Integer Private mWidth As Integer Private mHeight As Integer Public Property Let X(ByVal vValue As Integer) mX = vValue End Property Public Property Get X() As Integer X = mX End Property Public Property Let Y(ByVal vValue As Integer) mY = vValue End Property Public Property Get Y() As Integer Y = mY End Property Public Property Let Width(ByVal vValue As Integer) mWidth = vValue

110

End Property Public Property Get Width() As Integer Width = mWidth End Property Public Property Let Height(ByVal vValue As Integer) mHeight = vValue End Property Public Property Get Height() As Integer Height = mHeight End Property Public Sub DrawBox(Canvas As Object) Canvas.Line (mX, mY)-(mX + mWidth, mY + mHeight), , B End Sub Public Sub ClearBox(Canvas As Object) Canvas.Line (mX, mY)-(mX + mWidth, mY + mHeight), Canvas.BackColor, B End Sub Class clsBox có 4 Properties: X, Y, Width và Height. Ta s instantiate m t Box t clsBox. M i Box có t a ñ (X,Y) và kích thư c chi u r ng và chi u cao (width, height) c a nó. Th t ra ta có th dùng Public statement ñ declare các bi n X, Y, Width và Height. Nhưng ñây ta c ý declare chúng là Private, dư i d ng mX, mY, mWidth và mHeight. Khi ta mu n thay ñ i các tr s c a chúng, ta s dùng cùng m t cách vi t code như bình thư ng (thí d : myBox.X = 80 ). Nhưng khi chương trình x lý assignment statement y, nó s execute m t lo i method (gi ng như Sub) g i là Property Let X (vValue). Ta th y ñây vValue ñư c assigned cho mX (i.e. mX = vValue ), cái Private variable c a X. Như th công vi c n y cũng ch ng khác gì s a ñ i m t Public variable X. Tuy nhiên, ñây ta có th vi t thêm code trong Property Let X ñ nó làm gì cũng ñư c. B n có nh trong khi thi t k m t Label, m i l n b n dùng Property Window ñ edit Font size, forcolor hay backcolor thì ch ng nh ng các properties y c a Label thay ñ i, mà k t qu c a s thay ñ i ñư c có hi u l c ngay l p t c, nghĩa là Label ñư c hi n th tr l i v i tr s m i c a property. ðó là vì trong method Property có c code b o Label redisplay.

111

Ngư c l i, khi ta dùng property X c a Object myBox, không ph i ta ch ñ c tr s thôi mà còn execute c cái method Property Get X. Nói tóm l i, Property cho ta cơ h i ñ execute m t method m i khi User ñ c hay vi t tr s variable y. Thí d như n u ta mu n ki m soát ñ ch ch p nh n tr s t a ñ X m i khi nó không ph i là s âm. Ta s s a Property Let X l i như sau: Public Property Let X(ByVal vValue As Integer) If (vValue >= 0) Then mX = vValue End If End Property Property có th là Read Only hay Write Only. N u mu n m t Property là Read Only thì ta không cung c p Property Let. N u mu n m t Property là Write Only thì ta không cung c p Property Get. Ngoài ra n u làm vi c v i Object, thay vì Data type thông thư ng, thì ta ph i dùng Property Set, thay vì Property Let. Thí d ta cho clsBox m t Property m i, g i là Font dùng object c a class stdFont c a VB6. Trong clsBox ta declare m t Private variable mFont và vi t m t Property Set Font như sau:

Private mFont As StdFont Public Property Set Font(ByVal newFont As StdFont) Set mFont = newFont End Property Ta s dùng property Font c a myBox (thu c Class clsBox) như sau: ' Declare an object of Class StdFont of VB6 Dim myFont As StdFont Set myFont = New StdFont myFont.Name = "Arial" myFont.Bold = True Dim myBox As clsBox Set myBox = New clsBox Set myBox.Font = myFont ' Call the Property Set method Class clsBox có hai Public Subs, DrawBox và ClearBox. ClearBox cũng v m t box như DrawBox, nhưng nó dùng BackColor c a màn nh (canvas), nên coi như xóa cái box có s n. Do ñó, n u mu n, b n có th s a Sub DrawBox l i m t chút ñ nh n m t Optional draw color như sau:

112

Public Sub DrawBox(Canvas As Object, Optional fColor As Long) If IsMissing(fColor) Then Canvas.Line (mX, mY)-(mX + mWidth, mY + mHeight), , B Else Canvas.Line (mX, mY)-(mX + mWidth, mY + mHeight), fColor, B End If End Sub Trong thí d trên, Optional parameter fColor ñư c tested b ng function IsMissing. N u fColor là BackColor c a canvas thì ta s có hi u qu c a ClearBox. Trong form chính c a chương trình dùng ñ test clsBox, m i khi ta refer ñ n m t object thu c class clsBox, IDE Intellisense s hi n th các Properties và Subs/Functions c a clsBox như trong hình dư i ñây:

Trong chương trình n y, m i khi ta click nút Draw thì m t Box ñư c instantiate, cho t a ñ X,Y và kích thư c Width, Height, r i ñư c v ra ngay trên form. Ch Me trong code nói ñ n chính cái form frmClass.

113

ð cho chương trình thú v hơn, khi user clicks nút Animate, ta s cho m t box màu ñ ch y t trái qua ph i. Khi user clicks nút Two Boxes ta s v hai boxes, h p trong màu xanh, h p ngoài màu ñ , và cho chúng ch y t trái sang ph i. ñây ta bi u di n cho th y mình mu n instantiate bao nhiêu boxes t clsBox cũng ñư c, và dĩ nhiên m i box có m t b properties v i giá tr riêng c a nó.

Ta có th l p trình ñ cho Object báo cáo program ch c a nó khi có m t bi n c (Event) xãy ra bên trong Class. Ta th declare m t Event tên Draw trong clsBox, và vi t code ñ m i khi Sub DrawBox executes thì Class s Raise m t event Draw. Public Event Draw(X As Integer, Y As Integer) Public Sub DrawBox(Canvas As Object, Optional fColor As Long) If IsMissing(fColor) Then Canvas.Line (mX, mY)-(mX + mWidth, mY + mHeight), , B Else

114

Canvas.Line (mX, mY)-(mX + mWidth, mY + mHeight), fColor, B End If RaiseEvent Draw(mX, mY) End Sub

Bây gi , trong frmClass thay vì ch declare Dim myBox as clsBox, ta s declare Private WithEvents myBox as clsBox. Ngay sau ñó, ch myBox s hi n ra trong danh sách các Object có h tr Event c a frmClass. K ñó ta s vi t code ñ handle Event Draw c a myBox, t c là ta cung c p code cho Private Sub myBox_Draw (X as Integer, Y as Integer). ñây ta ch hi n th m t s ñi p báo cáo m t h p v a ñư c v ñâu.

Khi ch y program, m i l n m t clsBox object executes Sub DrawBox ta s th y frmClass display m t message gi ng như dư i ñây.

115

Nh r ng, ta declare m t Object v i WithEvents khi ta mu n handle các Events c a nó. Trong thí d trên frmClass là ch c a myBox và nó handles Event Draw c a myBox. Tương t như v y, ngay c bên trong m t Class, n u Class y ñư c giao cho m t Object có th Raise Events (thí d như TextBox, ListBox, Timer .v.v..), b n cũng có th declare Object y WithEvents ñ nó có th handle Events c a Object. Trong thí d dư i ñây ta vi t codes n y trong m t Class ñã ñư c giao cho m t Textbox khi form chính g i Sub InitObject ñ ñưa cho Object m t TextBox: Private WithEvents mTextBox As TextBox Public Sub InitObject(givenTextBox As TextBox) Set mTextBox = givenTextBox End Sub Private Sub mTextBox_KeyPress(KeyAscii As Integer) ' Place your code here to handle this event within the Class Object End Sub

Chương Chín - Debug
Bugs là nh ng l i l m c a program mà ta phát hi n khi ch y nó. Debug là công vi c lo i t t c nh ng l i l m trong chương trình ñ nó ch y êm xuôi trong m i hoàn c nh. Thông thư ng mu n fix m t cái bug nào trư c h t ta ph i tìm hi u lý do khi n nó xu t hi n. M t khi ñã bi t ñư c duyên c r i ta s nghĩ ra cách gi i quy t. Nói chung, có hai lo i bugs: 1. Ho c là program không làm ñúng chuy n c n ph i làm vì programmer hi u l m Specifications hay ñư c cho tin t c sai l c, ho c là program b sót chi ti t c n ph i có. Trư ng h p n y ta gi i quy t b ng cách gi m thi u s hi u l m qua s nâng c p kh năng truy n thông. 2. Program không th c hi n ñúng như ý programmer mu n. T c là programmer mu n m t ñàng mà b o chương trình làm m t ngã vì vô tình không vi t l p trình ñúng cách. Trư ng h p n y ta gi i quy t b ng cách dùng nh ng Software Tools (k c ngôn ng l p trình) thích h p, và có nh ng quá trình làm vi c có h th ng.

116

Trong hãng xe hơi ngư i ta dùng t Quality Control ñ nói ñ n vi c ch ra chi c xe không có l i l m gì c . ð ñ t m c tiêu y, ch ng nh ng c n có ngư i ki m ph m mà chính các nhân viên l p ráp th n tr ng ñ công vi c chính c a ngư i ki m ph m là xác nh n k t qu t t ch không ph i tìm l i l m. Có nhi u y u t nh hư ng ñ n ch t lư ng c a m t program như ch c năng c a program, c u trúc c a các b ph n, k thu t l p trình và phương pháp debug. Debug không h n n m giai ño n cu i c a d án mà tùy thu c r t nhi u vào các y u t k trư c trong m i giai ño n tri n khai. Ch c năng c a chương trình (Program Specifications) D u program l n hay nh , trư c h t ta ph i xác nh n rõ ràng và t m nó c n ph i làm gì, bao nhiêu ngư i dùng, m ng như th nào, database l n bao nhiêu, ph i ch y nhanh ñ n m c nào .v.v.. Có nhi u chương trình ph i b thay ñ i n a ch ng vì programmers hi u l m ñi u khách hàng mu n. Kh nh t là lúc g n giao hàng m i khám phá ra có nhi u ñi m trong chương trình khách mu n m t ñàng mà ta làm m t ngã. Do ñó trong s liên h v i khách hàng ta c n ph i h i ñi, h i l i, ph n h i v i khách hàng nhi u l n ñi u ta hi u b ng thư t , tài li u, ñ khách xác nh n là ta bi t ñúng ý h trư c khi xúc ti n vi c thi t k chương trình. N u sau n y khách ñ i ý, ñó là quy n c a h , nhưng h ph i tr ti n thay ñ i (variation). C u trúc các b ph n Program nào cũng có m t ki n trúc tương t như m t căn nhà. M i b ph n càng ñơn gi n càng t t và cách ráp các b ph n ph i như th nào ñ ta d th . Trong khi thi t k ta ph i bi t trư c nh ng y u ñi m c a m i b ph n n m ñâu ñ ta chu n b cách th chúng. Ta s không h tin b ph n nào hoàn h o cho ñ n khi ñã th nó, dù nó ñơn sơ ñ n ñâu. N u ta mu n dùng m t k thu t gì trong m t hoàn c nh nào mà ta không bi t ch c nó ch y không thì nên th riêng r nó trư c. Phương pháp y ñư c g i là Prototype. Ngoài ra, ta cũng nên k ho ch cho nh ng trư ng h p b t ng , ñi n hình là bad data - khi user b m lung tung hay database ch a rác r n. N u chương trình ch y trong real-time (t c là data thu nh p qua Serial Comm Port, Data Acquisition Card hay m ng), b n c n ph i lưu ý nh ng trư ng h p khác nhau tùy theo vi c gì x y ra trư c, vi c gì x y ra sau. Lúc b y gi Logic c a chương trình s tùy thu c vào tr ng thái (State) c a data. T t nh t là nghĩ ñ n nh ng Scenarios (di n ti n c a nh ng hoàn c nh) ñ có th th t ng giai ño n và tình hu ng. Ngày nay v i k thu t ð i Tư ng, giai ño n thi t k n y là lúc quy t ñ nh các Data Structures (tables, records ..v.v.) và con s Forms v i Classes. Nh r ng m i Class g m có m t Data Structure và nh ng Subs/Functions/Properties làm vi c (operate) trên data y. Data structure ph i ch a ñ y ñ nh ng chi ti t (data fields, variables) ta c n. K ñó là nh ng cách chương trình process data. Subs/Functions nào có th cho bên ngoài g i thì ta cho nó Public, còn nh ng Subs/Functions khác hi n h u ñ ph c v bên trong class thì ta cho nó Private. K thu t l p trình Căn b n c a programmers và các thói quen c a h r t quan tr ng. Nói chung, nh ng ngư i h p t p, nh y vào vi t chương trình trư c khi suy nghĩ hay cân nh c chính ch n thì sau n y bugs lòi ra kh p nơi là chuy n t nhiên. Dùng Subs và Functions

117

N u giai ño n thi t k ki n trúc c a chương trình ta chia ra t ng Class, thì khi l p trình ta l i thi t k chi ti t v Subs, Functions .v.v.., m i th s c n ph i th như th nào. N u ta có th chia công vi c ra t ng giai ño n thì m i giai ño n có th mà m t call ñ n m t Sub. Th gì c n ph i tính ra hay l y t nơi khác thì có th ñư c th c hi n b ng m t Function. Thí d như công vi c trong m t ti m gi t i có th g m có các bư c sau: 1. 2. 3. 4. 5. 6. 7. 8. Nh n hàng Phân chia t ng lo i T y Gi t i Vô bao Tính ti n Giao hàng

Trong ñó các bư c 1,2,6 và 8 có th là nh ng Subs. Còn các bư c 3,4,5 và 7 nh ng Functions, thí d như khi ta giao cho Function Gi t m t cái áo dơ ta s l y l i m t cái áo s ch. Nh r ng ñi m khác bi t chính gi a m t Sub và m t Function là Function cho ta m t k t qu mà không làm thay ñ i nh ng parameters ta ñưa cho nó. Trong khi ñó, d u r ng Sub không cho ta gì m t cách rõ ràng nhưng nó có th thay ñ i tr s (value) c a b t c parameters nào ta pass cho nó ByRef. Nh c l i là khi ta pass m t parameter ByVal cho m t Sub thì gi ng như ta ñưa m t copy (b n sao) c a variable ñó cho Sub, Sub có th s a ñ i nó nhưng nó s b b qua, không nh hư ng gì ñ n original (b n chính) variable. Ngư c l i khi ta pass m t parameter ByRef cho m t Sub thì gi ng như ta ñưa b n chính c a variable cho Sub ñ nó có th s a ñ i v y. Do ñó ñ tránh trư ng h p vô tình làm cho tr s m t variable b thay ñ i vì ta dùng nó trong m t Sub/Function b n nên dùng ByVal khi pass nó như m t parameter vào m t Sub/Function. Th t ra, b n có th dùng ByRef cho m t parameter pass vào m t Function. Trong trư ng h p ñó dĩ nhiên variable y có th b s a ñ i. ði u n y g i là ph n ng ph (side effect), vì bình thư ng ít ai làm v y. Do ñó, n u b n th t s mu n vư t ngoài qui ư c thông thư ng thì nên Comment rõ ràng ñ c nh cáo ngư i s ñ c chương trình b n sau n y. Ngoài ra, m i programmer thư ng có m t Source Code Library c a nh ng Subs/Functions ưng ý. B n nên dùng các Subs/Functions trong Library c a b n càng nhi u càng t t, vì chúng ñã ñư c th nghi m r i. ð ng s Error M i khi chương trình có m t Error, ho c là Compilation Error (vì ta vi t code không ñúng văn ph m, ng v ng), ho c là Error trong khi ch y chương trình, thì b n không nên s nó. Hãy bình tĩnh ñ c cái Error Message ñ xem nó mu n nói gì. N u không hi u ngay thì ñ c ñi ñ c l i vài l n và suy nghi m xem có tìm ñư c mách nư c nào không. Ngh programming c a chúng ta s g p Errors như ăn cơm b a, nên b n ph i t p bình tĩnh ñ i di n v i chúng. Dùng Comment (Chú thích) Lúc vi t code nh thêm Comment ñ y ñ ñ b t c khi nào tr l i ñ c ño n code y trong tương lai b n không c n ph i d a vào tài li u nào khác mà có th hi u ngay l p t c m c ñích c a m t Sub/Function hay ño n code.

118

Như th không nh t thi t b n ph i vi t r t nhi u Comment nhưng h có ñi m nào khác thư ng, bí hi m thì b n c n thông báo và gi i thích t i sao b n làm cách y. Có th sau n y ta khám phá ra ño n code có bugs; lúc ñ c l i có th ta s th y d u r ng ý ñ nh và thi t k ñúng nhưng cách l p trình có ph n thi u soát ch ng h n. Tính ra trung bình m t programmer ch làm vi c 18 tháng m i ch . T c là, g n như ch c ch n code b n vi t s ñư c ngư i khác ñ c và b o trì ( debug và thêm b t). Do ñó, code ph i càng ñơn gi n, d hi u càng t t. ð ng lo ng i là chương trình s ch y ch m hay chi m nhi u b nh , vì ngày nay computer ch y r t nhanh và b nh r t r . Khi nào ta th t s c n ph i quan tâm v v n t c và b nh thì ñi u ñó c n ñư c thi t k c n th n ch không ph i d a vào nh ng ti u x o v l p trình. ð t tên các variables có ý nghĩa Kh nh t là làm vi c v i các variables có tên v n t t như K, L, AA, XY. Ta không có m t chút ý ni m chúng là ai, hi n h u ñ làm gì. Thay vào ñó, n u ta ñ t các tên variables như NumberOfItems, PricePerUnit, Discount .v.v.. thì s d hi u hơn. M t trong nh ng bugs khó th y nh t là ta dùng cùng m t tên cho local variable (variable declared trong Sub/Function) và global variable (variable declared trong Form hay Basic Module). Local variable s che ñ y global variable cùng tên, nên n u b n mu n nói ñ n global variable trong hoàn c nh y b n s dùng l m local variable. Dùng Option Explicit B n nên trung tín dùng Option Explicit ñ u m i Form, Class hay Module. N u có variable nào ñánh v n tr t VB6 IDE s cho b n bi t ngay. N u b n không dùng Option Explicit, m t variable ñánh v n tr t ñư c xem như m t variable m i v i giá tr 0 hay "" (empty string). Nói chung b n nên th n tr ng khi assign m t data type cho m t variable v i data type khác. B n ph i bi t rõ b n ñang làm gì ñ kh i b ph n ng ph (side effect). Desk Check Ki m l i code trư c khi compile. Khi ta compile code, n u không có error ch có nghĩa là Syntax c a code ñúng, không có nghĩa là logic ñúng. Do ñó ta c n ph i bi t ch c là code ta vi t s làm ñúng ñi u ta mu n b ng cách ñ c l i code trư c khi compile nó l n ñ u tiên. Công vi c n y g i là Desk Check (Ki m trên bàn). M t chương trình ñư c Desk Checked k s c n ít debug và ch a ít bugs không ng trư c. Lý do là m i scenarios ñã ñư c tiên li u chu ñáo. So n m t Test Plan Test Plan li t kê t t c nh ng gì ta mu n th và cách th chúng. Khi th theo Test Plan ta s khám phá ra nh ng bug và tìm cách lo i chúng ra. H sơ ghi l i l ch s c a Test Plan (tr c tr c gì x y ra, b n ñã dùng bi n pháp nào ñ gi i quy t) s b ích trên nhi u phương di n. Ta s h c ñư c t kinh nghi m Debug và bi t rõ nh ng th gì trong d án ñã ñư c th theo cách nào. X lý Error lúc Run time

Khi EXE c a m t chương trình vi t b ng VB6 ñang ch y, n u g p Error, nó s hi n th m t Error Dialog cho bi t lý do v n t c. Sau khi b n click OK, chương trình s ngưng. N u b n ch y chương trình trong VB6 IDE, b n có d p b o program ng ng trong source code ch có Error b ng cách b m button Debug trong Error Dialog. Ti p theo ñó b n có th tìm hi u tr s các variables ñ ñoán nguyên do c a Error. Do ñó, n u b n b t ñ u cho dùng m t program b n vi t trong s , n u ti n thì trong vài

119

tu n ñ u, thay gì ch y EXE c a chương trình, b n ch y source code trong VB6 IDE. N u có bug nào x y ra, b n có th cho program ng ng trong source code ñ debug. Khi b n dùng statement: On Error Resume Next thì t ch ñó tr ñi, n u chương trình g p Error, nó s b qua (ignore) hoàn toàn. ði m n y ti n ch giúp chương trình EXE c a ta tránh b té cái ch r i bi n m t, r t là "quê" v i khách hàng. Nhưng nó cũng b t l i là khi khách hàng cho hay h g p nh ng trư ng h p l , không gi i thích ñư c (vì Error b ignored mà không ai ñ ý), thì ta cũng bí luôn, có th không bi t b t ñ u t ñâu ñ debug. Do ñó, dĩ nhiên trong lúc debug ta không nên dùng nó, nhưng trư c khi giao cho khách hàng b n nên cân nh c k trư c khi dùng. Dùng Breakpoints Cách hay nh t ñ theo dõi execution c a program là dùng Breakpoint ñ làm cho program ng ng l i m t ch ta mu n trong code, r i sau ñó ta cho program bư c t ng bư c. Trong d p n y ta s xem xét tr s c a nh ng variables ñ coi chúng có ñúng như d ñ nh không. B n ñoán trư c execution s ñi qua ch nào trong code, ch n m t ch thích h p r i click bên trái c a hàng code, ch d u ch m tròn ñ như trong hình dư i ñây:

N u b n click lên d u ch m tròn ñ m t l n n a thì là h y b nó. M t cách khác ñ ñ t m t breakpoint là ñ editor cursor lên hàng code r i b m F9. N u b n b m F9 l n n a khi cursor n m trên hàng ñó thì là h y b break point. Lúc program ñang d ng l i, b n có th xem tr s c a m t variable b ng cách ñ cursor lên trên variable y, tooltip s hiên ra như trong hình dư i ñây:

Có m t s chuy n khác b n có th làm trong lúc n y. B n có th n m d u ch m tròn ñ kéo (drag) nó ngư c lên m t hay nhi u hàng code ñ nó s execute tr l i vài hàng code. B n cho program execute t ng hàng code b ng cách b m F8. Menu command tương ñương v i nó là Debug | Step Into. S có

120

lúc b n không mu n program bư c vào bên trong m t Sub/Function mà mu n vi c execute m t Sub/Function như m t bư c ñơn gi n. Trong trư ng h p ñó, b n dùng Menu command Debug | Step Over hay Shift-F8.

Nh là ñ cho program ch y l i b n b m F5, tương ñương v i Menu command Run | Continue. Có khi b n mu n program ng ng gi a m t For Loop khi Iterator value có m t tr s khá l n. N u ta ñ s n m t breakpoint ñó r i c b m F5 nhi u l n thì hơi b t ti n. Có m t mánh l i là dùng m t IF statement ñ th khi Iterator value có tr s y thì ta ng ng breakpoint t i statement Beep (thay gì statement Print ICounter) như trong hình dư i ñây:

Mu n h y b m i breakpoints b n dùng Menu command Debug | Clear All Breakpoints. ð ti n vi c debug, b n có th dùng Debug Toolbar b ng cách hi n th nó v i Menu command View | Toolbars | Debug

VB6 IDE s hi n th Debug Toolbar như sau:

121

Dùng Immediate Window Immediate Window cho phép ta execute nh ng VB statement strong khi program ñang d ng l i. Ta có th dùng m t Print statement ñ hi n th tr s c a m t variable hay k t qu c a m t Function, g i m t Sub hay thay ñ i tr s m t variable trư c khi ti p t c cho chương trình ch y l i. ð hi n th Immediate Window, dùng Menu command View | Immediate Window.

Thay vì ñánh "Print ICounter" b n cũng có th ñánh "? ICounter". Nh là m i VB Statement b n ñánh trong Immediate Window s ñư c executed ngay khi b n b m Enter. B n có th dùng l i b t c VB statement nào trong Immediate Window, ch c n b m Enter cu i hàng y. Theo d u chân chương trình (Tracing) ðôi khi không ti n ñ ng ng program nhưng b n v n mu n bi t program ñang làm gì trong m t Sub. B n có th ñ gi a code c a m t Sub/Function m t statement gi ng như dư i ñây: Debug.Print Format ( Now,"hh:mm:ss ") & "(Sub ProcessInput) Current Status:" & Status ñ program hi n th trong Immediate Window value c a Status khi nó execute bên trong Sub ProcessInput lúc m y gi . Có m t cách khác là thay vì cho hi n th trong Immediate Window b n cho vi t xu ng (Log) vào trong m t text file. Dư i ñây là m t Sub ñi n hình b n có th dùng ñ Log m t Event message: Sub LogEvent(ByVal GivenFileName, ByVal Msg As String, HasFolder As Boolean, IncludeTimeDate As Integer) ' Append event message Msg to a text Logfile GivenFileName ' If GivenFileName is fullPathName then HasFolder is true

122

' IncludeTimeDate = 0 : No Time or Date ' = 1 : Prefix with Time ' = 2 : Prefix with Time and Date Dim FileNo, LogFileName, theFolder If HasFolder Then LogFileName = GivenFileName Else If Right(App.Path, 1) <> "\" Then theFolder = App.Path & "\" Else theFolder = App.Path End If LogFileName = theFolder & GivenFileName End If FileNo = FreeFile If Dir(LogFileName) <> "" Then Open LogFileName For Append As FileNo Else Open LogFileName For Output As FileNo End If Select Case IncludeTimeDate Case 0 ' No Time or Date Print #FileNo, Msg Case 1 ' Time only Print #FileNo, Format(Now, "hh:nn:ss ") & Msg Case 2 ' Date & Time Print #FileNo, Format(Now, "dd/mm/yyyy hh:nn:ss ") & Msg End Select Close FileNo End Sub Dùng Watch Window ðôi khi b n mu n program ng ng không ph i m t ch nào nh t ñ nh, nhưng khi tr s c a m t variable hay c a m t expression là bao nhiêu, có th là b n không bi t t i sao m t variable t nhiên có m t tr s như v y. Câu h i: Ai là th ph m? . Thí d b n mu n program ng ng l i khi ICounter = 15. B n có th dùng Menu command Debug | Add Watch. VB6 IDE s hi n th dialog dư i ñây. B n ñánh ICounter = 15 vào textbox Expression và click option box Break When Value Is True trong h p Watch Type. Làm như v y có nghĩa là ta mu n program ng ng khi ICounter b ng 15.

123

Dùng Phương Pháp Tri t Khai (Elimination Method) Có m t phương pháp r t thông d ng khi debug là Comment Out nh ng hàng code nghi ng ñ xem bug có bi n m t không. Nó ñư c g i là Elimination Method. N u bug bi n m t thì nh ng hàng code ñã ñư c comment out là th ph m. B n có th Comment Out m t s hàng cùng m t lúc b ng cách highlight các hàng y r i click Comment Block trên Edit ToolBar.

Khi dùng Elimination Method b n ph i cân nh c Logic c a code b n trong khi quy t ñ nh Comment Out nh ng hàng nào, n u không, ñó là m t phương pháp khá nguy hi m. Ngoài ra, Menu Command View | Locals Window li t kê cho b n tr s c a t t c variables trong m t Sub/Function và View | Call Stack li t kê th b c các Sub g i l n lư t t ngoài vào trong cho ñ n v trí code ñang ng ng hi n th i.

Chương Mư i - Dùng Menu
Menu trong Windows là nơi t t c các commands c a m t program ñư c s p x p th t theo t ng lo i ñ giúp ta dùng d dàng. Có hai lo i menu ta thư ng g p: drop-down (th xu ng) menu và pop-up (hi n lên) menu. Ta dùng drop-down menu làm Menu chánh cho chương trình. Thông thư ng nó n m phía trên chóp màn nh. N m d c theo chi u ngang là Menu Bar, n u ta click lên m t command trong Menu Bar thì program s th xu ng m t menu v i nh ng MenuItems n m d c theo chi u th ng ñ ng. N u ta click lên

124

MenuItem nào có d u hình tam giác nh bên ph i thì program s popup m t Menu như trong hình dư i ñây (khi ta click Format | Make Same Size):

Main Menu Ta dùng Menu Editor ñ t o ho c s a m t Menu cho program. Menu thu c v m t Form. Do ñó, trư c h t ta select m t Form ñ làm vi c v i Designer c a nó (ch không ph i code c a Form). K ñó ta dùng Menu Command Tools | Menu Editor hay click lên icon c a Menu Editor trên Toolbar ñ làm cho Menu Editor hi n ra.

ð u tiên có m t v t màu xanh n m trong khung tr ng c a Menu Editor, nơi s hi n th Caption c a Menu Command ñ u tiên c a Form. Khi ta ñánh ch &File vào Textbox Caption, nó cũng hi n ra trên v t xanh nói trên. K ñó, b n có th ñánh tên c a Menu Command vào Textbox Name. Dù ta cho Menu Command m t tên nhưng ta ít khi dùng nó, tr trư ng h p mu n nó visible/invisible (hi n ra/bi n m t). Bình thư ng ta dùng tên c a MenuItems nhi u hơn.

125

ð có m t Menu như trong hình dư i ñây ta còn ph i edit thêm vào các MenuItems Open, Save, Close và Exit.

Hình dư i ñây cho th y t t c các MenuItems c a Menu Command File ñ u n m th t qua bên ph i v i b n d u ch m (....) phía trư c. Khi ta click d u tên ch qua ph i thì MenuItem ta ñang Edit s có thêm b n d u ch m, t c là th t m t b c trong Menu (Nested).

126

Tương t như v y, khi ta click d u tên ch qua trái thì MenuItem ta ñang Edit s m t b n d u ch m, t c là tr i m t b c trong Menu. N u mu n cho User dùng Alt key ñ x d ng Menu, b n ñánh thêm d u & trư c character b n mu n trong menu Caption. Thí d Alt-F s th xu ng Menu c a Menu Command File. N u b n ñ t cho MenuItem &Open tên mnuOpen, thì khi b n Click lên Caption nó trên Form trong lúc thi t k , VB6 IDE s hi n th cái v c a Sub mnuOpen_Click(), gi ng như Sub cmdButton_Click() c a m t CommandButton: Private Sub mnuOpen_Click() MsgBox "You clicked mnuOpen" End Sub Trong thí d trên ta ñánh thêm m t Statement ñ hi n th m t message ñơn gi n "You clicked mnuOpen". B n có th ñ t cho m t MenuItem tên gì cũng ñư c, nhưng ngư i ta thư ng dùng prefix mnu ñ d phân bi t m t menuItem Event v i m t CommandButton Event. Do ñó, ta có nh ng tên mnuFile, mnuOpen, mnuSave, mnuClose, mnuExit. Cái g ch ngang gi a MenuItems Close và Exit ñư c g i là Menu Separator. B n có th nhét m t Menu Separator b ng cách cho Caption nó b ng d u tr ( - ). Ngoài Alt key ta còn có th cho User dùng Shortcut c a menuItem. ð cho MenuItem m t Shortcut,

127

b n ch n cho nó m t Shortcut t ComboBox Shortcut trong Menu Editor. Trong hình dư i ñây ta ch n Ctrl+O cho mnuOpen.

By default, menuItem ñư c Enabled và Visible. Lúc thi t k b n có th cho MenuItem giá tr kh i ñ u c a Enabled và Visible b ng cách dùng Checkboxes Enabled và Visible. Trong khi ch y program (at runtime), b n cũng có th thay ñ i các values Enabled và Visible như sau: mnuSave.Enabled = False mnuOpen.Visible = False Khi m t MenuItem có Enabled=False thì nó b m và user không dùng ñư c. B n dùng các d u mũi tên ch lên và xu ng ñ di chuy n MenuItem ñã ñư c selected lên và xu ng trong danh sách các MenuItems. B n dùng button Delete ñ h y b MenuItem ñã ñư c selected, Insert ñ nhét m t MenuItem m i ngay trên MenuItem ñã ñư c selected và Next ñ ch n MenuItem ngay dư i MenuItem ñã ñư c selected.

128

Pop-up Menu ð i v i User, ñang khi làm vi c v i m t Object trong Windows ti n nh t là ta có th làm hi n th Context Menu (Menu áp d ng cho ñúng tình hu ng) b ng m t Mouse click. Thông thư ng ñó là Right Click và cái Context Menu còn ñư c g i là Pop-up Menu. Chính cái Pop-Up menu th t ra là Drop-down menu c a m t Menu Bar Command. Bình thư ng Menu Bar Command y có th visible hay invisible (tàn hình). Trong hình dư i ñây, khi User Right click trên Form, mnuEdit s hi n lên. N u bình thư ng b n không mu n cho User dùng nó trong Main Menu thì b n cho nó invisible:

Code làm cho Popup menu hi n lên ñư c vi t trong Event Mousedown c a m t Object mà tình c ñây là c a chính cái Form:

129

Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single) ' Popup the Edit Menu if User clicked the Right Button of the Mouse If Button = vbRightButton Then PopupMenu mnuEdit End If End Sub Ngay c khi b n mu n cho mnuEdit bình thư ng là invisible, b n cũng nên ñ cho nó visible trong lúc ñ u ñ ti n b code vào dùng ñ x lý Click Events c a nh ng MenuItems thu c v mnuEdit như mnuCopy, mnuCut và mnuPaste.

Ch a menu Settings trong Registry Gi t program b n cho User m t Option WordWrap như dư i ñây:

B n mu n Program nh Option mà User ñã ch n, ñ l n t i khi User kh i ñ ng program thì Option WordWrap còn gi nguyên giá tr như cũ. Cách ti n nh t là ch a value c a Option WordWrap như m t Key trong Registry. Registry là m t lo i cơ s d li u ñ c bi t c a Windows Operating System dùng ñ ch a nh ng d ki n liên h ñ n Users, Hardware, Configurations, ActiveX Components ..v.v. dùng trong computer. Trong Registry, data ñư c s p ñ t theo t ng lo i theo ñ ng c p. B n có th Edit tr c ti p tr s các Keys trong Registry b ng cách dùng Registry Editor.

130

Trong program n y ta cũng nhân ti n b t program nh luôn v trí c a Form khi program ng ng l i, ñ l n t i khi User kh i ñ ng program thì program s có v trí lúc ñ u gi ng y như trư c. Ta s dùng Sub SaveSetting ñ ch a Checked value c a mnuWordWrap và Left, Top c a Form. Code y ta s ñ trong Sub Form_QueryUnload vì nó s ñư c executed trư c khi Form Unload. Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer) SaveSettings End Sub Private Sub SaveSettings() ' Save Location of the form SaveSetting App.Title, "Location", "Left", Me.Left SaveSetting App.Title, "Location", "Top", Me.Top ' Save the setting of WordWrap in menu SaveSetting App.Title, "Settings", "WordWrap", mnuWordWrap.Checked End Sub App.Title là T a ñ c a program. Thông thư ng nó là tên c a VB Project, nhưng b n có th s a nó trong Project Property Dialog (Tab Make) :

131

Khi ch a value c a m t th gì (ta g i là Key) vào Registry b n có th s p ñ t cho nó n m trong Section nào tùy ý. ñây ta ñ t ra hai Sections tên Location ñ ch a Top,Left c a Form và tên Settings ñ ch a Key mnuWordWrap.Checked. Mu n cho program có các giá tr c a Keys ch a trong Registry khi nó kh i ñ ng ta ch c n dùng Function GetSetting trong Sub Form_Load ñ ñ c vào t Registry như dư i ñây: Private Sub Form_Load() ' Initialise Location of the form by reading the Settings from the Registry Me.Left = Val(GetSetting(App.Title, "Location", "Left", "0")) Me.Top = Val(GetSetting(App.Title, "Location", "Top", "0")) ' Initialise setting of WordWrap in the menu mnuWordWrap.Checked = ( GetSetting(App.Title, "Settings", "WordWrap", "False") = "True" ) End Sub Lúc ñ u khi chưa có gì trong Registry thì "0" (string "0" ñư c converted b i Val ra 0) là default value cho Left và Top, còn "False" là default value c a mnuWordWrap.Checked. Ngoài ra ta cũng mu n program nh tên c a ba Files User dùng g n ñây nh t. T c là trong Drop-down c a Menu Command File s có MenuItem Recent Files ñ hi n th t m t ñ n ba tên Files, cái m i nh t n m trên h t. Trư c h t, ta c n t o ra 3 SubmenuItem có cùng tên mnuRFile nhưng mang Index b ng 0,1 và 2 (b n ñánh vào Textbox Index). Ta s dùng Captions c a chúng ñ hi n th tên các Files.

132

Lúc chưa có Filename nào c thì MenuItem Recent Files s b làm m ñi (t c là mnuRecentFiles.Enabled = False ). Ta s ch a tên các Files như m t String trong Section Settings c a Registry. Ta phân cách tên các Files b ng delimiter character |. Thí d : "LattestFileName.txt|OldFileName.txt|OldestFilename.txt" M i l n User Open m t File ta s thêm tên File y vào trong Registry và b t c lúc nào ch gi l i tên c a 3 Files m i dùng nh t.

Dư i ñây là code dùng ñ thêm tên File m i dùng nh t vào Registry: Private Sub mnuOpen_Click() ' Initialise Folder in Common Dialog CommonDialog1.InitDir = App.Path ' Launch the dialog CommonDialog1.ShowOpen ' Save the Filename in the Registry, using Object myRecentFiles myRecentFiles.AddFile CommonDialog1.FileName End Sub

Code dùng trong Sub Form_Load ñ ñ c tên RecentFiles và hi n th trong Menu:

' Set myRecentFiles = New clsRecentFiles ' Pass the form handle to it ' This effectively loads the most recently used FileNames to menu

133

myRecentFiles.Init Me

Ta s dùng m t Class tên clsRecentFiles ñ ñ c bi t lo vi c ch a tên Files vào Registry và hi n th tên các Files y trong Menu. Bên trong clsRecentFiles ta cũng dùng clsString, là m t Class giúp ta ng t khúc String trong Registry ra tên c a các Files d a vào ch các delimiter character |. ' Author: Le Duc Hong http://www.vovisoft.com ' Class Name: clsRecentFiles ' This Class saves the most Recent FileNames used in the Registry in form of ' a String delimited by |. ' Up to MaxFiles Filenames maybe stored. ' You need to pass the Form that contains the menu to it. ' The assumption is that you have created an array of MenuItems named mnuRFile ' to display the FileNames ' Const MaxFiles = 3 ' Maximum number of FileNames to remember Private myForm As Form Private RecentFiles As clsString Public Sub Init(TForm As frmMenu) Set myForm = TForm Set RecentFiles = New clsString ' Read the Most Recent Filename String from the Registry RecentFiles.Text = GetSetting(App.Title, "Settings", "RecentFiles", "") ' Assign the Delimiter character and tokennise the String (i.e. split it) into FileNames RecentFiles.Delimiter = "|" UpdateMenu End Sub

134

Public Sub AddFile(FileName As String) ' Add the latest FileName to the list and update the Registry ' Prefix the FileName to the existing MostRecentFileName String RecentFiles.Text = FileName & "|" & RecentFiles.Text ' Discard the oldest FileNames if the total number is greater than MaxFiles If RecentFiles.TokenCount > MaxFiles Then Dim TStr As String Dim i As Integer ' Reconstitute the String that contains only the most recent MaxFiles FileNames For i = 1 To MaxFiles TStr = TStr & RecentFiles.TokenAt(i) & "|" Next ' Remove the last delimiter character on the right RecentFiles.Text = Left(TStr, Len(TStr) - 1) End If ' Update the String in the Registry SaveSetting App.Title, "Settings", "RecentFiles", RecentFiles.Text UpdateMenu End Sub Private Sub UpdateMenu() ' Display the most recent Filenames in the menu Dim i As Integer ' If there is no FileNames to display then disable the MenuItem entry If RecentFiles.TokenCount = 0 Then myForm.mnuRecentFiles.Enabled = False Exit Sub Else ' Otherwise enable the MenuItem entry myForm.mnuRecentFiles.Enabled = True End If ' Assign FileName to Caption of mnuRFile array and make the MenuItem elements visible For i = 1 To RecentFiles.TokenCount myForm.mnuRFile(i - 1).Caption = RecentFiles.TokenAt(i) ' Assign to Caption myForm.mnuRFile(i - 1).Visible = True ' Make the MenuItem visible If i = MaxFiles Then Exit For ' This line maybe unnecessary Next ' Make the rest of the MenuItem array mnuRFile invisible if there are less than MaxFiles If RecentFiles.TokenCount < MaxFiles Then For i = RecentFiles.TokenCount To MaxFiles - 1 myForm.mnuRFile(i).Visible = False

135

Next End If End Sub B n có th ch y Line Command RegEdit sau khi click Start | Run

ñ xem chi ti t c a các Keys mà program ñã ch a trong Sections Location và Settings c a Folder HKEY_CURRENT_USER\Software\VB and VBA Program Settings\Menu

Chương Mư i M t - Dùng Dialogs
Dialogs (giao tho i) ñư c dùng ñ hi n th tin t c và nh n mouse hay keyboard input t users tùy theo tình hu ng. Chúng ñư c dùng ñ t p trung s chú ý c a users vào công tác ñương th i c a program nên r t h u d ng trong các chương trình c a Windows.

136

Có nhi u d ng Dialogs, m i th áp d ng cho m t hoàn c nh riêng bi t. Trong chương n y ta s bàn qua 4 lo i Dialogs chính và nghiên c u v khi nào và cách nào ta dùng chúng: 1. 2. 3. 4. Message Boxes Input Boxes Common Dialogs Custom Dialogs

Message Boxes Message Boxes ñư c dùng ñ nh c nh user m t chuy n gì, và ñòi h i m t ph n ng nào ñó t user. Thí d như khi ta ch m d t program MSWord mà chưa lưu tr h sơ thì MSWord s nh c ta lưu tr nó b ng Dialog dư i ñây:

Trong trư ng h p n y user có th click m t trong 3 buttons. N u click Yes thì s xúc ti n vi c lưu tr h sơ trư c khi k t thúc program MSWord. N u click No thì MSWord s l ng l k t thúc. N u click Cancel thì có nghĩa user ñ i ý vi c ch m d t program và tr l i ti p t c dùng MSWord. Ta dùng routine MsgBox ñ hi n th Message Box như coding trong hình dư i ñây:

Parameter (thông s ) th nh t c a MsgBox là text message Close the program down?, parameter th nhì là t p h p c a icon (vbQuestion) và s buttons (vbOKCancel) b ng cách c ng hai constants: vbQuestion + vbOKCancel (hai buttons OK và Cancel), parameter th ba là title (tiêu ñ ) c a Dialog. Trong thí d MSWord bên trên Constant c a icon và buttons là vbExclamation + vbYesNoCancel

137

(ba buttons Yes, No và Cancel). Ta ch n s và lo i buttons theo b ng dư i ñây:
Constant vbOKOnly vbOKCancel vbYesNo vbRetryCancel vbYesNoCancel vbAbortRetryIgnore Các buttons OK OK Cancel Yes No Retry Cancel Yes No Cancel Abort Retry Ignore

Constant c a các icons ta có th dùng là vbCritical, vbQuestion, vbExclamation và vbInformation. Khi m t Message Box ñư c m ra, c program ng ng l i và ñ i user ph n ng. Ta nói Message Box ñư c hi n th trong Modal Mode, nó dành m i s chú ý và t m ngưng các execution khác trong cùng program. Sau khi user click m t button, Message Box s bi n m t và program s ti p t c ch y t hàng code ngay dư i hàng MsgBox. Trong thí d trên ta dùng MsgBox như m t Sub, nhưng ta cũng có th dùng MsgBox như m t Function ñ bi t user v a m i click button nào. Function MsgBox returns m t value (tr v m t giá tr ) mà ta có th th bi t ñ theo ñó thi hành. Thí d như:

Private Sub CmdPrompt_Click() Dim ReturnValue As Integer ReturnValue = MsgBox("Close the program down", vbQuestion + vbOKCancel, "Exit Program") Select Case ReturnValue Case vbOK MsgBox "You clicked OK" Case vbCancel MsgBox "You clicked Cancel" End Select End Sub Các tr s Visual Basic intrinsic constants mà Function MsgBox returns là:

138

Tr s 1 2 3 4 5 6 7

Tên OK Cancel Abort Retry Ignore Yes No

Const VbOK vbCancel vbAbort vbRetry vbIgnore vbYes VbNo

B n có th hi n th Text message trong Message Box thành nhi u hàng b ng cách dùng Constant vbCrLf (CarriageReturn và LineFeed) ñ ñánh d u nh ng ch ng t khúc như sau:

MsgBox "This is the first line" & vbCrLf & " followed by the second line" N u b n th y mình thư ng dùng MsgBox v i cùng m t icon và nh ng buttons, nhưng có Text message khác nhau, b n có th vi t m t Global Subroutine trong .BAS module ñ dùng l i nhi u l n. Thí d b n có m t Global Sub như sau:

Public Sub DisplayError(ByVal ErrMess As String ) MsgBox ErrMess, vbCritical + vbOKOnly, "Error" End Sub M i l n mu n hi n th m t Error message b n ch c n g i Sub DisplayError v i Text message mà không s dùng l m l n icon. Sau n y mu n ñ i cách hi n th Error message ch c n edit m t ch . N u user mu n b n lưu tr t t c m i errors x y ra lúc run-time, b n ch c n thêm vài hàng code trong Sub DisplayError ñ vi t Error message vào m t text file.

Input Boxes V i Message Boxes, user ch có th click lên m t button. ðôi khi ta mu n user ñánh vào thêm m t ít d ki n, trong trư ng h p y ta có th dùng Input Boxes. Input Boxes gi ng gi ng Message Box, nhưng nó chuyên nh n input data t user và không hi n th m t icon. Thí d :

139

Private Sub CmdGreeting_Click() Dim strReply As String strReply = InputBox$("Please enter your name", "What 's your name?", "John", 2000, 1000) MsgBox "Hi " & strReply & ", it 's great to meet you!", vbOKOnly, "Hello" End Sub ð ý các parameters c a Function InputBox$. Parameter th nh t là Text message, parameter th hai là Title c a Dialog, parameter th ba là Default Input Value. ðây là value ñư c hi n th s n trong Input Box khi nó xu t hi n, n u ñó là input user thư ng ñánh vào thì user ch c n click nút OK là ñ . Hai parameters cu i cùng là Optional (nhi m ý, có cũng ñư c, không có cũng không sao). Nó là X,Y coordinates c a Input Box trong ñơn v twips. H th ng t a ñ l y góc trên bên trái làm chu n v i X=0, Y=0.

Input Box có hai d ng Functions:
• •

InputBox$ - returns m t String ñàng hoàng InputBox - returns m t String n m trong Variant variable N u b n click nút Cancel thì returned Value là empty string, b n có th test empty string ñ nh n di n trư ng h p n y. Dư i ñây là m t thí d dùng Function InputBox: Private Sub CmdFortuneTeller_Click() Dim varValue As Variant Dim intAge As Integer varValue = InputBox("Please enter your age", "How old are you?", "18") If IsNumeric(varValue) Then intAge = Val(varValue) If intAge < 20 Then MsgBox "You are a young and ambitious person", vbOKOnly, "Observation" Else MsgBox "You are a matured and wise person", vbOKOnly, "Observation"

140

End If Else MsgBox "Oh oh! - please type your age!", vbCritical + vbOKOnly, "Input Error" End If End Sub Khi nào nên dùng Input Boxes M c d u Input Boxes r t d dùng, trên th c t r t ít khi ta dùng nó vì nh ng lý do sau ñây:

• •

Ta không th làm gì ñư c trong lúc user input data, ph i ñ i sau khi user click OK thì m i b t ñ u x lý input textstring. Ngư c l i n u ta dùng m t Textbox trong m t Form thông thư ng, ta có th code trong các Event handlers c a Events KeyPress hay Change ñ ki m soát các keystrokes c a user. Input Boxes ch cho ta ñánh vào m t text string duy nh t. Nhi u khi ta mu n user ñánh vào nhi u th nên c n ph i có m t form riêng. Sau cùng, Input Boxes xem không ñ p m t. Program dùng Input Boxes có v như không chuyên nghi p, do ñó ta c n ph i dùng Custom Dialogs. Common Dialogs B n có ñ ý th y h u như m i programs trong Windows ñ u có cùng nh ng dialogs ñ Open và Save files ? Và h u như t t c programs ñ u có cùng dialogs ñ ch n màu, font ch hay ñ in ? ðó là vì các Dialogs thông d ng y thu c v Common Dialog Library c a MSWindows và cho phép các program g i. Mu n dùng các Dialogs y trong VB6 ta ph i reference Comdlg32.ocx b ng IDE Menu command Project | Components... r i ch n và Apply Microsoft Common Dialog Control 6.0.

Microsoft Common Dialog Control 6.0 cho ta sáu d ng Dialogs tùy theo g i Method nào:

141

Tên Open File Save File Color Font Print Help

Method ShowOpen ShowSave ShowColor ShowFont ShowPrinter ShowHelp

Open và Save File Dialogs B n hãy m m t Project m i v i m t button tên CmdOpen trong Form1 và ñánh vào code sau ñây cho Sub CmdOpen_Click: Private Sub CmdOpen_Click() On Error GoTo DialogError With CommonDialog1 .CancelError = True ' Generate Error number cdlCancel if user click Cancel .InitDir = "E:\VB6" ' Initial (i.e. default ) Folder .Filter = "Executables (*.exe) | *.exe| Batch Files (*.bat)| *.bat" .FilterIndex = 1 ' Select ""Executables (*.exe) | *.exe" as default .DialogTitle = "Select a program to run" .ShowOpen ' Lauch the Open Dialog MsgBox "You selected " & .FileName, vbOKOnly + vbInformation, "Open Dialog" End With Exit Sub DialogError: If Err.Number = cdlCancel Then MsgBox "You clicked Cancel!", vbOKOnly + vbInformation, "Open Dialog" Exit Sub Else MsgBox "Error in Dialog's use: " & Err.Description, vbOKOnly + vbCritical, "Error" Exit Sub End If End Sub

Hãy ch y program y và click button Open, program s hi n th error message dư i ñây:

142

ðó là vì ta quên b m t Microsoft Common Dialog Control 6.0 vào Form1. V y b n hãy doubleclick icon c a nó trong ToolBox. Bây gi hãy ch y program l i và click button Open ñ hi n th Open Dialog.

B n có th ch n folder nào tùy ý b ng cách di chuy n t folder n y qua folder khác hay thay ñ i disk drive. N u b n click vào bên ph i c a combobox File of type, nó s dropdown ñ cho th y b n có th ch n m t trong hai lo i Files như li t kê trong statement: .Filter = "Executables (*.exe) | *.exe| Batch Files (*.bat)| *.bat"

Sau khi ch n m t Filename có s n hay ñánh m t tên vào File name textbox, b n click Open. Sau ñó, CommonDialog1.Filename s ch a tên file b n ñã ch n hay ñánh vào.

143

Vì ta cho .CancelError = True nên n u user click Cancel program s generate m t Error s 32755 (cdlCancel). ñây ta b t Error y b ng cách dùng On Error GoTo DialogError và th Err.Number= cdlCancel ñ hi n th Error message dư i ñây:

Save Dialog cũng tương t như Open Dialog, ta dùng method ShowSave ñ hi n th nó.

Trong thí d trên ta ñ nh nghĩa các properties c a CommonDialog1 b ng code. B n cũng có th dùng Properties Windows ñ ñ nh nghĩa chúng như dư i ñây:

144

Ngoài ra, b n cũng có th dùng các trang Properties c a CommonDialog1 ñ ñ nh nghĩa Properties lúc thi t k b ng cách right click Commondialog1 trên Form1 r i ch n Properties:

Properties Pages Dialog s hi n th v i Tab Open/Save As có s n lúc ñ u, b n có th ñánh các tin t c như sau:

145

Color Dialog Color Dialog cho user m t cách ch n màu r t d dùng. Ngoài nh ng màu có s n, user có th t t o ra m t màu r i cho nó thêm vào trong b ng màu ñư c cung c p, g i là Windows Palette b ng cách click button Add to Custom Colors.

B n t o ra m t màu b ng cách click ch có màu theo ý trong b ng màu l n hình vuông r i n m hình tam giác bên ph i kéo lên, kéo xu ng ñ thay ñ i ñ ñ m c a màu như hi n th trong h p vuông Color|Solid. Khi v a ý v i màu hi n th , b n click button Add to Custom Colors, màu y s ñư c cho thêm vào nhóm Custom Colors n m phía dư i, bên trái.

146

Ta dùng method ShowColor ñ hi n th Color Dialog. Sau khi user ñã ch n m t màu r i, ta có th tr c ti p assign nó cho property ForeColor hay BackColor c a m t control. Trong thí d dư i ñây cái màu mà user v a ch n ñư c assigned cho background c a picturebox Picture1: Private Sub CmdSelectColor_Click() On Error GoTo NoColorChosen With CommonDialog1 .CancelError = True ' Entire dialog box is displayed, including the Define Custom Colors section .Flags = cdlCCFullOpen .ShowColor ' Launch the Color Dialog Picture1.BackColor = .Color ' Assign selected color to background of Picture1 Exit Sub End With NoColorChosen: ' Get here if user clicks the Cancel button MsgBox "You did not select a color!", vbInformation, "Cancelled" Exit Sub End Sub Font Dialog Font Dialog cho ta ch n Font cho màn nh hay printer và ch n màu ñ dùng cho ch c a Font. Ta dùng method ShowFont ñ hi n th FontDialog. Các chi ti t trình bày trong Font Dialog tùy thu c vào tr s c a Flags như sau:
Constant cdlCFScreenFonts Tr s 1 Hi u qu Ch hi n th các Fonts printer h tr

147

cdlCFPrinterFonts cdlCFBoth cdlCFScalableOnly

2 3 &H20000

Ch hi n th các Fonts c a màn nh, chưa ch c t t c ñ u ñư c printer h tr Hii n th các Fonts màn nh và printer Ch hi n th các scalable Fonts như TrueType fonts mà b n ñã cài vào máy

N u b n mu n cho user nhi m ý ñ ch n màu thì thêm 256 vào tr s c a Flags.

Dư i ñây là code ñ cho user ch n Font và màu c a Label1. Private Sub CmdSelectFont_Click() On Error GoTo NoFontChosen CommonDialog1.CancelError = True ' Causes the dialog box to list only the screen fonts supported by the system. CommonDialog1.Flags = cdlCFScreenFonts + 256 ' Add 256 to include Color option CommonDialog1.ShowFont ' Launch the Font Dialog With Label1.Font .Bold = CommonDialog1.FontBold .Italic = CommonDialog1.FontItalic .Name = CommonDialog1.FontName .Size = CommonDialog1.FontSize .Strikethrough = CommonDialog1.FontStrikethru

148

.Underline = CommonDialog1.FontUnderline End With Label1.ForeColor = CommonDialog1.Color Label1.Caption = "Hello world!!!, this is a Font Dialog Demo" Exit Sub NoFontChosen: MsgBox "No font was chosen!", vbInformation, "Cancelled" Exit Sub End Sub Chú ý: N u b n quên cho Flags m t trong nh ng h ng s nói trên program s cho m t Error message như sau:

Print Dialog Print Font cho ta m t giao di n cũng gi ng như trong Microsoft Office ñ ch n nh ng nhi m ý v vi c in. V i Print Dialog ta có th ch n printer nào v i nh ng ñ c tính nào b ng cách click button Properties hay button Preferences. Ta cũng có th quy t ñ nh in t trang nào ñ n trang nào c a document và in bao nhiêu copies. Ch có ñi u ph i lưu ý là n u user dùng Print Dialog ñ ch n m t Printer khác mà trong Print Dialog ta ñã ch n Property PrinterDefault = True thì Printer y s tr thành Default Printer và nó cũng s có hi u l c vĩnh vi n trong c Windows cho ñ n khi user thay ñ i l i. Khác v i Color và Font Dialogs, Print Dialog không ñòi h i ta ph i cho m t tr s c a Property Flags. Ta ch c n dùng Method ShowPrinter ñ hi n th Print Dialog. Ba properties thư ng ñư c dùng nh t sau khi user ch n các nhi m ý c a Print Dialog là Copies, FromPage và ToPage. ð cho user các default values c a nh ng properties n y, b n có th ñ s n các tr s trư c khi hi n th Print Dialog.

149

Dư i ñây là code m u dùng print Dialog: Private Sub CmdSelectPrinter_Click() With CommonDialog1 .FromPage = 1 .ToPage = 1 .Copies = 1 .ShowPrinter End With End Sub Help Dialog Ta dùng method ShowHelp ñ hi n th các thông tin giúp ñ , nhưng nh ph i cho CommonDialog ít nh t tr s c a các properties HelpFile và HelpCommand. Private Sub CmdHelp_Click() CommonDialog1.HelpFile = "YourProgram.hlp" CommonDialog1.HelpCommand = cdlHelpContents CommonDialog1.ShowHelp End Sub

150

ð bi t thêm chi ti t v cách dùng ShowHelp, highlight ch HelpContext trong source code VB6 r i n phím F1 và ch n MsComDlg.

Custom Dialogs Nhi u khi Message Box, Input Box hay các d ng Common Dialogs v n không thích h p cho hoàn c nh l p trình. Trong trư ng h p y b n có th dùng m t Form bình thư ng ñ làm thành m t Dialog cây nhà, lá vư n. Nó hơi m t công hơn m t chút, nhưng th nh t nó có nh ng màu s c gi ng như các Forms khác trong chương trình, và th hai ta mu n làm gì tùy ý. Ch có cái b t l i là chương trình s dùng nhi u tài nguyên hơn, nói th ng ra là c n thêm m t ít memory. Sau ñây ta th tri n khai m t Login Form t ng quát, có th dùng trong nhi u trư ng h p. Khi kh i ñ ng, program n y s hi n th m t Login form yêu c u user ñánh vào tên và m t kh u. Sau ñó, n u tên và m t kh u h p l thì cái Form chính c a program m i hi n ra. Cách ta th c hi n là cho program kh i ñ ng v i m t Sub Main trong .BAS Module. Sub Main s g i Sub GetUserInfo (cũng n m trong cùng Module) ñ hi n th form frmLogin trong Modal mode ñ nó làm vi c cùng m t cách như Message Box, Input Box hay Common Dialogs. Khi form frmLogin ñư c d u kín b ng statement Me.Hide thì execution trong Sub GetUserInfo s ti p t c ñ chi ti t ñi n vào các textboxes txtUserName và txtPassword ñư c tr v local variables strUserName và strPassword. Mã ngu n c a Sub Main và Sub GetUserInfo ñư c li t ra dư i ñây: Sub Main() Dim strUserName As String Dim strPassword As String ' Call local Sub getUserInfo to obtain UserName and Password GetUserInfo strUserName, strPassword If strUserName = "" Then MsgBox "Login failed or aborted", vbInformation, "login Aborted" Else MsgBox "User " & strUserName & " logged in with password " & strPassword, vbInformation, "Login accepted" ' Check UserName and Password here ' If valid password then show the Main form of the program which is implemented separately... ' frmMain.Show End If End Sub Private Sub GetUserInfo(ByRef sUserName As String, ByRef sPassword As String) ' Invoke frmLogin form in Modal mode frmLogin.Show vbModal ' As soon as frmLogin is hidden, the execution gets here sUserName = frmLogin.txtUserName ' assign the form's txtUserName to sUserName sPassword = frmLogin.txtPassword ' assign the form's txtPassword to sPassword Unload frmLogin ' Unload form frmLogin

151

End Sub Login form ñư c hi n th như dư i ñây:

Sau khi user ñi n chi ti t và click OK, t m th i ta ch hi n th m t thông ñi p ñ xác nh n các chi ti t y.

Trong tương lai, b n có th vi t thêm code ñ ki m tra xem tên và m t kh u có hi u l c không. Có m t vài chi ti t v form frmLogin ñ nó làm vi c gi ng gi ng m t Common Dialog:
• • • • •

Ta cho property BorderStyle c a frmLogin là Fixed Dialog. Ta cho Property PasswordChar c a textbox txtPassword b ng "*" ñ khi user ñi n m t kh u, ta ch th y m t hàng d u hoa th . Ta cho Property StartupPosition c a form là CenterScreen. Property Default c a button cmdOK là True ñ khi user n phím Enter trong form là coi như tương ñương v i click button cmdOK. Tương t như th , Property Cancel c a button cmdCancel là True ñ khi user n phím Esc trong form là coi như tương ñương v i click button cmdCancel. T m th i coding c a event click c a cmdOK và cmdCancel ch ñơn gi n như li t kê dư i ñây: Private Sub CmdCancel_Click() ' Clear txtUserName and txtPassword txtUserName = "" txtPassword = "" ' Hide the Form to get out of Modal mode Me.Hide End Sub Private Sub CmdOK_Click() ' Hide the Form to get out of Modal mode Me.Hide

152

End Sub

Chương Mư i Hai - Dùng ð H a (Ph n I)
T c ng Anh có câu: "M t hình nh ñáng giá m t ngàn ch (a picture is worth a thousand words)", ý nói khi ta dùng hình nh ñ di n t s giúp ngư i xem hi u nhanh hơn khi ta ch có nói thôi. Visual Basic 6 có cho ta m t s phương ti n v ñ h a (graphics) ñ trang ñi m cho các c a s phong phú, thân thi n, d làm vi c v i, và thú v . Dù r ng các phương ti n v ñ th n y không nhanh ñ cho ta vi t nh ng chương trình trò chơi (games) nhưng tương ñ i cũng ñ kh năng ñ ñáp ng các nhu c u c n thi t thông thư ng. Khi nói ñ n ñ h a, ta mu n phân bi t nó v i Text thông thư ng. Thí d ta dùng Notepad ñ edit m t bài thơ trong m t c a s . Trong lúc bài thơ ñang ñư c hi n th ta có th s a ñ i d dàng b ng cách dùng bàn phím ñ ñánh thêm các ch m i vào, dùng các nút Delete, Backspace ñ xóa các ch . ðó là ta làm vi c v i Text. Bây gi , trong khi bài thơ còn ñang hi n th , ta dùng m t chương trình Graphic như PhotoImpact Capture c a ULead ñ ch p cái hình c a s c a bài thơ (active window) thành gi ng như m t photo, thì ta có m t Graphic. Sau ñó, mu n s a ñ i bài thơ t graphic n y ta ph i dùng m t graphic editor như MSPaint, PaintShopPro,.v.v.. Các ch trong hình cũng có cùng d ng graphic như ta th y m t photo, nên mu n edit ph i dùng m t c v i màu sơn. Dư i ñây là graphic c a m t c a s Notepad sau khi ñư c thêm ch g và d u ch m h i cách dùng MSPaint. cu i b ng

Màu (color) và ñ m n (resolution) Ta nói m t t m hình t t vì nó có màu s c s o và rõ ràng. B n có còn nh trong ngày L khai m c Th V n H i Moscow, ngư i ta cho hi n th nhi u hình r t hay b ng cách nh khán gi , trong m t khu hình ch nh t, m i ngư i c m ñưa lên m t t m c t-tông màu. Hàng ngàn t m c t-tông ñưa lên ráp l i thành ra m t hình tuy t ñ p. M t graphic trong Windows cũng g m có nhi u ñóm nh , m i ñóm, ñư c g i là m t pixel, có kh n ng hi n th 16, 256, ... màu khác nhau.

153

ð m n (resolution) Thông thư ng ñ m n (resolution) c a màn nh ta dùng là 800x600, t c là chi u ngang có 800 pixels và chi u cao có 600 pixels. Sau n y, ñ xem các hình rõ hơn ta còn dùng ñ m n 1028x768 v i c t SuperVGA và Monitor t t. Ta nói c t SuperVGA có ñ n 2MB RAM, t i sao ph i c n ñ n 2MB ñ hi n th graphic ñ p? N u màu c a m i pixel ñư c bi u di n b i m t byte d ki n thì v i m t byte ta có th ch a m t con s t 0 ñ n 255. Ngư i ta ñ ng ý v i nhau theo m t quy ư c r ng s 0 tư ng trưng cho màu ñen, s 255 tư ng trưng cho màu tr ng ch ng h n. N u ñ m n c a màn nh là 1024x768 thì ta s c n 1024x768=786432 bytes, t c là g n 0,8 MB. M t byte có 8 bits. ðôi khi ta nghe nói 16 bit color, ý nói thay vì m t byte, ngư i ta dùng ñ n 2 bytes cho m i pixel. Như v y m i pixel n y có kh năng hi n th 216 = 65536 màu khác nhau. Mu n dùng 16 bit color cho SuperVGA, ta c n ph i có 1024x768x2 =1572864 bytes, t c là g n 1,6 MB. ðó là lý do t i sao ta c n 2MB RAM. Lưu ý là RAM c a VGA (Vector Graphic Adapter) card không liên h gì v i RAM c a b nh computer. Không ng các c Ăng-Lê ngày xưa ñã bi t Tin H c nên nói trư c:"M t hình nh ñáng giá m t ngàn ch ". Ch word th i IBM g m có 4 bytes, nên m t màn nh ñáng giá 400 ngàn ch , như v y các c không chính xác l m, nhưng coi như ñúng. Nên nh r ng cùng m t graphic hi n th trên hai màn nh có cùng ñ m n, thí d như 800x600, nhưng kích thư c khác nhau, thí d như 14 inches và 17 inches, thì dĩ nhiên hình trên màn nh 17 inches s l n hơn, nhưng nó v n có cùng m t s pixels, có ñi u pixel c a nó l n hơn pixel c a màn nh 14 inches. Nói m t cách khác, n u ta dùng màn nh l n hơn thì graphic s l n hơn nhưng không có nghĩa là nó rõ hơn. Mu n th y rõ chi ti t, ta ph i làm cho graphic có ñ m n cao hơn. Tr l i câu chuy n Th V n H i Moscow, mu n có hình rõ hơn, thì trong cùng m t di n tích, ta ph i nh bà con ng i xích l i g n nhau ñ kho ng ñ t ch a nhi u ngư i hơn và m i ngư i c m m t t m c t-tông nh hơn. Ta thay ñ i Display Properties c a m t màn nh b ng cách right click lên desktop r i select Properties, k ñó click Tab Settings r i ch n Screen resolution và Color quality gi ng như hình dư i ñây:

154

Khi ta tăng ñ m n c a màn nh, các hình nh s nh l i vì kích thư c c a pixel ñư c thu nh l i. Do ñó, ta có th cho hi n th nhi u th hơn trên desktop. Ph m ch t c a các graphic v n không thay ñ i, m c d u hình nh hơn. Nh là mu n hình rõ hơn thì khi c u t o và ch a graphic, ta ph i dùng m t ñ m n cao. Gi ng như khi ch p hình, mu n hình ñ p ta c n cái máy ch p hình dùng phim l n c a th chuyên nghi p và focus k lư ng, thay vì dùng máy r ti n t ñ ng, ch ñưa lên là b m ch p ñư c. Màu (color) Khi ta dùng ch có m t bit (ch có tr s 0 hay 1) cho m i pixel thì ta ch có tr ng hay ñen. Lúc y ta có th dùng m t byte (8 bits) cho 8 pixels. D u v y, n u ñ m n c a graphic cao ñ , thì hình cũng ñ p. Th xem các tuy t tác photos tr ng ñen c a Cao ðàm, Cao Lĩnh thì bi t. Các máy Fax dùng nguyên t c scan hình gi y c A4 ra thành nh ng pixels tr ng ñen r i g i qua ñư ng dây ñi n tho i qua ñ u kia ñ tái t o l i hình t nh ng d ki n pixels. Visual Basic 6 cho ta ch ñ nh m t con s vào m i màu VB có th hi n th , hay ch n tr c ti p m t màu t Dialog. Có b n cách:

B n ch ñ nh tr c ti p m t con s hay ch n m t màu t cái Palette.

155

B n ch n m t trong các h ng s ñ nh nghĩa s n trong VB, g i là intrinsic color constants (intrinsic có nghĩa nôm na là cây nhà lá vư n hay in-built), ch ng h n như vbRed , vbBlue. Danh sách c a intrinsic color constants l y t VB6 online help ñư c li t kê dư i ñây:

Dùng Function QBColor ñ ch n m t trong 16 màu. Function QBColor xu t phát t th i Quick Basic (QBasic) c a Microsoft. QBsic là ti n thân c a Visual Basic. Trong QBasic b n có th dùng các con s 1,2,3 .. ñ ch ñ nh các màu Blue, Green, Cyan , .v.v..Function QBColor gi n ti n hóa cách dùng màu, user không c n ph i b n tâm v cách tr n ba th màu căn b n Red, Green, Blue. B n vi t code m t cách ñơn gi n như:

Dư i ñây là tr s các màu ta có th dùng v i Function QBColor. Tr s Màu Tr s Màu

156

0 1 2 3 4 5 6 7

Black Blue Green Cyan Red Magenta Yellow White

8 9 10 11 12 13 14 15

Gray Light Blue Light Green Light Cyan Light Red Light Magenta Light Yellow Bright White

Dùng Function RGB ñ tr n ba màu Red, Green và Blue. Trong cái b ng li t kê các intrinsic color constants phía trên, n u ñ ý b n s th y vbWhite(0xFFFFFF) là t ng s c a vbRed(0x0000FF), vbGreen(0x00FF00) và vbBlue(0xFF0000). M t màu ñư c bi u di n b ng s pha tr n c a ba thành ph n màu căn b n, m i màu b ng m t byte có tr s t 0 ñ n 255. 0 là không dùng màu y, 255 là dùng t i ña màu y. H th ng s ta dùng h ng ngày là Th p Phân. Tr s 0xFF c a vbRed là con s 255 vi t dư i d ng Th p l c phân (Hexadecimal hay Hex cho g n và ñây ñư c ñánh d u b ng 0x trư c con s ñ phân bi t v i s Th p phân). Trong h th ng s Hex ta ñ m t 0 ñ n 9 r i A,B,C,D,E,F r i qua s hàng th p l c 10, 11,.., 19, 1A, 1B, ..1E,1F,20,21..v.v. T c là thay vì ch dùng 10 symbols t 0 ñ n 9 trong Th p phân, ta dùng 16 symbols t 0 ñ n F. Mu n bi t thêm v h th ng s Hex hãy ñ c bài Cơ s Nh Phân. Trong hình dư i ñây là m t thí d cho th y màu xanh nh t ñã ñư c ch n g m ba thành ph n Blue(0x990000= 153*256*256), Green(0xCC00= 204*256) và Red(0xFF= 255):

157

Ghi chú: B n có th dùng Windows Calculator ñ hoán chuy n s gi a các d ng Decimal, Binary và Hexadecimal. Ch n View|Scientific thay vì View|Standard.

Function RGB ð áp d ng Function RGB, ta s vi t m t chương trình VB6. B n hãy kh i ñ ng m t chương trình VB6 m i, b vào m t Label tên Label1 v i Caption Red và m t Vertical Scroll tên VScroll1. K ñó select c hai Label1 và VScroll1 r i Copy và Paste hai l n ñ là thêm hai c p. ð i Caption c a hai Label m i n y ra Green và Blue. Bây gi ta có m t Array ba Vertical Scrolls cùng tên VScroll1, v i index là 0,1 và 2. ð t m t PictureBox tên picColor vào bên ph i ba cái VScrolls. Thêm m t Label phía dư i, ñ t tên nó là lblRGBValue, nh clear caption c a nó, ñ ng có ñ ch Label1 như dư i ñây:

158

Bây gi select c ba VScrolls và edit value c a property Max trong c a s Properties thành 255, ý nói khi kéo cái bar c a m t VScroll1 lên xu ng ta gi i h n tr s c a nó t Min là 0 ñ n Max là 255.

Chuy n chính ta ph i làm là vi t code ñ x lý Event Change c a các VScrolls. Vì chúng là m t Array nên ta có th dùng m t Sub duy nh t ñ handle events ñ n t c ba VScrolls. M i lúc m t trong 3 VScrolls thay ñ i tr s ta s tr n ba màu Red, Green, Blue bi u di n b i tr s c a 3 VScrolls thành màu BackColor c a PictureBox picColor. ð ng th i ta cho hi n th tr s c a ba thành ph n màu Red, Green và Blue trong Label lblRGBValue. B n hãy double click lên m t trong 3 VScrolls r i vi t code như sau:

159

Private Sub VScroll1_Change(Index As Integer) ' Use Function RGB to mix 3 colors VScroll1(0) for Red, ' VScroll1(1) for Green and VScroll1(2) for Blue ' and assign the result to BackColor of PictureBox picColor picColor.BackColor = RGB(VScroll1(0).Value, VScroll1(1).Value, VScroll1(2).Value) ' Variable used to prepare display string Dim strRGB As String ' Description of what is displayed strRGB = "picColor.BackColor = RGB(Red, Green, Blue) " & vbCrLf ' Values of Red, Green, Blue in Decimal strRGB = strRGB & " Decimal: " & VScroll1(0).Value & ", " & VScroll1(1).Value & ", " & VScroll1(2).Value & vbCrLf ' Values of Red, Green, Blue in Hexadecimal strRGB = strRGB & " Hex: 0x" & Hex(VScroll1(0).Value) & ", 0x" & Hex(VScroll1(1).Value) & ", 0x" & Hex(VScroll1(2).Value) ' Assign the resultant string to caption of Label lblRGBValue lblRGBValue.Caption = strRGB End Sub B n hãy kh i ñ ng chương trình r i n m các bar c a 3 VScrolls kéo lên, kéo xu ng ñ xem k t qu . C a s c a chương trình s có d ng gi ng như dư i ñây:

Color Mapping N u dùng Hex Calculator ñ i con s 0xFFFFFF ra decimal ta s ñư c 16777215, n u k c s 0 ta s có t ng c ng 16777216 màu. Lúc nãy ta bàn v 8bit (1 byte) và 16bit (2 bytes) color, nhưng ñây ta nói chuy n 3 byte color. Như th có th màn nh không ñ kh năng ñ cung c p m i màu mà

160

Function RGB tính ra. V y VGA card s làm sao? Thí d m t c t VGA ch h tr ñ n 8 bits. Nó s cung c p 256 màu khác nhau. N u Function RGB ñói h i m t màu mà VGA card có th cung c p chính xác thì t t, n u không nó s tìm cách dùng hai hay ba ñóm g n nhau ñ tr n màu và cho ta o tư ng màu ta mu n. Công tác n y ñư c g i là Color Mapping và cái màu ñư c làm ra ñư c g i là custom color. Dùng Intrinsic Color Constants M t trong nh ng features c a MSWindows là cho ta ch n Color Scheme c a Windows theo s thích. Bình thư ng, Color Scheme c a Windows là Blue, nhưng ta có th ch n Olive Green hay Silver, n u ta mu n.

Ch kh n i n u ta ñã dùng m t màu ñ ñ m ñ hi n th tuy t ñ p th gì trong chương trình VB6 mà bây gi user t nhiên thay ñ i Color Scheme thành Olive Green ch ng h n khi n cho màu ñ ñ m y coi ch ng gi ng ai trong cái Color Scheme m i. ð tránh trư ng h p y, thay vì nói th ng ra là màu gì (xanh hay ñ ) ta nói dùng màu vbActiveTitlebar hay vbDesktop, .v.v. Dùng Intrinsic Color Constant s b o ñ m màu ta dùng s ñư c bi n ñ i theo Color Scheme mà user ch n ñ kh i b trư ng h p cái màu tr nên ch ng gi ng ai. Lúc thi t k , ta cũng có th ch n Intrinsic Color Constant t Tab System khi ch n màu.

161

Graphic files Khi m t hình Graphic ñư c lưu tr theo d ng s pixels v i màu c a chúng như ñã nói trên thì ta g i là m t Bit Map và tên file c a nó trong disk có extension BMP thí d như House.bmp. Lưu tr ki u n y c n r t nhi u memory và r t b t ti n ñ g i ñi hay hi n th trên m t trang Web. Do ñó ngư i ta dùng nh ng k thu t ñ gi m thi u lư ng memory c n ñ ch a graphic nhưng v n gi ñư c ch t lư ng c a hình nh. Có hai d ng Graphic files r t thông d ng trên Web, mang tên v i extensions là JPG và GIF. ð c bi t v i GIF files ta có th ch a c ho t h a (animation), t c là m t GIF file có th ch a nhi u hình (g i là Frames) ñ chúng l n lư t thay nhau hi n th , cho ngư i xem có c m tư ng m t v t ñang di ñ ng. In trên màn nh VB6 có method Print cho ta in th ng trên Form, PictureBox hay Printer. Ba lo i control n y ñư c coi như nh ng khung v i mà h a sĩ v lên. B n hãy kh i ñ ng m t chương trình VB6 m i. ð t lên form m t PictureBox tên Picture1 và m t button tên CmdPrintTenLines v i Caption Print Ten Lines. DoubleClick lên button n y và vi t code dư i ñây: Private Sub CmdPrintTenLines_Click() Dim i As Integer ' String variable used for display Dim strLine As String ' Write 10 lines, one under the other For i = 1 To 10 strLine = "This is line " & CStr(i) Me.Print strLine ' Print on Form Picture1.Print strLine ' Print on Picture1 Next End Sub B n hãy ch y th program r i click nút Print Ten Lines. Trong trư ng h p n y ta dùng default Font và Color ñ in 10 hàng. Sau m i Print, chương trình t ñ ng xu ng hàng. K ñó, thêm m t button tên CmdPrintFontSizes v i Caption Print Font Sizes. DoubleClick lên button n y và vi t code dư i ñây:

162

Private Sub CmdPrintFontSizes_Click() Dim i As Integer ' Print numbers 1 to 10, one after the other on the same line For i = 1 To 10 ' Define Font size Me.Font.Size = Me.Font.Size + i ' Define Color using Function QBColor Me.ForeColor = QBColor(i) ' Print without moving to next line. Note the semicolon ";" Me.Print Str(i); Next End Sub Trong Sub CmdPrintFontSizes_Click, ta thay ñ i c ki u ch ñ cho các con s ñư c in ra l n lên d n d n và thay ñ i màu c a các con s b ng cách dùng function QBColor. ð in các con s liên t c không xu ng hàng ta dùng method Print v i semicolon (;). B n hãy ch y chương trình l i. Click nút Print Ten Lines r i click nút Print Font Sizes, k t qu s gi ng như dư i ñây:

Bây gi b n th minimize c a s c a chương trình, k ñó restore nó l i kích thư c cũ. B n s th y các hàng ta in lúc nãy không còn trong form hay PictureBox n a. Lý do là khi ta Print lên form hay PictureBox, các hình y ñư c v trong graphic ñ a phương ch không ñư c VB6 k là m t ph n c a c a s . Mu n tránh tr ng i n y ta ph i d n VB6 nh v l i b ng cách set property AutoRedraw c a form và Picture1 ra True.

163

H th ng t a ñ Khi ñ t m t Object hay v m t cái gì lên màn nh (screen) hay form .v.v.. ta c n ph i ch ñ nh Object y n m ch nào k t (with reference to) cái góc Trên Trái (Top Left) c a màn nh hay form. Cái góc Trên Trái là Trung tâm t a ñ c a screen hay form. ñó t a ñ X và Y ñ u b ng 0, ta vi t là 0,0. N u ta ñi l n qua ph i theo chi u r ng c a screen thì t a ñ X tăng lên. N u ta ñi d c xu ng dư i theo chi u cao c a screen thì t a ñ c a Y tăng lên. K ñ n là ñơn v ño lư ng ta dùng ñ bi u di n kho ng cách. Trong bài trư c ta ñã nói ñ n ñ m n c a màn nh (screen resolution) d a vào pixel. Ta có th dùng ñơn v pixel ñ nói m t Object có t a ñ X và Y m i chi u bao nhiêu pixels tính t trung tâm t a ñ . Như th , ngay c trên cùng m t màn nh khi ta tăng ñ m n nó lên thì m t Object ñã ñư c ñ t lên màn nh theo ñơn v pixel s xích qua trái và lên trên m t ít vì kích thư c m t pixel bây gi nh hơn lúc trư c m t chút. Hình dư i ñây minh h a các kích thư c c a màn nh và Form.

ði m c n bi t là có nh ng ph n như title bar và border c a m t form ta không th v lên ñư c. Do ñó di n tích còn l i c a form ñư c g i là Client Area. Chi u r ng và chi u cao c a Client Area ñư c g i là ScaleWidth và ScaleHeight.

164

N u mu n kho ng cách t m t Object ñ n trung tâm t a ñ , hay kích thư c c a chính Object, không h thay ñ i dù ta có tăng, gi m ñ m n c a màn nh hay in hình ra printer (thí d ta mu n nó luôn luôn dài 5cm ch ng h n) thì ta dùng h th ng t a ñ theo ñơn v twips c a form. Twips là Default Coordinate System c a VB6. Trong h th ng n y m i ñi m là tương ñương v i 1/567 centimeter. Do ñó, n u b n v m t dư ng dài 567 twips nó s hi n th dài 1cm trên màn nh, và khi b n in nó ra, nó cũng dài 1cm trên gi y. T c là ñ dài th t c a Object không tùy thu c vào lo i màn nh (ñ m n cao hay th p) hay printer. Ngư i ta nói nó là Device independent coordinate system (H th ng t a ñ ñ c l p v i d ng c ). Nói m t cách khác Twips cho ta th t s what you see is what you get (WYSIWYG - th y sao có v y), r t thích h p v i Desktop publishing. B n có th thay ñ i h th ng t a ñ c a m t form b ng cách edit property ScaleMode qua c a s Properties như sau:

Ghi chú: Thay ñ i tr s ScaleMode không có hi u l c ngay mà ch nh hư ng nh ng gì ñư c thi t k sau ñó. Gi ng như khi ta Edit Text trong Notepad, Text Cursor (thanh | ch p ch p) là v trí hi n t i, nơi s hi n th cái ch ta ñánh s p t i, trong graphic ta có m t Cursor vô hình, nơi s hi n th cái gì ta s p Print. Ta ch ñ nh v trí c a graphic cursor y b ng cách cho tr s c a CurrentX và CurrentY. B n hãy kh i ñ ng m t d án VB6 m i và vi t code cho Event Resize c a form chính như sau:

165

Th ch y chương trình và Resize form. M i khi b n Resize form, ch X s ñư c d i ñ n v trí kho ng chính gi a c a Client Area c a form.

Dùng Graphics ðã có m t chút căn b n v graphics c a VB6, bây gi ta có th ñ t nh ng graphics lên form. Có hai cách ñ làm chuy n y:
• •

Dùng Graphical Controls: Ta có PictureBox và Image có th ch a hình nh. Trong khi Line và Shape có th v ñư ng th ng hay các hình ch nh t, tròn .v.v.. trên form, lúc thi t k . Dùng Graphics Methods: ðây là nh ng m nh l nh cho ta v tr c ti p lên form lúc run-time. Các m nh l nh VB6 cho ta là Cls, Pset, Point, Line và Circle.

Tùy theo hoàn c nh, b n có th l a ch n cách nào ti n d ng. PictureBox và Image Dùng PictureBox hay Image là cách d nh t ñ hi n th m t graphic trong form. Lúc thi t k , b n có th ñánh th ng tên c a graphic vào property Picture trong c a s Properties. Form cũng nh n property Picture. B n cũng có th click lên bên ph i ch property Picture ñ browse và ch n m t graphic, thư ng là Bitmap hay Icon.

166

S khác bi t chí gi a Image và PictureBox là Image có property Stretch mà ta có th set thành True ñ kéo dãn graphic ra cho chi m tr n di n tích c a Image. Image là m t grapgic control lightweight (nh ký), t c là nó không ñòi h i nhi u memory và ch y nhanh hơn PictureBox. Lý do là PictureBox là m t container, t c là nó có th ch a các controls khác. Ngoài ra, PictureBox cũng cho phép ta v lên trên nó gi ng như trên form. Trong hình dư i ñây, trong lúc thi t k ta ñ t m t PictureBox và m t Image cùng m t c lên cùng m t form. K ñó ta assign cùng m t picture hình happy.bmp cho c hai. Riêng v i Image, ta set property Stretch c a nó ra True.

Ch ñ nh hình nh lúc run-time Trong lúc program ñang ch y, ta có th thay ñ i hình nh ch a trong PictureBox hay Image b ng cách dùng Function LoadPicture. Nh là ta không th assign tr c ti p vào Property Picture c a hai graphical controls n y. Lý do là Property Picture ch là m t cách thân thi n cho ta ch ñ nh m t graphic trong lúc thi t k . Khi m t hình nh ñã ñư c ch ñ nh r i, VB6 ch a c hình y vào file có cùng tên v i file c a form nhưng v i extension .frx. T c là n u tên c a form là Form1 thì graphic c a Property Picture ñư c ch a chung v i các graphics khác c a form trong file Form1.frx. Do ñó, vì VB6 program ch a luôn graphic chung v i nó, ta không c n ph i nh c ñ n tên c a graphic file khi dùng hay deploy, t c là không c n ñính kèm tên graphic file trong Setup file cho ngư i ta

167

install. Dư i ñây là code m u ñ lúc run-time ta load m t graphic tên sad.bmp n m trong Subfolder tên images c a App.path vào Image control tên Image1. Private Sub CmdLoad_Click() Dim LocalDir As String ' Assign Folder where program resides to LocalDir LocalDir = App.Path ' Append right backslash if last character is not "\" If Right(LocalDir, 1) <> "\" Then LocalDir = LocalDir & "\" End If ' Load graphic "sad.bmp" from SubFolder "images" into Image1 Image1.Picture = LoadPicture(LocalDir & "images\sad.bmp") End Sub Dĩ nhiên, n u ta mu n load graphic lúc run-time thì ph i cung c p graphic file riêng. Control Shape Control Shape cho phép b n v nh ng hình ñơn gi n như ñư ng th ng, h p, vòng tròn trên form, lúc thi t k . Sau khi DoubleClick lên control Shape trong Toolbox ñ thêm m t control Shape vào form, b n ch n lo i Shape c a nó t c a s Properties r i n m vào m t góc c a Shape trên form drag l n nh tùy ý. Mu n sơn bên trong m t Shape, b n ch n màu t property FillColor. Property FillColor cũng gi ng như BackColor c a các controls khác, nhưng nó ch có hi u l c khi b n cho property FillStyle m t tr s khác hơn là 1- Transparent (trong su t), thí d như 0- Solid (dày ñ c).

168

Control Line Tương t v i các properties Fill c a Shape, ñ i v i Line b n có các properties BorderColor, BorderStyle và BorderWidth. Border color ch ñ nh màu c a chính ñư ng th ng, BorderStyle ñ cho b n l a ñư ng liên t c hay g ch ch m, và BorderWidth ñ làm cho ñư ng dày to hơn. Các properties n y cũng áp d ng cho chu vi (ñư ng bao quanh) c a các hình ch nh t, tròn .v.v.

Graphics Methods

169

Trong khi các Graphical Controls như Shape, Line cho ta v hình lúc thi t k thì Graphics Methods cho ta v nh ng th y lúc run-time. Ta cũng có th ch m t ng ñóm (pixel) hay copy c m t Picture t ch n y ñ n ch khác. Ch c n m t chút kinh nghi m b n có th làm ho t h a (animation) hay t o visual effects tuy t di u mà không c n ph i ñ ng ñ n Windows API (Application Programming Interface) ñ dùng Function BitBlt. Method PaintPicture Method PaintPicture cho phép b n copy r t nhanh m t kh i d ki n ñ h a, nói nôm na là m t khu v c trong m t hình graphic trên form, PictureBox hay Printer ñ n m t nơi khác. Thí d b n copy m t hình t ch n y ñ n ch khác trong form, hay t form/PictureBox ra Printer Object ñ m t ch c sau b n in nó ra. B n hãy kh i ñ ng m t d án VB6 m i và DoubleClick lên PictureBox Icon trong ToolBox ñ ñ t m t PictureBox lên form. ð t tên PictureBox y là picGraphic và set property Visible c a nó ra False ñ ta không th y nó lúc run-time. Bây gi load m t hình vào property Picture c a picGraphic b ng cách Browse m t Bitmap file t c a s Properties. ñây ta ch n INTL_NO.BMP t folder \Program Files\Microsoft Visual Studio\Common\Graphics\Bitmaps\Assorted

Trong chương trình n y ta mu n h khi ñè nút trái c a Mouse xu ng và di chuy n Mouse cursor thì khi cursor ñi ñ n ñâu, hình INTL_NO ñư c v ñ n ñó. Ta s dùng m t Flag ñ ñánh d u nút-trái-c a-Mouse-Down, ñ t tên là flgMouseDown. Khi nh n ñư c Event MouseDown ta set flgMouseDown thành True, và khi nh n ñư c Event MouseUp ta reset flgMouseDown thành False. M i l n nh n ñư c Event MouseMove thì n u flgMouseDown là True ta s PaintPicture INTL_NO. ð xóa background c a form, ta thêm m t button tên CmdClearForm ñ ch y graphic method Cls. Dư i ñây là li t kê code m u:

170

' Flag that indicates that the Mouse's left button is depressed Dim flgMouseDown As Boolean Private Sub Form_Load() ' Initialise flgMouseDown to False flgMouseDown = False End Sub Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single) ' Set Flag flgMouseDown flgMouseDown = True End Sub Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single) ' Paint picGraphic if flgMouseDown is True If flgMouseDown Then ' Paint full-size picGraphic at Mouse cursor location PaintPicture picGraphic.Picture, X, Y, picGraphic.Width, picGraphic.Height End If End Sub Private Sub Form_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single) ' Reset Flag flgMouseDown flgMouseDown = False End Sub Private Sub CmdClearForm_Click() ' Clear the form Cls End Sub

171

Lưu ý là b n ph i declare variable flgMouseDown bên ngoài các Subs ñ m i Sub ñ u th y và có th dùng nó. Mu n bi t thêm chi ti t v cách dùng method PaintPicture, trong VB6 IDE DoubleClick lên ch PaintPicture trong code editor ñ highlight ch y r i b m nút F1. Method PSet
Ta dùng method PSet (ñ n t ch Point Set) ñ v m t pixel lên form. Ta c n cho bi t PSet v i màu gì, t c là ta cho nó t a ñ X,Y c a pixel và m t màu tính t function RGB. ñâu và

Dư i ñây là code ñ v pixels ñ màu lên form m t cách b t ch ng (randomly) v v trí và màu s c khi user clicks lên form chính: Private Sub Form_Click() Dim i As Integer ' Variables for pixel coordinates Dim iXCoord As Integer Dim iYCoord As Integer ' Variable for primary colours Dim iRed As Integer Dim iGreen As Integer Dim iBlue As Integer ' Start the Random number generation Randomize ' Plot 2000 dots randomly For i = 1 To 2000 ' get a random XCoord. ' Note that Rnd(1) returns a real number between 0 and 1, eg: 0.384 iXCoord = Int(Rnd(1) * ScaleWidth) ' get a random YCoord. iYCoord = Int(Rnd(1) * ScaleHeight)

172

' Get a random number between 0 and 254 for each primary colour iRed = Int(Rnd(1) * 255) iGreen = Int(Rnd(1) * 255) iBlue = Int(Rnd(1) * 255) ' Plot the pixel at iXCoord,iYCoord PSet (iXCoord, iYCoord), RGB(iRed, iGreen, iBlue) Next MsgBox ("All done!") End Sub Trong thí d trên ta dùng method Randomize ñ generate s n trong b nh các con s real b t ch ng t 0 ñ n 0.999. Sau ñó m i l n ta g i Function Rnd(1) là nó s tr v m t con s real l y b t ch ng t b s do method Randomize generated. Do ñó, Rnd(1) * ScaleWidth s cho ta m t con s real có tr s t 0 ñ n ScaleWidth. Mu n ñ i con s real ñó ra Integer, ta dùng Function Int. Khi kh i ñ ng chương trình và Click lên form ta s có hình gi ng như dư i ñây:

Mách nư c: ð xóa m t ñóm b n Pset l i t i ch BackColor c a form. Method Line

y m t ñóm m i có cùng màu v i

Method Line v m t ñư ng th ng t m t t a ñ n y ñ n m t t a ñ khác trong màu do ta ch ñ nh. V i hai methods PSet và Line ta có th làm ñư c r t nhi u chuy n. Thí d mu n cho m t v t di ñ ng, ta xóa v t y b ng cách v l i nó v i cùng màu c a BackColor c a form, r i v v t y v trí m i. Mu n v m t ña giác như tam giác hay ch nh t ta ráp nhi u ñư ng th ng l i v i nhau, ñ u c a m i ñư ng th ng là cu i c a ñư ng th ng v a m i ñư c v trư c. Mu n sơn Shade bên trong m t hình ch nh t ta dùng PSet..v.v.

173

Có ba cách ñ ch ñ nh t a ñ c a hai ñ u c a m t ñư ng th ng ta mu n v : 1. Cho bi t t a ñ c a ñ u và cu i ñư ng th ng: thí d : Line (50, 100)-(3000, 4000) Khi ñư ng n y ñư c v xong thì v trí c a graphic cursor có t a ñ là v trí c a cu i ñư ng, t c là CurrentX=3000 và CurrentY=4000 trong trư ng h p n y. Ch cho bi t t a ñ cu i ñư ng th ng: thí d : Line -(3600, 4500), vbMagenta Trong trư ng h p n y v trí c a graphic cursor (CurrentX, CurrentY) ñư c l y làm t a ñ c a ñ u ñư ng th ng khi v . T c là n u trư c khi execute dòng code n y CurrentX=3000 và CurrentY=4000 thì dòng code tương ñương v i: Line (3000,4000)-(3600,4500), vbMagenta 3. Dùng ch Step ñ nói s khác bi t t CurrentX và CurrentY: thí d : Line Step(400, 600)-Step(800, -500), vbGreen N u trư c khi execute dòng code n y CurrentX=3600 và CurrentY=4500 thì dòng code tương ñương v i: Line (4000,5100)-(4800,4600), vbGreen Trong thí d dư i ñây, m t hình tam giác ñư c v b ng hai cách coding khác nhau. Khi ch y program ñ th , b n hãy l n lư t click Triangle METHOD I và Triangle METHOD II ñ th y c hai cách v ñ u y như nhau, ch khác màu thôi. Private Sub CmdTrianI_Click() ' Drawing a black triangle: METHOD I Line (700, 500)-(2800, 2400) Line (2800, 2400)-(1800, 900) Line (1800, 900)-(700, 500) End Sub Private Sub CmdTrianII_Click() ' Drawing a red triangle: METHOD II ' Draw a red line from Location(700, 500) to Location (2800, 24000) Line (700, 500)-(2800, 2400), vbRed ' Draw a red line from Location(2800,2400) to Location (1800,900) Line -(1800, 900), vbRed ' Draw a red line from Location(1800,900) to Location (700,500) Line -(700, 500), vbRed End Sub ð v m t hình ch nh t, cách ti n nh t là dùng Step như dư i ñây: Private Sub Rectangle(ByVal X1 As Integer, ByVal Y1 As Integer, ByVal X2 As Integer, ByVal Y2 As Integer)

2.

174

' Draw a rectangle Line (X1, Y1)-(X2, Y1) Line -(X2, Y2) Line -(X1, Y2) Line -(X1, Y1) End Sub Ta còn có th v m t hình ch nh t v i b n góc tròn như sau: Private Sub RoundCornerRectangle(ByVal X1 As Integer, ByVal Y1 As Integer, ByVal X2 As Integer, ByVal Y2 As Integer) Const Delta = 50 ' Draw a rectangle with round corner Line (X1 + Delta, Y1)-(X2 - Delta, Y1) Line -Step(Delta, Delta) Line -(X2, Y2 - Delta) Line -Step(-Delta, Delta) Line -(X1 + Delta, Y2) Line -Step(-Delta, -Delta) Line -(X1, Y1 + Delta) Line -Step(Delta, -Delta) End Sub Ta cũng có th sơn Shade bên trong hình ch nh t b ng cách dùng method PSet ñ ch m các ñóm cách nhau ch ng 50 pixels như sau:

Private Sub Shade(ByVal X1 As Integer, ByVal Y1 As Integer, ByVal X2 As Integer, ByVal Y2 As Integer) ' Shade a roundcorner rectangle by plotting dots using method Pset Const Delta = 50 Dim i As Integer Dim j As Integer ' Make sure that X1 is less than X2 ' Swap values of X1, X2 if X1 > X2 If X2 < X1 Then Temp = X1 X1 = X2 X2 = Temp End If ' Make sure that Y1 is less than Y2 ' Swap values of Y1, Y2 if Y1 > Y2

175

If Y2 < Y1 Then Temp = Y1 Y1 = Y2 Y2 = Temp End If ' Plotting dots inside the rectangle at 50 pixels apart For i = X1 + Delta To X2 - Delta Step 50 For j = Y1 + Delta To Y2 - Delta Step 50 PSet (i, j) Next Next End Sub Mu n Shade ñ m hơn, b n có th ch m các ñóm g n nhau hơn, thí d cho cách nhau 30 pixels thay vì 50 pixels. Có m t cách khác là tăng tr s c a DrawWidth, ñ dày c a ñư ng v hay ñóm. Bây gi ph i h p cách v hình ch nh t v i method Shade nói trên và method Print ta có th vi t ch bên trong m t khung màu nh t như sau:

Private Sub CmdDrawFrame_Click() Dim X1 As Integer Dim Y1 As Integer Dim X2 As Integer Dim Y2 As Integer ' Initialise Coordinates of rectangle X1 = 4200: Y1 = 1000 X2 = 6200: Y2 = 2000 ' Draw a roundcorner rectangle RoundCornerRectangle X1, Y1, X2, Y2 ' Shade the rectangle Shade X1, Y1, X2, Y2 ' Position cursor to Print some text CurrentX = X1 + 50 CurrentY = Y1 + 50 ' Define Font Size Font.Size = 18 ' Print the text at cursor location Print "Hello there!" End Sub

176

Khi ch y chương trình n y và click t t c các buttons trên form, b n s có hình dư i ñây:

Hãy nh set property AutoDraw c a form ra True ñ các graphic chương trình v không b m t khi user minimises form. B n cũng có th dùng nh ng k thu t nói trên v i Object Printer ñ in các m u gi y ñi n chi ti t. Method Circle
Ta dùng Method Circle ñ v hình tròn, hình b u d c và ñư ng cung, v i bên trong tr ng r ng hay ñư c sơn ñ y b ng m t màu ta ch ñ nh. Ta ph i cho bi t t a ñ c a tâm ñi m vòng tròn và bán kính c a nó. B n hãy kh i ñ ng m t d án VB6 m i, ñ t lên form m t button v i tên frmCircle và caption Circle & Lines. DoubleClick lên button y và vi t code sau ñây: Private Sub CmdCircleLine_Click() ' Draw a circle centered at 2000,1500 with radius equal 800 Circle (2000, 1500), 800 ' Draw a vertical line from center Line (2000, 1500)-Step(0, 800) ' Draw a horizontal line from center Line (2000, 1500)-Step(800, 0) End Sub Bây gi hãy ñ t lên form m t button khác tên CmdArc và caption Draw Arc. Thay vì v nguyên m t vòng tròn, ta s ch v m t hình vòng cung b ng màu ñ . ð ch ñ nh r ng ta s v t v trí nào trên vòng tròn ñ n v trí nào khác, thí d t 45ñ ñ n 230ñ , ta c n ph i ñ i degree ra ñơn v Radian b ng cách dùng Function Rads như sau:

177

Private Function Rads(ByVal Degree As Single) As Single ' Convert Degrees to Radian Const PI = 22 / 7 Rads = Degree / 180 * PI End Function Vòng cung luôn luôn ñư c v ngư c chi u kim ñ ng h . Dư i ñây là code ñ v m t ñư ng vòng cung màu ñ bán kính 800, tâm ñi m (4000, 2000), t 45ñ ñ n 230ñ :

Private Sub CmdArc_Click() Circle (4000, 2000), 800, vbRed, Rads(45), Rads(230) End Sub Ta có th cho sơn bên trong các hình tròn, hay Pie Slices (m t ph n c a hình tròn) b ng cách set FillStyle b ng 0 và ch ñ nh màu FillColor. M t Pie Slice là m t vòng cung ñóng kính b i hai ñư ng th ng bán kính hai ñ u. Mu n v m t Pie Slice ta ñánh thêm d u tr ("-") trư c hai tr s Radian, t c là dùng -Rads(45), -Rads(230) thay vì Rads(45), Rads(230). Dư i ñây là code v hai Pie Slices, có tâm ñi m l ch nhau m t tí, ñ ng th i thêm chú thích 87.5% và 12.5%.

Private Sub CmdPie_Click() FillStyle = 0 ' Fill inside any closed shaped FillColor = vbYellow ' Draw a Pie Slice from 90deg to 45deg in Yellow Circle (3000, 4000), 800, , -Rads(90), -Rads(45) ' Position the graphic cursor to Print some text CurrentX = 2800: CurrentY = 4400 Print "87.5%" FillColor = vbBlue ' Draw a Pie Slice from 45deg to 90deg in Blue Circle (3050, 3900), 800, , -Rads(45), -Rads(90) ' Position the graphic cursor to Print some text CurrentX = 3400: CurrentY = 3000 Print "12.5%" FillStyle = 1 ' No fill End Sub

178

Cách dùng cu i cùng c a method Circle là ñ v m t hình b u d c (Elllipse). V hình b u d c gi ng như v m t hình tròn nhưng ta c n cho thêm m t parameter g i là Aspect. Aspect là s liên h gi a bán kính vertical và bán kính horizontal. Thí d n u Aspect=2 thì chi u cao c a hình b u d c g p ñôi chi u ngang, ngư c l i, n u Aspect=0.5 thì chi u ngang s g p ñôi chi u cao. Dư i ñây là code ta dùng ñ v hai hình b u d c cùng c , m t cái màu tím n m th ng ñ ng và m t cái màu xanh n m ngang.

Private Sub CmdEllipse_Click() Circle (1400, 3000), 800, vbMagenta, , , 2 Circle (1400, 3000), 800, vbBlue, , , 0.5 End Sub N u b n kh i ñ ng chương trình và click c b n buttons b n s th y hình sau ñây:

Property DrawMode Thông thư ng khi ta v , tr s default c a property DrawMode là 13- Copy Pen. Có m t tr s DrawMode r t thích h p cho áp d ng ho t h a là 7- Xor Pen. Mu n xóa m t hình v a v xong ta ch c n v l i hình y trong DrawMode Xor Pen, không c n bi t trư c ñó background như th nào, nó s hi n ra tr l i.

Chương Mư i Ba - Cơ s d
Table, Record và Field

li u (Database)

179

Nói ñ n cơ s d li u, ta l p t c nghĩ ñ n SQLServer, Access hay Oracle .v.v., nh ng nơi ch a r t nhi u d li u ñ ta có th lưu tr hay l y chúng ra m t cách ti n l i và nhanh chóng. H u h t các chương trình ta vi t ñ u có truy c p cơ s d li u, và ta dùng nó như m t công c ñ làm vi c v i r t nhi u d li u trong khi t p trung vào vi c l p trình ph n giao di n v i ngư i dùng (users). Do ñó ta c n có m t ki n th c căn b n v ki n trúc c a cơ s d li u ñ hi u lý do t o sao ta thi t k hay truy c p nó theo nh ng cách nh t ñ nh. Ta s dùng Access Database biblio.mdb, n m C:\Program Files\Microsoft Visual Studio\VB98\biblio.mdb ñ minh h a các ý ni m c n bi t v cơ s d li u. Trong database n y có 4 tables: Authors (tác gi ), Publishers (nhà xu t b n), Titles (ñ m c) và Title Author.

Table Authors ch a nhi u records. M i record trong table Authors ch a 3 fields: Au_ID, Author và Year Born (năm sanh). Ta có th trình bày Table Authors dư i d ng m t spreadsheet như sau:

Vì cùng m t field c a các records hi n th trong cùng m t c t c a spreadsheet, nên ta cũng nói ñ n m t field như m t column (c t). Và vì m i data record chi m m t row (hàng) c a spreadsheet, nên có khi ta cũng nói ñ n m t record như m t row. Th t tình mà nói, ta không c n ph i có m t computer ñ lưu tr hay làm vi c v i m t table như Authors n y. Ta ñã có th dùng m t h p c t, trên m i c t ta ghi các chi ti t Au_ID, Author và Year Born c a m t Author. Như th m i t m c t tương ñương v i m t record và nguyên cái h p là tương ñương v i Table Authors. Ta s s p các c t trong h p theo th t c a s Au_ID ñ có th truy c p record nhanh chóng khi bi t Au_ID. Ch kh m t n i, n u mu n bi t có bao nhiêu tác gi , trong s 300 c t trong h p, già hơn 50

180

tu i thì ph i m t vài phút m i có th tr l i ñư c. Database trong computer nhanh hơn m t h th ng b ng tay (Manual) là ch ñó. Primary Key và Index ð tránh s trùng h p, thư ng thư ng có m t field c a record, thí d như Au_ID trong Table Authors, ñư c dành ra ñ ch a m t tr s ñ c ñáo (unique). T c là trong Table Authors ch có m t record v i field Au_ID có tr s y mà thôi. Ta g i nó là Primary Key.

Không ph i lúc nào ta cũng mu n truy c p m t record Author d a vào Au_ID. Nhi u khi ta mu n dùng chính tên c a Author ñ truy c p, do ñó ta cũng c n ph i sort s n các records theo th t alphabet. Ta cũng có th h p nhi u fields l i ñ sort các records. Th t ra, chính các records không c n ph i ñư c d i ñi ñ n m ñúng v trí th t . Ta ch c n nh v trí c a nó ñâu trong table là ñ r i. Cái field hay t p h p c a nhi u fields (thí d surname và firstname ) ñ dùng vào vi c sorting n y ñư c g i là Index (ngón tay ch ). M t Table có th có m t hay nhi u Index. M i Index s là m t table nh c a nh ng pointers, ch a v trí c a các records trong Table Authors. Nó gi ng như m c l c index cu i m t cu n sách ch a trang s ñ ch ta ñ n ñúng ph n ta mu n tìm trong quy n sách. Khi thi t k m t Table ta ch ñ nh Datatype c a m i field ñ có th ki m tra data cho vào có h p l hay không. Các Datatypes thông d ng là Number, String (ñ ch a Text), Boolean (Yes/No), Currency (ñ ch a tr s ti n) và Date (ñ ch a date/time). Datatype Number l i g m có nhi u lo i datatypes v con s như Integer, Long (integer chi m 32 bits), Single, Double, .v.v. Dư i ñây là Datatypes c a các fields trong record Author:

181

Có lo i Datatype ñ c bi t tên là AutoNumber. Th t ra nó là Long nhưng tr s ñư c phát sinh t ñ ng m i khi ta thêm m t record m i vào Table. Ta không làm gì hơn là ph i ch p nh n con s y. Relationship và Foreign Key Bây gi , n u b n ñang ch y Microsoft Access ñ quan sát database biblio.mdb, b n có th dùng Menu Command Tools | Relationships như sau ñ xem s liên h (relationships) gi a các tables.

Access s hi n th giao tho i Relationships, trong ñó m i table có ch a tên các fields. M i table l i có m t hay hai s i dây n i qua các tables klhác. M i s i dây là m t m i liên h (relationship), nó n i m t field trong m t table v i m t field có cùng tên trong table kia. Thí d như gi a hai tables Publishers và Titles có m i liên h d a trên field PubID (Publisher IDentification - s lý l ch c a nhà xu t b n). Hơn n a, n u ñ ý b n s th y ñ u dây phía table Publishers có con s 1, còn ñ u dây bên phía table Titles có d u vô c c (∞). Ta g i m i liên h (1-∞ ) là one-to-many, ý nói m t nhà xu t b n có th phát hành nhi u ñ m c sách/CD.

182

Tương t như v y, trong m i liên h one-to-many gi a table Authors và Title Author, ta th y m t tác gi (bên ñ u có con s 1) có th sáng tác nhi u tác ph m ñư c ñ i di n b i các record Title Author. Trong khi ñó gi a hai tables Titles và Title Author, ta có m t m i liên hê one-to-one, t c là tương ng v i m i record Title ch có m t record Title Author. Câu h i ñ t ra là các m i liên h one-to-many có cái gì quan tr ng. Tư ng tư ng khi ta làm vi c v i table Titles (t m g i là Tác ph m), nhi u khi ta mu n bi t chi ti t c a nhà xu t b n c a tác ph m y. Th t ra ta ñã có th ch a chi ti t c a nhà xu t b n c a m i tác ph m ngay trong table Titles. Tuy nhiên, làm như th có ñi m b t l i là records c a các tác ph m có cùng nhà xu t b n s ch a nh ng d li u gi ng nhau. M i l n mu n s a ñ i chi ti t c a m t nhà xu t b n ta ph i s a chúng trong m i record Title thu c nhà xu t b n y. Vì mu n ch a chi ti t c a m i nhà xu t b n m t ch duy nh t, tránh s l p l i, nên ta ñã ch a chúng trong m t table riêng, t c là table Publishers. N u gi s ta b t ñ u thi t k database v i Table Titles, r i quy t ñ nh tách các chi ti t v nhà xu t b n ñ vào m t table m i, tên Publishers, thì k thu t y ñư c g i là normalization. Nói m t cách khác, normalization là thi t k các tables trong database làm sao ñ m i lo i m nh d ki n (không ph i là Key) ch xu t hi n m t ch . Trong m i liên h one-to-many gi a tables Publishers và Titles, field PubID là Primary Key trong table Publishers. Trong table Titles, field PubID ñư c g i là Foreign Key, có nghĩa r ng ñây là Primary Key c a m t table l (foreign). Hay nói m t cách khác, trong khi làm vi c v i table Titles, lúc nào c n chi ti t m t nhà xu t b n, ta s l y chìa khóa l (Foreign Key) dùng làm Primary Key c a Table Publishers ñ truy c p record ta mu n. ð ý là chính Table Titles có Primary Key ISBN c a nó. Relational Database M t database có nhi u tables và h tr các liên h , nh t là one-to-many, ñư c g i là Relational Database. Khi thi t k m t database, ta s tìm cách s p ñ t các d li u t th gi i th t bên ngoài vào trong các tables. Ta s quy t ñ nh ch n các c t (columns/fields) nào, ch n Primary Key, Index và thi t l p các m i liên h , t c là ñ t các Foreign Key ñâu. Các l i ích Trong s các l i ích c a m t thi t k Relational Database có:

S a ñ i d ki n, cho vào records m i hay delete (g ch b ) records có s n r t hi u qu (nhanh).

183

• • • •

Truy c p d ki n, làm báo cáo (Reports) cũng r t hi u qu . Vì d ki n ñư c s p ñ t th t và có quy c nên ta có th tin c y tính tình c a database (không có ba tr n, khi thì th n y, khi thì th khác - gi t gi t). Vì h u h t d ki n n m trong database, thay vì trong chương trình ng d ng, nên database t có documentation (tài li u c t nghĩa). D s a ñ i chính c u trúc c a các tables.

Integrity Rules (các quy lu t liêm chính) Integrity Rules ñư c dùng ñ nói v nh ng qui lu t c n ph i tuân theo trong khi làm vi c v i database ñ ñ m b o là database còn t t. Có hai lo i quy lu t: lu t t ng quát (General Integrity Rules) và lu t riêng cho database (Database-Specific Integrity Rules). Các lu t riêng n y thư ng tùy thu c vào các quy lu t v m u d ch (Business Rules).

General Integrity Rules
Có hai quy lu t liêm chính liên h hoàn toàn vào database: Entity (b n th ) Integrity Rule và Referential (ch ñ n) Integrity Rule. Entity Integrity Rule nói r ng Primary Key không th thi u ñư c, t c là không th có tr s NULL. Quy lu t n y xác nh n là vì m i Primary Key ñưa ñ n m t row ñ c ñáo trong table, nên dĩ nhiên nó ph i có m t tr s ñàng hoàng. Lưu ý là Primary Key có th là m t Composite Key, t c là t p h p c a m t s keys (columns/fields), nên nh t ñ nh không có key nào trong s các columns là NULL ñư c. Referential Integrity Rule nói r ng database không th ch a m t Foreign Key mà không có Primary Key tương ng c a nó trong m t table khác. ði u y hàm ý r ng:

• •

Ta không th thêm m t Row vào trong m t Table v i tr s Foreign Key trong Row y không tìm th y trong danh sách Primary Key c a table bên phía one (1) mà nó liên h . N u có thay ñ i tr s c a Primary Key c a m t Row hay delete m t Row trong table bên phía one (1) thì ta không th ñ các records trong table bên phía many (∞) ch a nh ng rows tr thành m côi (orphans). Nói chung, có ba nhi m ý (options) ta có th ch n khi thay ñ i tr s c a Primary Key c a m t Row hay delete m t Row trong table bên phía one (1):

1. Disallow (không cho làm): Hoàn toàn không cho phép chuy n n y xãy ra. 2. Cascade ( nh hư ng dây chuy n): N u tr s Primary Key b thay ñ i thì tr s Foreign Key tương ng trong các records c a table bên phía many (∞) ñư c thay ñ i theo. N u Row ch a Primary Key b deleted thì các records tương ng trong table bên phía many (∞) b deleted theo.

184

3. Nullify (cho thành NULL): N u Row ch a Primary Key b deleted thì tr s Foreign Key tương ng trong các records c a table bên phía many (∞) ñư c ñ i thành NULL, ñ hàm ý ñ ng có ñi tìm thêm chi ti t ñâu c .

Database-Specific Integrity Rules
Nh ng quy lu t liêm chính nào khác không ph i là Entity Integrity Rule hay Referential Integrity Rule thì ñư c g i là Database-Specific Integrity Rules. Nh ng quy lu t n y d a vào chính lo i database và nh t là tùy thu c vào các quy lu t v m u d ch (Business Rules) ta dùng cho database, thí d như m i record v ti n lương c a công nhân ph i có m t field S Thu (Tax Number) do s Thu V phát hành cho công dân. Lưu ý là các quy lu t n y cũng quan tr ng không kém các quy lu t t ng quát v liêm chính. N u ta không áp d ng các Database-Specific Integrity Rules nghiêm ch nh thì database có th b hư và không còn dùng ñư c.

Microsoft Access Database Management System (MSAccess DBMS) Microsoft Access Database Management System g m có Database Engine và nh ng công c ñi chung ñ cung c p cho users m t môi trư ng làm vi c thân thi n v i database, như Database Design (thi t k các tables và m i liên h ), Data entry và báo cáo (reports). Kèm theo v i Visual Basic 6.0 khi ta mua là m t copy c a Database Engine c a MSAccess. Tên nó là Jet Database Engine, cái lõi c a MSAccess DBMS. Các chương trình VB6 có th truy c p database qua Jet Database Engine. N u trên computer c a b n có cài s n MSAccess, thì b n có th dùng ñó ñ thi t k các tables c a database hay cho data vào các tables. Properties Required và Allow Zero Length Khi thi t k m t table field, lưu ý property Required và nh t là property Allow Zero Length c a Text. N u property Required c a m t field là Yes thì ta không th update (vi t) m t record v i field y có tr s NULL. N u m t Text field có property Allow Zero Length là No thì thì ta không th update m t record khi field y ch a m t empty string.

Khi ta t o m t record l n ñ u, n u không cho tr s c a m t field, thì field y có tr s là NULL.

185

Thư ng thư ng, Visual Basic 6.0 không thích NULL value nên ta ph i th m t field v i Function IsNULL() ñ ñ m b o nó không có tr s NULL trư c khi làm vi c v i nó. N u IsNULL tr v tr s False thì ta có th làm vi c v i field y. Nh là khi tr s NULL ñư c dùng trong m t expression, ngay c khi chương trình không cho Error, k t qu cũng là NULL. Làm vi c v i các versions khác nhau N u máy b n ñang ch y MSAccess2002 thì b n có th làm vi c v i Access database file version 97, 2000 và 2002. N u c n ph i convert t version n y qua version khác, b n có th dùng Access DBMS Menu Command Tools | Database Utilities | Convert Database | To Access 2002 File Format.... N u mu n gi nguyên version, b n có th convert database qua File Format 2002 ñ s a ñ i, r i sau ñó convert tr l i File Format cũ.

Access database file l n lên r t nhanh, vì các records ñã b deleted v n còn n m nguyên, nên m i tu n b n nên nh nén nó l i ñ b h t các records ñã b deleted b ng cách dùng Access DBMS Menu Command Tools | Database Utilities | Compact and Repair Database... hay dùng function DBEngine.CompactDatabase trong VB6. Dùng Query ñ vi t SQL M t cách ñ truy c p database là dùng ngôn ng Structured Query Language (SQL) theo chu n do ISO/IEC phát hành năm 1992, g i t t là SQL92. T t c m i database thông d ng ñ u h tr SQL, m c d u nhi u khi chúng còn cho thêm nhi u ch c năng r t hay nhưng không n m trong chu n. Các l nh SQL thông d ng là SELECT, UPDATE, INSERT và DELETE. Ta có th dùng phương ti n thi t k Query c a MSAccess ñ vi t SQL. Sau khi thi t k Query b ng cách drag drop các fields, b n có th dùng Menu Command View | View SQL như sau:

186

Ti p theo ñây là SQL statement c a Query bên trên mà b n có th copy ñ paste vào trong code VB6:

Dùng Link Table ñ làm vi c tr c ti p v i database lo i khác Ta có th dùng m t database lo i khác, như DBase, tr c ti p trong VB6 như dùng m t Access database bình thư ng. Mu n thi t l p móc n i y, b n dùng Menu Command File | Get External Data | Link Tables... r i ch n lo i DBase và chính file c a table mà b n mu n dùng ñ nhét nó vào Access database ñang m :

187

Database Server và m t s ý ni m Dù Jet Database Engine là m t relational database r t t t và hi u năng, nó thu c lo i File Based database, t c là nó th ñ ng, không ch y m t mình nhưng ph i tùy thu c vào chương trình dùng nó. File Based database không thích h p v i nh ng ng d ng có nhi u ngư i dùng cùng m t lúc. Trong khi ñó, m t Database Server như SQLServer ch y riêng ñ ph c v b t c chương trình khách (client) nào c n. Database Server thich h p cho các ng d ng có nhi u users vì ch có m t mình nó ch u trách nhi m truy c p d li u cho m i clients. Nó có th ch a nhi u routines ñ a phương, g i là Stored Procedures, ñ th c hi n các công tác client yêu c u r t hi u năng. Database Server thư ng có cách ñ i phó h u hi u khi có s c v ph n c ng như ñĩa hư hay cúp ñi n. Ngoài ra, Database Server có s n các phương ti n v an ninh và backup. Nó cũng có thêm các ch c năng ñ dùng cho m ng. Ngày nay ta thâu th p d li u dư i nhi u hình th c như Email, Word documents, Speadsheet. Không nh t thi t d li u luôn luôn ñư c ch a dư i d ng table c a nh ng records và không nh t thi t d li u luôn luôn ñư c lưu tr trong m t database ñàng hoàng. Dù v y, chúng v n ñư c xem như database dư i m t m t chương trình ng d ng. Do ñó, ta dùng t Data Store (Kho d li u) thay th cho database ñ nói ñ n nơi ch a d li u. Và ñ i v i chương trình tiêu th d li u, ta nói ñ n Data Source (Ngu n d li u) thay vì database. Khi l p trình b ng VB6 ñ truy c p database, ta nhìn databse m t cách tr u tư ng, t c là d u nó là Access, DBase, SQLServer hay Oracle ta cũng xem như nhau. N u có thay ñ i lo i database bên dư i, cách l p trình c a ta cũng không thay ñ i bao nhiêu. Trong tương lai, m t XML file cũng có th ñư c xem như m t database nho nh . Nó có th ñ ng m t mình hay là m t table trích ra t m t database chính huy. XML là m t chu n mà ta có th dùng ñ import/export d li u v i t t c m i lo i database h tr XML. Ta có th trao ñ i d li u trên m ng

188

Intenet dư i d ng XML. Ngoài ra, thay vì làm vi c tr c ti p v i m t database l n, ta có th trích ra vài tables t database y thành m t XML file. K ñó ta ch l p trình v i XML file cho ñ n khi k t thúc s hòa (merge/reconcile) XML file v i database l n. N u ph n l n các chương trình áp d ng ñư c thi t k ñ làm vi c cách n y, thì trong tương lai ta không c n m t Database Server th t m nh.

Chương Mư i B n - Dùng Control Data
Control Data
T VB5, Visual Basic cho l p trình viên m t control ñ truy c p cơ s d li u, tên nó ch ñơn sơ là Data. Như ta bi t, có m t cơ s d li u Microsoft gói kèm khi ta mua VB6 - ñó là Jet Database Engine. Jet Database Engine là cái "phòng máy" c a chính MS Access Database Management System. Cho ñ n th i VB5, Microsoft cho ta ba k thu t chính:

DAO (Data Acess Objects): DAO là k thu t bí truy n c a Microsoft, ch ñ dùng v i Jet Database Engine. Nó r t d dùng, hi u năng và ti n, nhưng b gi i h n trong ph m vi MS Access. D u v y, nó r t th nh hành vì có l i ích th c ti n. ODBC (Open Database Connectivity): ODBC ñư c thi t k ñ cho phép users n i v i ñ lo i databases mà ch dùng m t method duy nh t. ði u n y c t b t gánh n ng cho l p trình viên, ñ ch c n h c m t k thu t l p trình duy nh t mà có th làm vi c v i b t c lo i database nào. Nh t là khi sau n y n u c n ph i thay ñ i lo i database, như nâng c p t Access lên SQLServer ch ng h n, thì s s a ñ i v coding r t ít. Khi dùng ODBC chung v i DAO, ta có th cho Access Database n i v i các databases khác. Có m t b t l i c a ODBC là nó r c r i. RDO (Remote Data Object): M t trong nh ng lý do chính ñ RDO ñư c thi t k là gi i quy t khó khăn v s r c r i c a ODBC. Cách l p trình v i RDO ñơn gi n như DAO, nhưng th t ra nó dùng ODBC nên cho phép users n i v i nhi u databases. Tuy nhiên, RDO không ñư c th nh hành l m.

VB6 ti p t c h tr các k thu t nói trên, và cho thêm m t k thu t truy c p database m i, r t quan tr ng, ñó là ADO (ActiveX Data Objects). Trong m t bài t i ta s h c v ADO v i nh ng ưu ñi m c a nó. Tuy nhiên, vì DAO r t ñơn gi n và hi u năng nên ta v n có th ti p t c dùng nó r t h u hi u trong h u h t các áp d ng. Do ñó bài n y và bài k s t p trung vào nh ng k thu t l p trình ph bi n v i DAO. Cách dùng gi n ti n c a control Data là ñ t nó lên m t Form r i làm vi c v i nh ng Properties c a nó. B n hãy b t ñ u m t d án VB6 m i, cho nó tên DataControl b ng cách click tên project trong Project Explorer bên ph i r i edit property Name trong Properties Window. DoubleClick lên Icon c a Control Data trong Toolbox. M t Control Data tên Data1 s hi n ra trên Form. Mu n cho nó n m bên dư i Form, gi ng như m t StatusBar, hãy set property Align c a nó trong Properties Window thành 2 - Align Bottom. Click bên ph i hàng property DatabaseName, k ñó click lên nút browse có ba ch m ñ ch n m t file Access dabase t giao tho i cho Data1. ñây ta ch n E:\Program Files\Microsoft Visual Studio\VB98\BIBLIO.MDB , trong computer c a b n có th nó n m trên disk C hay D.

189

Trong chương trình n y ta mu n làm vi c v i table Titles c a database BIBLIO.MDB, ñ xem và edit các records. ð ý property DefaultType c a Data1 có tr s 2- UseJet, t c là dùng k thu t DAO, thay vì dùng k thu t ODBC. Khi b n click lên property Recordsource c a Data1, r i click lên cái tam giác nh bên ph i, m t ComboBox s m ra cho ta th y danh sách các tables trong database. B n hãy ch n Titles. ð ý property RecordsetType c a Data1 có tr s là 0 - Table:

Cái t m i mà ta s dùng thư ng xuyên khi truy c p d li u trong VB6 là Recordset (b records). Recordset là m t Set of records, nó có th ch a m t s records hay không có record nào c . M t record trong Recordset có th là m t record l y t m t Table. Trong trư ng h p y có th ta l y v t t c records trong table hay ch nh ng records th a ñúng m t ñi u ki n, thí d như ta ch mu n l y các records c a nh ng sách xu t b n trư c năm 1990 (Year Published < 1990). M t Record trong Recordset cũng có th là t p h p các c t (columns) t hai (hay ba)

190

tables qua các m i liên h one-to-one và one-to-many. Thí d như khi l y các records t table Titles, ta mu n có thêm chi ti t tên công ty (Company Name) và ñi n tho i (Telephone) c a nhà xu t b n (table Publishers) b ng cách dùng Foreign Key PubID trong table Titles làm Primary Key trong table Publishers ñ l y các chi ti t y. N u b n chưa n m v ng ý ni m Foreign Key thì hãy ñ c l i bài Database. Trong trư ng h p y ta có th xem như có m t virtual ( o) table là t p h p c a hai tables Titles và Publishers. Bây gi b n hãy ñ t lên Form 4 labels v i captions: Title, Year Published, ISBN và Publisher ID. K ñó cho thêm 4 textboxes tương ng và ñ t tên chúng là txtTitle, txtYearPublished, txtISBN và txtPublisherID. Ch n textbox txtTitle, r i set property Datasource c a nó trong Properties Window thành Data1. Khi click lên property Datafield c a txtTitle và m ComboBox ra b n s th y li t kê tên các Fields trong table Titles. ðó là vì Data1 ñư c coi như trung gian l y table Titles t database. ñây ta s ch n c t Title. L p l i công tác n y cho 3 textboxes kia, và ch n các c t Year Published (năm xu t b n), ISBN (s lý l ch trong thư vi n qu c t ), và PubID (s lý l ch nhà xu t b n) làm Datafield cho chúng.

T i ñây, m c d u chưa vi t m t hàng code, ta có th ch y chương trình ñư c r i. Nó s hi n th chi ti t c a record ñ u tiên trong table Titles như dư i ñây:

191

B n có th b m các nút di chuy n Navigator Buttons ñ ñi ñ n các record ñ u (first), trư c (previous), k (next) và cu i (last). M i l n b n di chuy n ñ n m t record m i là chi ti t c a record y s hi n th . N u không dùng các Navigator Buttons, ta cũng có th code ñ làm công tác tương ñưong b ng cách g i các Recordset methods MoveFirst, MovePrevious, MoveNext và MoveLast. Khi record cu i c a Recordset ñang hi n th , n u ta g i method MoveLast thì property EOF (End-Of-File) c a Recordset tr thành True. Tương t như v y, khi record th nh t c a Recordset ñang hi n th , n u ta g i method MovePrevious thì property BOF (Begin-Of-File) c a Recordset tr thành True. N u m t Recordset không có ch a m t record nào c thì c hai properties EOF và BOF ñ u là True. ð c tính hi n th d li u trong các textboxex theo ñúng record hi n th i (current record) ñư c g i là data binding hay data bound (bu c vào d li u) và control TextBox h tr ch c năng n y ñư c nói là Data Aware (bi t bà con d li u). Khi record ñ u tiên ñang hi n th , n u b n edit Year Published ñ ñ i t 1985 thành 1983 r i click Navigator button Next ñ hi n th record th nhì, k ñó click Navigator button Previous ñ hi n th l i record ñ u tiên thì b n s th y là field Year Published c a record ñ u tiên ñã th t s ñư c thay ñ i (updated) thành 1983. ði u n y có nghĩa r ng khi Data1 navigates t record n y ñ n record khác thì n u record n y ñã có s thay ñ i vì user edited, nó lưu tr s thay ñ i ñó trư c khi di chuy n. Chưa ch c là b n mu n ñi u n y, do ñó, n u b n không mu n user tình c edit m t record thì b n có th set property Locked c a các textboxes y thành True ñ user không th edit các textboxes như trong hình dư i ñây:

192

Ch ñ nh v trí Database lúc ch y chương trình
Cách ch ñ nh tên DatabaseName trong giai ño n thi t k (at design time) ta ñã dùng trư c ñây tuy ti n l i nhưng hơi nguy hi m, vì khi ta cài chương trình n y lên computer c a khách, chưa ch c file database y n m trong m t folder có cùng tên. Thí d trên computer mình thì database n m trong folder E:\Program Files\Microsoft Visual Studio\VB98, nhưng trên computer c a khách thì database n m trong folder C:\VB6\DataControl ch ng h n. Do ñó, khi chương trình kh i ñ ng ta nên xác ñ nh l i v trí c a database. Gi d ta mu n ñ database trong cùng m t folder v i chương trình ñang ch y, ta có th dùng property Path c a Application Object App như sau:

Dim AppFolder As String Private Sub Form_Load() ' Fetch Folder where this program EXE resides AppFolder = App.Path ' make sure it ends with a back slash If Right(AppFolder, 1) <> "\" Then AppFolder = AppFolder & "\" ' Assign Full path database filename to Data1 Data1.DatabaseName = AppFolder & "BIBLIO.MDB" End Sub

V i cách code nói trên ta s ñ m b o chương trình tìm th y file database ñúng ch , không c n bi t ngư i ta cài chương trình b n ñâu trong hard disk c a computer khách. N u b n ñang h c VB6 t xa, khi n p bài database cho giám th VB6 mà b n hardcode

193

(vi t ch t c ng) v trí c a file database trong lúc thi t k thì giám th (tutor) cũng g p cùng s khó khăn n y vì chưa ch c giám th s ch a database trong m t folder có cùng tên như trong harddisk c a b n.

Thêm b t các Records
Chương trình trên dùng cũng t m ñ c, nhưng nó không cho ta phương ti n ñ thêm (add), b t (delete) các records. Bây gi b n hãy ñ vào Form 5 buttons tên: cmdEdit, cmdNew, cmdDelete, cmdUpdate và cmdCancel. M c d u b n không th y, nhưng th t ra Control Data Data1 có m t property Recordset và khi ta dùng Navigator buttons là di chuy n t record n y ñ n record khác trong Recordset y. Ta có th nói ñ n nó b ng Notation (cách vi t) Data1.Recordset, và m i l n mu n l y Recordset m i nh t t database ta dùng method Refresh như Data1.Recordset.Refresh. Lúc chuơng trình m i kh i ñ ng, user ñang xem (browsing) các records thì hai buttons Update và Cancel không c n ph i làm vi c. Do ñó ta s nhân ti n Lock (khóa) các textboxes và disable (làm cho b t l c) hai buttons n y vì không c n dùng chúng. Trong Sub SetControls dư i ñây, ta dùng m t parameter g i là Editing v i tr s False hay True tùy theo user ñang Browse hay Edit, ta g i là Browse mode và Edit mode. Trong Edit mode, các Textboxes ñư c unlocked (m khóa) và các nút cmdNew, cmdDelete và cmdEdit tr nên b t l c:
Sub SetControls(ByVal Editing As Boolean) ' Lock/Unlock textboxes txtTitle.Locked = Not Editing txtYearPublished.Locked = Not Editing txtISBN.Locked = Not Editing txtPublisherID.Locked = Not Editing ' Enable/Disable buttons CmdUpdate.Enabled = Editing CmdCancel.Enabled = Editing CmdDelete.Enabled = Not Editing cmdNew.Enabled = Not Editing CmdEdit.Enabled = Not Editing End Sub

Trong Browse mode, Form có d ng như sau:

194

Sub SetControls ñư c g i trong Sub Form_Load khi chương trình kh i ñ ng và trong Sub CmdEdit khi user click nút Edit như sau:
Private Sub Form_Load() ' Fetch Folder where this program EXE resides AppFolder = App.Path ' make sure it ends with a back slash If Right(AppFolder, 1) <> "\" Then AppFolder = AppFolder & "\" ' Assign Full path database filename to Data1 Data1.DatabaseName = AppFolder & "BIBLIO.MDB" ' Place controls in Browse Mode SetControls (False) End Sub Private Sub CmdEdit_Click() ' Place controls in Edit Mode SetControls (True) End Sub

Khi ta Delete m t record trong recordset, v trí c a record hi n t i (current record) v n không thay ñ i. Do ñó, sau khi delete m t record ta ph i MoveNext. Kh n i, n u ta v a delete record cu i c a Recordset thì sau khi MoveNext, property EOF c a Recordset s thành True. Thành ra ta ph i ki m tra ñi u ñó, n u ñúng v y thì l i ph i MoveLast ñ hi n th record cu i c a Recordset như trong code c a Sub cmdDelete_Click dư i ñây:

Private Sub CmdDelete_Click()

195

On Error GoTo DeleteErr With Data1.Recordset ' Delete new record .Delete ' Move to next record .MoveNext If .EOF Then .MoveLast Exit Sub End With DeleteErr: MsgBox Err.Description Exit Sub End Sub

Trong lúc code, ta Update (c p nh t hóa) m t record trong Recordset b ng method Update. Nhưng ta ch có th g i method Update c a m t Recordset khi Recordset ñang trong Edit hay AddNew mode. Ta ñ t m t Recordset vào Edit mode b ng cách g i method Edit c a Recordset, thí d như Data1.Recordset.Edit. Tương t như v y, ta ñ t m t Recordset vào AddNew mode b ng cách g i method AddNew c a Recordset, thí d như Data1.Recordset.AddNew.

Private Sub cmdNew_Click() ' Place Recordset into Recordset AddNew mode Data1.Recordset.AddNew ' Place controls in Edit Mode SetControls (True) End Sub

Sau khi Recordset g i method Update thì Recordset y ra kh i AddNew hay Edit modes. Ta cũng có th t thoát ra kh i AddNew hay Edit modes, hay nói cho ñúng hơn là h y b m i pending (ñang ch ñ i) Update b ng cách g i method CancelUpdate, thí d như Data1.Recordset.CancelUpdate.
Dùng DataBound Combo

Trong chương trình hi n t i ta ch hi n th lý l ch nhà xu t b n (PubID) c a Title, ch không có thêm chi ti t. Ph i chi m c d u chương trình lưu tr PubID, nhưng hi n th ñư c Company Name c a nhà xu t b n cho ta làm vi c ñ kh i ph i nh các con s thì

196

hay quá. Ta có th th c hi n ñi u ñó b ng cách dùng Control DBCombo (Data Bound Combo). B n hãy dùng IDE Menu Command Project | Components... ñ ch n Microsoft Data Bound List Controls 6.0 r i click Apply.

K ñó, thêm m t DBCombo tên DBCombo1 vào Form. Vì ta c n m t Recordset khác ñ cung c p Table Publisher cho DBCombo1, nên b n hãy thêm m t control Data th nhì tên Data2 vào Form. Cho Data2, hãy set property DatabaseName thành E:\Program Files\Microsoft Visual Studio\VB98\BIBLIO.MDB và property RecordSource thành Publishers. ð không cho ngư i ta th y hình Data2 lúc run-time, b n hãy set property Visible nó thành False.

Cái m c ñích c a chúng ta khi dùng DBCombo1 là hi n th Company Name c a nhà xu t b n, nhưng ñ ng sau lưng thì không có gì thay ñ i, t c là ta v n làm vi c v i PubID cho các record Title c a Data1. Khi user click lên DBCombo1 ñ ch n m t nhà

197

xu t b n, thì ta theo Company Name ñó mà ch a PubID tương ng trong record Title c a Data1. Do ñó có nhi u th ta ph i s p ñ t cho DBCombo1 như sau:
Property RowSource Value Data2 Chú thích ðây là datasource c a chính DBCombo1. Nó cung c p table Publishers. Khi RowSource phía trên ñã ñư c ch n r i, Combo c a property Listfield n y s hi n th các fields c a table Publishers. Company Name là field c a RowSource mà ta mu n hi n th trên DBCombo1. ðây là datasource c a record mà ta mu n. edit, t c là record c a table Titles Field (c a record Title) s ñư c thay ñ i. Field trong RowSource (table Publishers) tương ng v i item user ch n trong DBCombo1 (Company Name).

Listfield

Company Name

DataSource Datafield BoundColumn

Data1 PubID PubID

Khi trong Edit mode user ch n m t Company Name khác trong DBCombo1 r i click nút Update b n s th y Textbox txtPublisherID cũng ñ i theo và hi n th con s lý l ch PubID m i. N u trư c khi Update b n mu n th y PubID m i hi n th trong Textbox txtPublisherID thì b n có th dùng Event Click c a DBCombo1 như sau:

Private Sub DBCombo1_Click(Area As Integer) ' Display new PuBID txtPublisherID.Text = DBCombo1.BoundText End Sub

Property BoundText c a DBCombo1 là tr s c a BoundColumn mà ta có th truy c p (vi t hay ñ c) ñư c. Thí d như b n mu n m i khi thêm m t record Title m i thì default PubID là 324, t c là Company Name= "GLOBAL ENGINEERING". B n có th assign tr s 324 vào property BoundText c a DBCombo1 trong Sub cmdNew_Click như sau:

Private Sub cmdNew_Click() ' Place Recordset into Recordset AddNew mode

198

Data1.Recordset.AddNew ' Default Publisher is "GLOBAL ENGINEERING", i.e. PubID=324 DBCombo1.BoundText = 324 ' Place controls in Edit Mode SetControls (True) End Sub

Trong bài t i ta s h c thêm v cách coding ñ dùng Recordset trong k thu t DAO.

Chương Mư i Lăm - L p trình v i k thu t DAO
Reference DAO
Trong bài n y ta s h c nh ng cách l p trình căn b n v i MS Access database qua k thu t DAO mà không c n dùng ñ n Control Data như trong bài trư c. Ta s c n ñ n vài Objects trong thư vi n DAO, do ñó n u b n m m t d án VB6 m i thì hãy dùng Menu Command Project | References... ñ ch n Microsoft DAO 3.51 Object Library b ng cách click cái checkbox bên trái như trong hình dư i ñây. (M t cách ñ nh tên c a Object n y là nh câu "th ng cha cua ðÀO 35 con dê").

Sau ñó trong code c a Form chính ta s declare variable myDatabase cho m t instance c a DAO database và variable myRS cho m t DAO recordset. ñây ta nói rõ Database và Recordset là thu c lo i DAO ñ phân bi t v i Database và Recordset thu c lo i ADO (ActiveX Data Object) sau n y. ð ý là Intellisense giúp ta trong lúc vi t code:

199

Bây gi b n hãy ñ t lên Form chính, tên frmDAO, 4 labels v i captions: Title, Year Published, ISBN và Publisher ID. K ñó cho thêm 4 textboxes tương ng và ñ t tên chúng là txtTitle, txtYearPublished, txtISBN và txtPublisherID. ði u ta mu n làm là khi Form m i ñư c loaded, nó s l y v t database m t Recordset ch a t t c records trong table Titles theo th t v m u t (alphabetical order) c a field Title và hi n th record ñ u tiên.

Dùng keyword SET
Chuy n trư c h t là m m t Database Object d a vào tên ñ y ñ (full path name) c a Access database:
' Open main database Set myDB = OpenDatabase(AppFolder & "BIBLIO.MDB")

ð ý ch Set trong câu code trên. ðó là vì myDB là m t Pointer ñ n m t Object. M c d u t rày v sau ta s dùng myDB như m t Database theo cách gi ng như b t c variable thu c data type nào khác, nhưng khi ch ñ nh l n ñ u là nó t ñâu ñ n thì ta dùng ch Set, ñ nói r ng th t ra myDB không ph i là Object Database, nhưng là Pointer ñ n Object Database. ði m n y càng nói ñ n càng khó hi u. ð i khái là VB6 runtime dynamically allocates (dành ra cho khi c n) m t ph n trong b nh (memory) ñ ch a Object Database khi ta nh n ñư c nó t execution c a Method OpenDatabase. D u v trí ch ch a Object Database trong b nh không nh t ñ nh, nhưng vì ta n m cái cán ch ñ n v trí y nên ta v n có th làm vi c v i nó m t cách bình thư ng. Cái cán y là value (tr s ) c a variable myDB. Vì value n y không

200

ph i là Object, nhưng nó ch a memory address ch ñ n (point to hay refer to) Object Database, nên ta g i nó là Pointer. L p trình dùng Pointer nói chung r t linh ñ ng là hi u năng trong các ngôn ng như C, Pascal, C++ ,v.v.. Tuy nhiên, l p trình viên ph i nh tr l i Operating System ph n memory mình dùng khi không còn c n nó n a ñ Operating System l i allocate cho Object khác. N u công vi c qu n lý dùng l i memory không n th a thì có nh ng m nh memory n m lang bang mà Operating Sytem không bi t. L n l n Operating System s không còn memory dư n a. Ta g i hi n tư ng y là memory leakage (r ). Các ngôn ng sau n y như Java, C# ñ u không dùng Pointer n a. Visual Basic không mu n l p trình viên dùng Pointer. Ch trong vài trư ng h p ñ c bi t VB6 m i l ra cho ta th y th t ra trong h u trư ng VB6 Runtime dùng Pointer, như trong trư ng h p n y. Tương t như v y, vì Recordset là m t Pointer ñ n m t Object, ta cũng dùng Set khi ch ñ nh m t DAO Recordset l y v t Method OpenRecordset c a database myDB.
'Open recordset Set myRS = myDB.OpenRecordset("Select * from Titles ORDER BY Title")

Cái parameter lo i String ta dùng cho method OpenRecordset là m t L nh (Statement) SQL. Nó ch ñ nh cho database l y t t c m i fields (columns) (Select *) c a m i record t Table Titles (from Titles) làm m t Recordset và sort các records trong Recordset y theo alphabetical order c a field Title (ORDER BY Title). Nh là Recordset n y cũng gi ng như property Recordset c a m t Control Data mà ta dùng trong bài trư c. Bây gi có Recordset r i, ta có th hi n th chi ti t c a record ñ u tiên n u Recordset y có ít nh t m t record. Ta ki m tra ñi u y d a vào property RecordCount c a Recordset như trong code dư i ñây:

Private Sub Form_Load() ' Fetch Folder where this program EXE resides AppFolder = App.Path ' make sure it ends with a back slash If Right(AppFolder, 1) <> "\" Then AppFolder = AppFolder & "\" ' Open main database Set myDB = OpenDatabase(AppFolder & "BIBLIO.MDB") 'Open recordset Set myRS = myDB.OpenRecordset("Select * from Titles ORDER BY Title") ' if Recordset is not empty then display the first record If myRS.RecordCount > 0 Then

201

myRS.MoveFirst ' move to first record Displayrecord ' display details of current record End If End Sub

Sau khi dùng method MoveFirst c a Recordset ñ position current record Record ñ u tiên, ta hi n th tr s các fields c a record b ng cách assign chúng vào các textboxes c a Form như sau:

Private Sub Displayrecord() ' Assign record fields to the appropriate textboxes With myRS ' Assign field Title to textbox txtTitle txtTitle.Text = .Fields("Title") txtYearPublished.Text = .Fields("[Year Published]") txtISBN.Text = .Fields("ISBN") txtPublisherID.Text = .Fields("PubID") End With End Sub

ð ý vì field Year Publshed g m có hai ch nên ta ph i ñ t tên c a field y gi a hai d u ngo c vuông ([]). ð tránh b phi n ph c như trong trư ng h p n y, khi b n ñ t tên database field trong lúc thi t k m t table hãy dán dính các ch l i v i nhau, ñ ng ñ r i ra. Thí d như dùng YearPublished thay vì Year Published.

Các nút di chuy n
Mu n có các nút Navigators tương ñương v i c a m t Control Data, b n hãy ñ t lên Form 4 buttons mang tên CmdFirst, CmdPrevious, CmNext và CmdLast v i captions: <<, <, >, >>. Code cho các nút n y cũng ñơn gi n, nhưng ta ph i coi ch ng khi user mu n di chuy n quá record cu i cùng hay record ñ u tiên. Ta ph i ki m tra xem EOF có tr thành True khi user click CmdNext, hay BOF có tr thành True khi user click CmdPrevious:
Private Sub CmdNext_Click() myRS.MoveNext ' Move to next record ' Display record details if has not gone past the last record If Not myRS.EOF Then Displayrecord ' display details of current record Else myRS.MoveLast ' Move back to last record

202

End If End Sub Private Sub CmdPrevious_Click() myRS.MovePrevious ' Move to previous record ' Display record details if has not gone past the first record If Not myRS.BOF Then Displayrecord ' display details of current record Else myRS.MoveFirst ' Move back to first record End If End Sub Private Sub CmdFirst_Click() myRS.MoveFirst ' Move back to first record Displayrecord ' display details of current record End Sub Private Sub CmdLast_Click() myRS.MoveLast ' Move back to last record Displayrecord ' display details of current record End Sub

Khi ch y chương trình b n s th y nó hi n th chi ti t c a Record ñ u tiên khác v i trong bài trư c ñây vì các records ñã ñư c sorted:

B n hãy th dùng các Navigator buttons cây nhà, lá vư n c a mình xem chúng làm vi c có ñúng không. T i ñây, không bi t b n có ñ ý là dù user có vô tình s a ñ i m t chi ti t nào trong các textboxes, không có record nào b c p nh t hóa trong database khi user di chuy n t record n y ñ n record khác. Lý do là các Texboxes không có Data Bound v i các Fields c a Recordset.

203

Thêm b t các Records
Gi ng như chương trình trong bài r i, ta s thêm phương ti n ñ thêm (add), b t (delete) các records. Bây gi b n hãy ñ vào Form 5 buttons tên: cmdEdit, cmdNew, cmdDelete, cmdUpdate và cmdCancel. Ch nào trong chương trình trư c ta dùng Data1.Recordset thì bây gi ta dùng myRS. Ta s dùng l i Sub SetControls v i parameter Editing có tr s False hay True tùy theo user ñang Browse hay Edit. Trong Browse mode, các Textboxes b Locked (khóa) và các nút cmdUpdate và cmdCancel tr nên b t l c. Trong Edit mode, các Textboxes ñư c unlocked (m khóa) và các nút cmdNew, cmdDelete và cmdEdit tr nên b t l c. Vì ñây không có Data Binding nên ñ i cho ñ n khi Update (c p nh t hóa) ta m i ñ t Recordset vào AddNew hay Edit mode. Do ñó ta ch c n nh là khi user edits là ñang Edit m t record hi n h u hay thêm m t Record m i. Ta ch a tr s Boolean y trong variable AddNewRecord. N u user s p thêm m t record m i thì AddNewRecord = True, n u User s p Edit m t record hi n h u thì AddNewRecord = False. Ngoài ra, khi User s p thêm m t record m i b ng cách click nút New thì ta ph i t clear (làm tr ng) h t các textboxes b ng cách assign Empty string vào text property c a chúng như sau:
' If Editing existing record then AddNewRecord = False ' Else AddNewRecord = true Dim AddNewRecord As Boolean Private Sub ClearAllFields() ' Clear all the textboxes txtTitle.Text = "" txtYearPublished.Text = "" txtISBN.Text = "" txtPublisherID.Text = "" End Sub Private Sub cmdNew_Click() ' Remember that this is Adding a new record AddNewRecord = True ' Clear all textboxes ClearAllFields ' Place controls in Edit Mode SetControls (True) End Sub Private Sub CmdEdit_Click() ' Place controls in Edit Mode

204

SetControls (True) ' Remember that this is Editing an existing record AddNewRecord = False End Sub

N u user clicks Cancel trong khi ñang edit các textboxes, ta không c n g i method CancelUpdate vì Recordset chưa b ñ t vào AddNew hay Edit mode. ñây ta ch c n hi n th l i chi ti t c a current record, t c là h y b nh ng gì user ñang ñánh vào:

Private Sub CmdCancel_Click() ' Cancel update SetControls (False) ' Redisplay details or current record Displayrecord End Sub

Lúc user clicks Update, b n có d p ñ ki m tra data xem có field nào b b tr ng (nh t là Primary Key ISBN b t bu c ph i có tr s ) hay có gì không valid b ng cách g i Function GoodData. N u GoodData tr l i m t tr s False thì ta không xúc ti n v i vi c Update. N u GoodData tr v tr s True thì ta ñ t Recordset vào AddNew hay Edit mode tùy theo tr s c a Boolean variable AddNewRecord. Gi ng như khi hi n th chi ti t c a m t Record ta ph i assign t ng Field vào textbox, thì bây gi khi Update ta ph i làm ngư c l i, t c là assign property Text c a t ng textbox vào Record Field tương ng. Sau cùng ta g i method Update c a recordset và cho các controls tr l i Browse mode:

Private Function GoodData() As Boolean ' Check Data here. If Invalid Data then GoodData = False GoodData = True End Function Private Sub CmdUpdate_Click() ' Verify all data, if Bad then do not Update If Not GoodData Then Exit Sub ' Assign record fields to the appropriate textboxes

205

With myRS If AddNewRecord Then .AddNew ' Place Recordset in AddNew Mode Else .Edit ' Place Recordset in Edit Mode End If ' Assign text of txtTitle to field Title .Fields("Title") = txtTitle.Text .Fields("[Year Published]") = txtYearPublished.Text .Fields("ISBN") = txtISBN.Text .Fields("PubID") = txtPublisherID.Text ' Update data .Update End With ' Return controls to Browse Mode SetControls (False) End Sub

Cũng vì không có Data Binding, nên khi User Delete m t record, sau khi di chuy n qua record k ti p ta ph i t hi n th chi ti t c a record ñó như sau:

Private Sub CmdDelete_Click() On Error GoTo DeleteErr With myRS ' Delete new record .Delete ' Move to next record .MoveNext If .EOF Then .MoveLast ' Display details of current record Displayrecord Exit Sub End With DeleteErr: MsgBox Err.Description Exit Sub End Sub

Tìm m t record
Ti p theo ñây, ta mu n li t kê các sách có tiêu ñ ch a m t ch hay câu nào ñó, thí d như ch "Guide". K ñó user có th ch n m t sách b ng cách select tiêu ñ sách y và click nút Go. Chương trình s locate (tìm ra) record c a sách y và hi n th chi ti t c a nó.

206

Bây gi b n hãy cho vào Form m t textbox tên txtSearch và m t Image tên ImgSearch. K ñó ñ t m t frame tên fraSearch vào Form. ð lên frame n y m t listbox tên List1 ñ hi n th tiêu ñ các sách, và hai buttons tên CmdClose và CmdGo, v i caption Close và Go. Sau khi select m t sách trong List1, user s click nút Go ñ hi n th chi ti t sách y. N u ñ i ý, user s click nút Close ñ làm bi n m t frame fraSearch. Bình thư ng frame fraSearch ch hi n ra khi c n, nên lúc ñ u hãy set property Visible c a nó thành False. Ta s cho ImgSearch hi n th hình m t ng dòm nên b n hãy click vào bên ph i property Picture trong Properties Window ñ ch n Icon BINOCULR.ICO t folder E:\Program Files\Microsoft Visual Studio\Common\Graphics\Icons\Misc:

Cái Primary Key c a table Titles là ISBN. Khi user select m t sách ta mu n bi t ISBN c a sách y ñ locate (ñ nh ch ) nó trong Recordset myRS. Do ñó trong khi thêm tiêu ñ c a m t sách vào List1, ta ñ ng th i thêm ISBN c a sách y vào m t Listbox th hai tên List2. Ta ch s dùng List2 sau h u trư ng, nên hãy set property Visible c a nó thành False. Dư i ñây là code ñ load tiêu ñ sách và ISBN vào các Listboxes:
Private Sub ImgSearch_Click() ' Show Search Frame fraSearch.Visible = True Dim SrchRS As DAO.Recordset Dim SQLCommand As String ' Define SQL statement SQLCommand = "Select * from Titles where Title LIKE '" & "*" & txtSearch & "*" & "'

207

ORDER BY Title" ' Fetch all records having Title containing the text pattern given by txtSearch Set SrchRS = myDB.OpenRecordset(SQLCommand) ' If Recordset is not Empty then list the books' titles in List1 If SrchRS.RecordCount > 0 Then List1.Clear ' Clear List1 ' We use List2 to contain the Primary Key ISBN corresponding to the books in List1 List2.Clear ' Clear List2 With SrchRS ' Iterate through the Recordset until EOF Do While Not SrchRS.EOF ' Display Title in List1 List1.AddItem .Fields("Title") ' Store corresponding ISBN in List2 List2.AddItem .Fields("ISBN") .MoveNext ' Move to next record in the Recordset Loop End With End If End Sub

Khi user Click ImgSearch v i text pattern là ch Guide, ta s th y hình dư i ñây:

Trong SELECT statement bên trên ta dùng operator LIKE trên text pattern, ch Guide, có wildcard character (*) hai bên. Wildcard character là ch có (hay không có) ch gì cũng ñư c. Trong trư ng h p n y có nghĩa là h có ch Guide trong tiêu ñ sách là ñư c, không c n bi t nó n m ñâu. Ngoài ra s ch n l a n y Không có Case Sensitive, t c là ch guide, Guide hay GUIDE ñ u ñư c c . Khi user clicks nút Go, ta s dùng method FindFirst c a Recordset myRS ñ ñ nh ch c a record có tr s Primary Key là hàng text trong List2 tương ng v i tiêu ñ dư c ch n trong List1 như sau:

208

Private Sub CmdGo_Click() Dim SelectedISBN As String Dim SelectedIndex As Integer Dim Criteria As String ' Index of line selected by user in List1 SelectedIndex = List1.ListIndex ' Obtain corresponding ISBN in List2 SelectedISBN = List2.List(SelectedIndex) ' Define Search criteria - use single quotes for selected text Criteria = "ISBN = '" & SelectedISBN & "'" ' Locate the record, it will become the current record myRS.FindFirst Criteria ' Display details of current record Displayrecord ' Make fraSearch disappeared fraSearch.Visible = False End Sub

Lưu ý là trong string Criteria, vì ISBN thu c lo i text, ch không ph i là m t con s , nên ta ph i k p nó gi a hai d u ngo c ñơn.

Bookmark
Khi di chuy n t record n y ñ n record khác trong Recordset, ñôi khi ta mu n ñánh d u v trí c a m t record ñ có d p s tr l i. Ta có th th c hi n ñi u y b ng cách ghi nh Bookmark c a Recordset. Thí d khi user clicks nút Go, ta mu n nh v trí c a record lúc y ñ sau n y quay tr l i khi User clicks nút Go Back. B n hãy thêm vào Form m t button tên CmdGoBack v i Caption Go Back. Ta s thêm m t variable tên LastBookmark lo i data type Variant:
Dim LastBookMark As Variant

Lúc ñ u button CmdGoBack invisible, và ch tr nên visible sau khi user clicks nút Go. Ta thêm các hàng codes sau vào Sub CmdGo_Click() như sau:

' Remember location of current record LastBookMark = myRS.BookMark CmdGoback.Visible = True

Dư i ñây là code ñ quay tr l i v trí current record trư c ñây trong Recordset:
Private Sub CmdGoback_Click()

209

' Reposition record to last position myRS.BookMark = LastBookMark ' Redisplay details or current record Displayrecord End Sub

LastModified
LastModified là vi tr c a record v a m i ñư c s a ñ i hay thêm vào trong Recordset. ð th ñi u n y b n hãy thêm m t button invisible tên CmdLastModified v i caption là Last Modified. Button n y ch hi n ra sau khi user clicks Update. B t c lúc nào b n Click nút CmdLastModified, record m i v a ñư c s a ñ i hay thêm vào s hi n th :
Private Sub CmdLastModified_Click() ' Reposition record to last position myRS.BookMark = myRS.LastModified ' Redisplay details or current record Displayrecord End Sub

Dư i ñây là hình c a Form lúc ñang ñư c thi t k :

Ta s h c k thu t ADO (ActiveX Data Object) trong bài t i.

Chương Mư i Sáu - L p trình v i ADO (ph n I)
Control Data ADO
210

Visual Basic 6 cho ta s l a ch n v k thu t khi l p trình v i database, ho c là dùng DAO như trong hai bài trư c, ho c là dùng ADO (ActiveX Data Objects). S khác bi t chính gi a ADO và DAO là ADO cho phép ta làm vi c v i m i lo i ngu n d ki n (data sources), không nh t thi t ph i là Access database hay ODBC. Ngu n d ki n có th là danh sách các ñ a ch Email, hay m t file text string, trong ñó m i hàng là m t record g m nh ng fields ngăn cách b i các d u ph y (comma separated values). N u trong DAO ta dùng th ng tên c a MSAccess Database thì trong ADO cho ta n i v i (connect) m t database qua m t Connection b ng cách ch ñ nh m t Connection String. Trong Connection String có Database Provider (thí d như Jet, ISAM, Oracle, SQLServer..v.v.), tên Database, UserName/Password ñ logon m t database .v.v.. Sau ñó ta có th l y v (extract) nh ng recordsets, và c p nh t hóa các records b ng cách dùng nh ng l nh SQL trên các tables hay dùng nh ng stored procedures bên trong database. Bình thư ng, khi ta m i kh i ñ ng m t project VB6 m i, Control Data ADO không có s n trong IDE. Mu n có nó, b n hãy dùng Menu Command Project | Components..., r i ch n Microsoft ADO Data Control 6.0 (OLEDB) t giao di n Components như dư i ñây:

B n hãy b t ñ u m t d án VB6 m i, cho nó tên ADODataControl b ng cách click tên project trong Project Explorer bên ph i r i edit property Name trong Properties Window. S a tên c a form chính thành frmADO, và ñánh câu ADO DataControl Demo vào Caption c a nó. DoubleClick lên Icon c a Control Data ADO trong Toolbox. M t Control Data ADO tên Adodc1 s hi n ra trên Form. Mu n cho nó n m bên dư i Form, gi ng như m t StatusBar, hãy set property Align c a nó trong Properties Window thành 2 - vbAlignBottom. Click bên ph i hàng property (Custom), k ñó click lên nút browse có ba ch m ñ giao tho i Property Pages hi n ra. Trong giao tho i n y, trên Tab General ch n Radio (Option) Button Use Connection String r i click nút Build....

211

Trong giao tho i Data Link Properties, Tab Provider, ch n Microsoft Jet 3.51 OLE DB Provider, r i click nút Next >> hay Tab Connection.

212

ch Select or enter a database name ta ch n E:\Program Files\Microsoft Visual Studio\VB98\BIBLIO.MDB, trong computer c a b n có th file y n m trên disk C hay D. Sau ñó, b n có th click nút Test Connection phía dư i ñ th xem connection có ñư c thi t l p t t không.

L p connection xong r i, ta ch ñ nh mu n l y gì v làm Recordset b ng cách click property Recordsource c a Adodc1. Trong giao di n Property Pages c a nó ch n 2-adCmdTable làm Command Type, k ñó m Combo box cho Table or Stored Procedure Name ñ ch n table Titles.

Tùy theo cách ta dùng Recordset trong ADO, nó có ba lo i và ñư c g i là Cursor Type. Cursor ch ng qua là m t tên khác c a Recordset:

Static Cursor: Static Cursor cho b n m t static copy (b n sao c ng ng c) c a các records. Trong lúc b n dùng Static Cursor, n u có ai khác s a ñ i hay thêm, b t gì vào recordset b n s không th y. Keyset Cursor: Keysey Cursor hơn Static Cursor ch trong lúc b n dùng nó, n u có ai s a ñ i record nào b n s bi t. N u ai delete record nào, b n s không th y nó n a. Tuy nhiên b n s không bi t n u có ai thêm m t record nào vào recordset.

213

Dynamic Cursor: Như ch s ng ñ ng (dynamic) hàm ý, trong lúc b n ñang dùng m t Dynamic Cursor, n u có ai khác s a ñ i hay thêm, b t gì vào recordset b n s th y h t. B n hãy ch n tr s 2-adOpenDynamic cho property Cursor Type c a Adodc1:

Bây gi b n hãy ñ t lên Form 4 labels v i captions: Title, Year Published, ISBN và Publisher ID. K ñó cho thêm 4 textboxes tương ng và ñ t tên chúng là txtTitle, txtYearPublished, txtISBN và txtPublisherID. ð th c hi n Data Binding, b n hãy ch n textbox txtYearPublished (năm xu t b n), r i set property Datasource c a nó trong Properties Window thành Adodc1. Khi click lên property DataField c a txtYearPublished và m ComboBox ra b n s th y li t kê tên các Fields trong table Titles. ðó là vì Adodc1 ñư c coi như trung gian l y table Titles t database. ñây ta s ch n c t Year Published. L p l i công tác n y cho 3 textboxes kia, và ch n các c t Title (Tiêu ñ ), ISBN (s lý l ch trong thư vi n qu c t ), và PubID (s lý l ch nhà xu t b n) làm DataField cho chúng.

214

ð n ñây, m c d u chưa vi t m t hàng code nào, b n có th ch y chương trình và nó s hi n th như dư i ñây:

B n có th t i v chương trình dùng Control Data ADO n y t ñây ADODatacontrol.zip.

Data Form Wizard
ð giúp l p trình viên thi t k các data forms nhanh hơn, VB6 cho ta Data Form Wizard ñ generate (phát sinh) ra m t form có h tr Edit, Add và Delete records. Bây gi b n hãy kh i ñ ng m t standard project VB6 m i, tên ADOClass và copy MS Access file BIBLIO.MDB, t c là database, vào trong cùng folder c a d án m i n y. Mu n dùng Data Form Wizard, trư c h t ta ph i thêm nó vào môi trư ng phát tri n (IDE) c a VB6. B n hãy dùng IDE Menu Command Add-Ins | Add-In Manager.... Ch n VB6 Data Form Wizard trong giao tho i, r i click Checkbox Loaded/Unloaded ñ ch Loaded hi n bên ph i hàng "VB6 Data Form Wizard" như trong hình dư i ñây:

N u b n mu n m i l n kh i ñ ng VB6 IDE là có s n Data Form Wizard trong menu Add-Ins thì ngoài option Loaded, b n click thêm check box Load on Startup. M t Add-In là m t menu Item m i mà ta có th thêm vào m t chương trình ng d ng có s n.

215

Thư ng thư ng, ngư i ta dùng Add-Ins ñ thêm ch c năng cho m t chương trình, làm như là chương trình ñã có s n ch c năng y t ñ u. B n hãy kh i ñ ng Data Form Wizard t IDE Menu Command m i Add-Ins | Data Form Wizard...

Khi trang Data Form Wizard - Introduction hi n ra, click Next

Trong trang k ñó ch n Access làm Database Type.

216

Trong trang Database, click Browse ñ ch n m t MS Access database file. BIBLIO.MDB t chính folder c a chương trình n y. ðo n click Next.

ñây ta ch n file

Trong trang Form, ta ch n Single Record cho Form Layout và Class cho Binding Type. ðo n click Next. N u ta ch n ADO Data Control thì k t qu s gi ng gi ng như khi ta dùng Control Data DAO như trong m t bài trư c.

Trong trang Record Source ta ch n table Titles. Listbox c a Available Fields s hi n th các fields c a table Titles. Sau khi ch n m t field b ng cách click lên tên field y trong Listbox, n u b n click hình tam giác ch qua ph i thì tên field y s ñư c d i qua n m dư i cùng trong Listbox Selected Fields bên ph i. N u b n click hình hai tam giác ch qua bên ph i thì t t c m i fields còn l i bên trái s ñư c d i qua bên ph i. B n cũng có th s p ñ t v trí c a các selected fields b ng cách click lên tên field y r i click hình mũi tên ch lên hay xu ng ñ di chuy n field y lên hay xu ng trong danh sách các fields.

217

Ngoài ra, b n hãy ch n Title làm Column to Sort By trong cái Combobox c a nó ñ các records trong Recordset ñư c s p x p theo th t ABC (alphabetical order) c a field Tiêu ñ (Title).

Trong trang Control Selection, ta s ñ y nguyên ñ có ñ m i buttons. B n hãy click Next.

Khi Data Form Wizard ch m d t, nó s generate form frmADODataForm. B n hãy remove Form1 và dùng Menu Command Project | ADODataControl Properties... ñ ñ i Startup Object thành frmADODataForm. Th là t m xong chương trình ñ Edit các records c a table Titles.

218

Chúng ta hãy quan sát cái Form và ph n code ñư c Data Form Wizard generated. Trong frmADODataForm, các textboxes làm thành m t array tên txtFields. M i textbox ñ u có property DataField ñ nh s n tên field c a table Titles. Thí d như txtFields(2) có DataField là ISBN. Form chính không dùng Control Data ADO nhưng dùng m t Object c a class clsTitles. Ph n Initialisation c a class clsTitles là Open m t Connection và l y v m t Dataset có tên DataMember là Primary như sau: Private Sub Class_Initialize() Dim db As Connection Set db = New Connection db.CursorLocation = adUseClient ' Open connection db.Open "PROVIDER=Microsoft.Jet.OLEDB.3.51;Data Source=E:\Websites\Vovisoft\VisualBasic\ADOForm\BIBLIO.MDB;" ' Instantiate ADO recordset Set adoPrimaryRS = New Recordset ' Retrieve data for Recordset adoPrimaryRS.Open "select Title,[Year Published],ISBN,Description,Notes,PubID from Titles Order by Title", _ db, adOpenStatic, adLockOptimistic ' Define the only data member, named Primary DataMembers.Add "Primary" End Sub V v trí c a database, n u b n không mu n nó ch t c ng m t folder nào thì dùng App.Path ñ xác ñ nh m i liên h gi a v trí c a database và folder c a chính chương trình ñang ch y, thí d như:

db.Open "PROVIDER=Microsoft.Jet.OLEDB.3.51;Data Source=" & App.Path & "\BIBLIO.MDB;" Trong Sub Form_Load, ta có th dùng For Each ñ ñi qua h t các textboxes trong array txtFields. Vì property Datasource c a textbox là m t Object nên ta dùng keyword Set ñ point

219

nó ñ n Object PrimaryCLS. ð ng th i ta cũng ph i ch ñ nh tên c a DataMember c a m i textbox là Primary: Private Sub Form_Load() ' Instantiate an Object of class clsTitles Set PrimaryCLS = New clsTitles Dim oText As TextBox ' Iterate through each textbox in the array txtFields 'Bind the text boxes to the data source, i.e. PrimaryCLS For Each oText In Me.txtFields oText.DataMember = "Primary" ' Use Set because property Datasource is an Object Set oText.DataSource = PrimaryCLS Next End Sub Khi s di chuy n t record n y ñ n record khác ch m d t, chính Recordset có raise Event MoveComplete. Event y ñư c handled (gi i quy t) trong class clsTitles b ng cách l i raise Event MoveComplete ñ nó ñư c handled trong Form. Mu n handle Event trong clsTitles ta ph i declare recordset adoPrimaryRS v i WithEvents:

Dim WithEvents adoPrimaryRS As Recordset Private Sub adoPrimaryRS_MoveComplete(ByVal adReason As ADODB.EventReasonEnum, _ ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, ByVal pRecordset As ADODB.Recordset) ' Raise event to be handled by main form RaiseEvent MoveComplete End Sub Và trong Form ta cũng ph i declare (object clsTitles) PrimaryCLS v i WithEvents: Private WithEvents PrimaryCLS As clsTitles Trong Form, Event MoveComplete s làm hi n th v trí tuy t ñ i (Absolute Position) c a record b ng code dư i ñây:

Private Sub PrimaryCLS_MoveComplete() 'This will display the current record position for this recordset lblStatus.Caption = "Record: " & CStr(PrimaryCLS.AbsolutePosition) End Sub

220

Khi user clicks Refresh, các textboxes s ñư c hi n th l i v i chi ti t m i nh t c a record t trong recordset, nh khi có ai khác ñã s a ñ i record. Method Requery c a clsTitles l i g i method Requery c a Recordset như sau:

Private Sub cmdRefresh_Click() 'This is only needed for multi user applications On Error GoTo RefreshErr ' fetch the latest copy of Recordset PrimaryCLS.Requery Exit Sub RefreshErr: MsgBox Err.Description End Sub 'In Class clsTitles Public Sub Requery() ' Fetch latest copy of record adoPrimaryRS.Requery DataMemberChanged "Primary" End Sub

221

Sign up to vote on this title
UsefulNot useful