วันอาทิตย์ที่ 13 กุมภาพันธ์ พ.ศ. 2554

4 : สร้าง MENU แบบมืออาชีพ ด้วย FORM

วัตถุประสงค์

ทำความรู้จัก Form Object  และการใช้ Form มาสร้างเป็นโปรแกรมสำคัญๆ ในระบบ   

เนื้อหา

Form เป็นส่วนสำคัญของ Access ที่เราจะนำมาสร้างเป็นโปรแกรมของเรา  โดยเนื้อแท้ Form ของ Access ก็เป็น Forms object แบบหนึ่ง   ท่านที่เคยใช้ VB จะพบว่า Form ของ Access จะคล้าย VB 6 เอามากมาก  แต่จะถูกเสริม  Properties , Method, Event  ที่เกี่ยวกับงาน Database มากกว่า
Properties คืออะไร
                Properties เป็นค่าคุณลักษณะของ  Object ไม่ว่าจะเป็น Form หรือ Control ที่อยู่บน Form   ความจริงทุกท่านได้เคยใช้ Properties มาบ้างแล้ว   เพราะทันที ที่เราสร้าง Form ใหม่ 1 Form  เราก็จะพบว่า Form พวกนี้ มีค่า Properties ที่ถูกตั้งเป็น Default มาให้เราแล้ว รวมไปถึงการนำ Control ต่างๆ มาปะบร Form  
การเปลี่ยนค่าต่างๆ โดยไม่เขียนโปรแกรมนั้น  เราก็จะไปเปลี่ยนผ่าน Properties  Windows ของมัน  คราวนี้ เราจะมาเขียน VBA เพื่อไปเปลี่ยนค่า Properties เหล่านี้ เพื่อให้ทำงานที่เราต้องการ  มาลองปรับ Propeties ตาม ตย นี้ดูครับ
            ภาพแสดงการทำปุ่มเพื่อทดสอบการเปลี่ยน Properties ของ Form จาก VBA

1.       สร้าง Form เปล่ามา 1 Form อย่าใช้ Wizard ในการเสก Form นะครับ
2.       วางปุ่ม 4 ปุ่มลงบน Form น่าจะได้ชื่อปุ่ม เป็น command0-command3
3.       ลองใส่ code ที่ตามภาพดูครับ โดยการ Click ขวาที่ปุ่มแล้วเลือก Buidl Event
code ที่ติดลงไปในปุ่มทั้ง 4 เป็นการเปลี่ยนค่า Properties ใน Form 4 แบบครับ มีข้อสังเกตุคือ
-       แบบที่ 1 ที่ใช้คำว่า Me เป็นการบอกให้ใช้ Form ปัจจุบันใช้กับกรณีที่เรา Set ค่าต่างๆ บน Form ของตัวเอง   ถ้าอ้างถึงค่าใน Form ที่เรากำลังเขียนโปรแกรม ควรใช้วิธีนี้นะครับ เพราะหากเราเปลี่ยนชื่อ form โปรแกรมก็ยังคงทำงานได้  
-        กรณีที่เราไปสั่ง Form ที่ไม่ใช่ Form ปัจจุบัน  ต้องใช้แบบที่ใช้ใน command 1-3  แบบที่ 4 ที่อยู่ command3 เป็นแบบที่แนะนำครับ  เพราะเขียนโปรแกรมง่ายและสามารถผ่านตัวแปรได้ด้วย    เช่น ตยนี้ เราใส่ชื่อ Form ไว้ในตัวแปร fname แล้วไปทำการเปลี่ยนค่า caption
Dim fName
FName = “prgTest”
Forms(Fname).caption = “hello”


Forms(“prgTest”).caption
ระบุชื่อ Form ลงในวงเล็บ และมี เครื่องหมาย คลุม ตามด้วย . และชื่อ Control แบบนี้เป็นแบบที่นิยมใช้มากที่สุด

Forms(0).caption
แบบนี้ใช้ดัชนีที่เป็นตัวเลขระบุ Form เลขที่เป็นลำดับที่ของ Form ที่เปิดอยู่  ขฯะนั้น  ไม่นิยมใช้ เพราะไม่ทราบแน่ว่า Form ที่กำลังอ้างอิงถูกเปิดเป็นลำดับที่เท่าไรแน่ๆ

Forms!prgTest.caption
ใช้เครื่องหมาย ! เพื่อให้ทราบว่าตัวที่ตามหลังเป็นชื่อ Form  สะดวก และสั้น แต่ไม่สามารถใช้งานได้ในกรณีที่ชื่อ Form มี ช่องว่างเช่น Form ชื่อ Sample 1 เป็นต้น

Forms![prgTest].caption
เป็นแบบที่ใช้มาแก้ไข กรณีที่ 3 สามารถกำหนดชื่อ Form ที่มีช่องว่างได้ โดยใช้เครื่องหมายปีกกา คลุม

ทำ Form เปล่าๆ จริงๆ
                ค่า Properties ที่ได้ทำการเขียนโปรแกรมไว้ข้างต้นเป็นการทำให้ Form Access กลายเป็น Form ของพวก VB ทั่วๆ ไปทันที   โดยการปิดค่า Properties ชื่อ  RecordSelectors, DividingLines , NavigationButtons  ค่า Properties อื่นของ Form มีอยู่มากทีเดียวคงเล่าให้ฟังไม่หมด แต่เชื่อว่าทุกท่านสามารถทดลองตั้งปรับเปลี่ยนได้เอง  ชื่อที่ปรากฎใน Properties Sheet ก็จะเหมือนที่จะเขียน โปรแกรมใน VBA เพียงแต่ ใน VBA จะไม่เว้นว่างระหว่างชื่อ Properties เท่านั้นเอง  แนะนำให้ทดลองเปลี่ยน Properties ชื่อ AutoCenter, AutoResize, ScrollBars ดูนะครับ

ทำ Form สำหรับ Search ข้อมูล
            เราจะมาลองทำ Form ค้นหาหาขอมูลง่ายๆ กันครับ  โดยการใช้ Properties Fileter มาช่วยในค้นหาข้อมูล   ขอใช้ northwind.mdb ซึ่งเป็น MDB ตัวอย่างที่มากับ Access 2003 เป็นตัวทดลองนะครับ  เรียก File นี้ โดยกด Help, Sample Database ครับ  สำหรับ Version อื่นจะอยู่ ใน Folder ที่ลง Access ครับ    โจทย์ข้อนี้ก็คือ เราจะต้องการค้น Supplier โดย User เลือกได้เองว่าจะค้นผ่าน Field ไหนก็ได้
                สร้าง Form ที่มี Supplier เป็น Table โดยไปกำหนดที่ Record Source ครับ แล้ววาง Control ที่มาจาก Database ( Field List ) ตามภาพ
1 สร้าง ORDERBY PROPERTIES
1.        สร้าง Combo Box ใหม่บน Form Header Cancel Wizard ( ถ้ามี )
2.        กำหนด Properties  ของ ComboBox: Name = OrderSelect, Row Source Type = Field List, Row Source = Suppliers ตามภาพ
3.        ใส่ Code ลงใน OrderSelect_AfterUpdate  ตามตัวอย่าง
Private Sub OrderSelect_AfterUpdate()
        Me.OrderBy = Me.OrderSelect
End Sub

ลอง Run Form และลองเปลี่ยน ลำดับการ Order ใน List Box จะพบว่า Form จะเปลี่ยนการเรียง หรือ Order By ตามที่เรากำหนด
2 สั่ง FILTER PROPERTIES
1.        สร้าง TextBox ชื่อ SearchMe ลงบน Form Header
2.        บรรจุ Code ลงใน AfterUpdate ของ SearchMe ตามตัวอย่าง
Private Sub SearchMe_AfterUpdate()
       Me.Filter = Me.OrderSelect & " Like '" & Me.SearchMe & "'"
       Me.FilterOn = True
End Sub
3.        ทดลอง Run Form
4.        เลือกค่า OrderBy Field ซึ่งในตัวอย่างใช้เป็น Field ที่ใช้ในการ Where ด้วย
5.        ระบุเงื่อนไขในการค้นหาเป็น WildCard
การต่อ String
ตัวอย่างนี้มีการต่อ String เพื่อใช้ในการ Where ข้อมูล  เนื่องจาก Field ที่ต้องการ Where เป็น String จึงต้องสร้าง String ที่มี เครื่องหมาย คลุมหัวท้าย  และมี  คลุมชุด String ทั้งหมด เพราะถ้าเราใช้ ทั้งหมด Access คงเข้าใจผิด เพราะหาทางจบคำสั่งคู่แรก ไม่พบ  จึงใช้เครื่องหมายแยกกัน
 สมมุติว่าเราต้องการค้นหา ContactName ที่มีคำว่า TO เราจะต้องสร้าง String ที่ระบุลงใน Filter เป็น “ContactName Like ‘*TO*’” ค่า  * TO * ได้มาจากตัวแปร Me.SearchMe และค่า Field ที่ Search ได้จาก Me.OrderSelect ทำให้เราต้องตัด String เป็นท่อนๆ ดังตัวอย่าง  ซึ่งจะเห็นว่าเป็น 4 ท่อนประกอบกัน คือ Me.ordrSelect  , “Like ‘” , Me.Searchme และ “’”
ทำ Sub Form  สำหรับบันทึกข้อมูล
                Classic case ของการโปรแกรมบันทึกข้อมูลคือ user อยากได้หน้าจอบันทึกข้อมูลแบบ Excel คือ เป็นลักษณะที่เป็น Data Sheet  แต่ก็มีคนแย้งผมเหมือนกัน ว่าหน้าตาหน้าจอแบบนี้ทำให้ User คีย์ง่ายไปมีโอกาศผิดพลาดสูง  ก็ใช้วิจารณาญานในการเลือกเป็นหน้าจอไปนะครับ  ถ้าโปรแกรมไหนต้องการความสะดวกเร็ว ควรจะใช้หน้าจอแบบนี้ในการบันทึก
วิธีการคือทำผมจะใช้ Form 2 Form มาบันทึกข้อมูลตาราง Product นะครับ
1.        สร้าง Form เปล่าสำหรับเป็น Form ลูกกำหนด Record Source เป็นตารางข้อมูล Product ตั้งชื่อ Form นี้ว่า prgProductSub
2.        ลากต่างๆ Field มาปะบน Form
3.        กำหนด Properties  ชื่อ Default View ให้เป็น Data sheet
4.        คราวนี้มาสร้าง Form แม่ ให้ชื่อว่า  prgProduct
5.        ปิด properties RecordSelectors, DividingLines , NavigationButtons ให้เป็น False ทั้งหมด
6.        ไปที่ Database Windows เพื่อลาก Form ลูกที่สร้างไว้ เมื่อสักครู่ ( prgProductSub ) มาปะ บน Form แม่  ซึ่งเป็นการสร้าง subForm แบบหนึ่ง
ท่านก็จะได้ Form บันทึกข้อมูล Product  แบบเป็น Data Sheet  ที่มี หน้ากากเป็น Form แม่มาครอบไว้  เป็น Form บันทึกข้อมูลแบบง่ายๆ    ครับคราวนี้ สังเกตุว่ามี Field ชื่อ Discontinued อยู่ ถ้าต้องการให้ โจทย์ข้อนี้ยากขึ้น  คืออยากให้มี Checkbox ให้เลือกรายการสินค้าที่  Discontinued แล้วหรือ ยัง Continued อยู่  , เราต้องยืมมือ VBA ซะละ
ภาพโปรแกรมที่เป็น Datasheet พร้อม การใช้ Check Box ในการสั่งให้ทำงาน

7.        สร้าง CheckBox  2 อันมาปะบนจอ  เอาไว้ตรง Form Header นะครับจะได้เป็นสัดเป็นส่วนกัน
8.        กำหนด Properties Default ของ Checkbox เป็น True เพื่อให้เข้ามาครั้งแรกแสดงทั้งหมดตามข้อมูลจริง
9.        ตั้งชื่อ Control CheckBox นี้เป็น chkCon, chkDiscon แล้วใส่ Caption หน่อยครับ
10.     ใส่โปรแกรมลงบน CheckBox ทั้ง 2 โดยการ Click ขวาที่ Control แล้วเลือก Build event  จะปรากฎ on_click  ให้ใส่ code ว่า  Call ChangeQuery ลงทั้ง 2 ตัว ( ดู ตย code ที่แสดงถัดมา )
11.     แล้วสร้าง sub มา 1 sub แล้วใส่โปรแกรมตามนี้ครับ

           Option Compare Database

Private Sub chkDiscon_Click()
        Call ChangeQuery
End Sub

Private Sub chkCon_Click()
        Call ChangeQuery
End Sub
Sub ChangeQuery()
    If Me.chkCon = False And Me.chkDiscon = True Then
       Me.prgProductSub.Form.Filter = "Discontinued=True"
       Me.prgProductSub.Form.FilterOn = True
       Me.prgProductSub.Visible = True
    End If

    If Me.chkCon = True And Me.chkDiscon = False Then
       Me.prgProductSub.Form.Filter = "Discontinued=False"
       Me.prgProductSub.Form.FilterOn = True
       Me.prgProductSub.Visible = True
    End If

    If Me.chkCon = True And Me.chkDiscon = True Then
       Me.prgProductSub.Form.Filter = ""
       Me.prgProductSub.Form.FilterOn = False
       Me.prgProductSub.Visible = True
    End If
   
    If Me.chkCon = False And Me.chkDiscon = False Then
        MsgBox "What should I display ?"
        Me.prgProductSub.Visible = False
    End If

End Sub
                โปรแกรมนี้ดูหรูขึ้นมาทันทีครับ เพราะมันปรับการแสดงรายการสินค้าได้เองตาม Checkbox ที่กดเลย

ทำ Form เป็น MENU
                สุดท้ายของบทนี้มาลองทำสร้าง FORM ที่เป็นเหมือน Menu ที่จะไปเรียก FORM อื่นๆกันครับ  ผมจะใช้ FORM  1 FORM ทีมี LIST BOX ให้ CLICK 2 ส่วน  มี Menu เป็น 2 ขั้นครับ กลุ่ม Menu และรายการ MENU ก็ต้องรบกวนให้สร้าง Table  2 TABLE สำหรับเก็บกลุ่ม Menu ( sysGroup ) และ รายการ Menu (sysMenu ) โดยมี Field ตามภาพครับ
ทดลองใส่ข้อมูลเข้าไปด้วยนะครับ ว่าจะให้ MENU ไปเปิดอะไรบ้าง  ผมใส่ชื่อ Table และ Form ที่เตรียมไว้ จะลองใส่ Table/ Form / Query / Report ที่มีใน Northwind อื่นๆ ก็ได้ครับ
            ภาพแสดงตารางข้อมูล sysGROUP และ sysMENU ที่ต้องสร้างขึ้น

                คราวนี้ลองสร้าง โปรแกรมกันครับ
1.        สร้าง Form เปล่า 1 FORM ปิด Properties พวก RecordSelectors, DividingLines , NavigationButtons, Scrollbar ให้หมดครับ
2.        วาง Control ที่เป็น ListBox 2 ตัว  ชื่อ lstGroup และ lstMenu ไม่ต้องใช้ Wizard นะครับ แล้วกำหนด Properties ตามนี้ครับ , ตรง RowSource ของ lstMenu จะดูยุ่งๆ หน่อย แต่ก็คือการให้ lstMenu หยิบรายการ MENU มาจาก lstGroup ที่กำลัง Click อยู่
Properties
LstGroup
LstMenu
RowSource
sysGROUP
SELECT sysMENU.GROUPID,
       sysMENU.MENUID,
       sysMENU.MEUNAME,
       sysMENU.MENUTYPE,
       sysMENU.CALLING
FROM sysMENU
WHERE (sysMENU.GROUPID=[lstGroup])
ORDER BY sysMENU.MENUID;
Column Count
2
2
Column Width
0; 2 Cm
0cm;0.501cm;4cm;1cm;2cm
Bound Coulumn
1
1
3.        ถ้าด้วยการปะ List Box 2 ตัว โปรแกรมจะเห็นการทำงานแล้วบ้างครับ  คือพอเปิดมาถ้า User เลือก กลุ่ม Menu รายการ Menu ก็จะเปลี่ยนตามเมื่อเรากด F9   ตรงนี้ละครับ, เราต้องใส่โปรแกรม VBA ลงไป ให้เจ้า lstMENU เปลี่ยนแปลงทุกครั้งเมื่อ lstGroup ปรับเปลี่ยนค่า  วิธีการก็คือคำสั่ง Requery ลงไปใน sysGroup  ให้ เขียน Code ลงใน lstGroup โดยการ Click ขวา แล้วเลือก Build Event
4.        เสร็จแล้วมาใส่โปรแกรมให้ โปรแกรมของเราไปเปิด Form/Table/Query/Report  ตรงนี้ไม่ยากเลยครับ ใช้เพียงคำสั่งตระกูล docmd.open  ให้ใส่ไว้ที่ Click ของ lstMENU โดยการเลือก BuildEvent เช่นกัน

Option Compare Database

Private Sub lstGroup_BeforeUpdate(Cancel As Integer)
        Me.lstMenu.Requery
End Sub

Private Sub lstMenu_BeforeUpdate(Cancel As Integer)
        Select Case Me.lstMenu.Column(3)
        Case "T"
            DoCmd.OpenTable Me.lstMenu.Column(4)
        Case "Q"
            DoCmd.OpenQuery Me.lstMenu.Column(4)
        Case "F"
            DoCmd.OpenForm Me.lstMenu.Column(4)
        Case "R"
            DoCmd.OpenReport Me.lstMenu.Column(4), acViewPreview
        End Select
End Sub

โปรแกรมจะตรวจสอบค่าที่อยู่ใน lstMENU ว่าจะเปิดอะไรจาก lstMenu แต่เนื่องจาก lstMenu มีหลาย Column การหยิบค่าจาก แต่ละ Column เราจะใช้ว่า lstMenu.Column(n)  โดย n เป็นลำดับที่ Column ตรงนี้ขึ้นตามที่เรา Select ไว้เป็น Row source ของ lsMenu  เราจะนับจาก 0 เป็น Column แรกนะครับ   ในที่นี้  column(3) ก็จะเก็บ รหัส Menutype ว่าเป็น  Table, Query, Form, หรือ Report แล้วใช้คำสั่งให้เหมาะกับประเภท  ส่วนชื่อที่จะไปเปิด จะอยู่ใน coumn(4) ก็ใช้เป็นชื่อตามหลัง docmd.openXXXX นั่งเองครับ

ทำ Form Search จาก Field
                ก่อนลากันในบทนี้  อยากให้ท่านลองแก้ไข Form prgProduct ให้มีความสามารถเพิ่มขึ้นครับ  โดยการนำแนวทางที่ใช้ในการทำหน้าจอค้นหามาช่วย  เพื่อให้หน้าจอบันทึกรายการสินค้า สามารถ Search ชื่อสินค้าในขณะกรอกได้ด้วย  ตรงนี้ไม่ยากครับ ก็เพิ่มการตรวจสอบ ใน ChangeQuery ให้ Filter มีการ Search ชื่อสินค้าไปพร้อมกันด้วย อาจใช้คำสั่ง Like ในการค้นครับ

ไม่มีความคิดเห็น:

แสดงความคิดเห็น

แสดงความคิดเห็น