DataCombo และ DataList
Visual Basic 6 ได้เพิ่ม DataCombo และ DataList ซึ่งเป็น bound control (เป็นตัว control ที่ต้องรวมกับข้อมูล) ตัว control กลุ่มนี้แตกต่างจาก List box และ Combo box เพราะสามารถรวมกับ ADO Data control ที่ต่างกัน 2 ตัว control โดย Data control แรกหาค่าที่เลือกในตัว control (เช่นเดียวกับ List box และ Combo box) และ Data control ที่สองเป็นการเพิ่มข้อมูลเข้ามาเป็นรายการ
DataCombo และ DataList มี lookup ที่ใช้ในการแปลงคำสั่งให้เป็นฟอร์ม เช่น การเลือกข้อมูลจาก table "Products" ในฐานข้อมูล Nwind.mdb โดยให้ฟิลด์ CategoryID มีค่าตรงกับฟิลด์ CategoryID ของ table "Categories" เพื่อแสดงสารสนเทศของสินค้า ด้วยการใช้คำสั่ง INNER JOIN ในการดึงข้อมูลทั้งหมด
SELECT ProductName,CategoryName FROM Products INNER JOIN Categories
ON Products.CategoryID = Categories.CategoryID
คำสั่งข้างต้นสามารถใช้ได้กับการประมวลผลข้อมูลด้วยคำสั่ง แต่ไม่สามารถใช้ได้กับตัว control แบบ bound เช่น เมื่อมีการให้ผู้ใช้สามารถปรับปรุงค่าในฟิลด์ CategoryID ของสินค้าจะต้องมีการอินเตอร์เฟซให้มีการ โหลดข้อมูลจาก Table "Categories" ไปสู่ List box หรือ Combo box เพื่อทำให้ผู้ใช้ไม่สามารถป้อนชื่อ Category ที่ผิด ซึ่งจำเป็นต้องมีการเปิด Recordset อันดับสอง
Dim rsCat As New ADODB.Recordset
rsCat.Open "SELECT ProductName,CategoryName FROM Categories",
cn
lstCategories.Clear
Do until rsCat.EOF
lstCategories.AddItem rsCat("CategoryName")
lstCategories.ItemData (lstCategories.NewIndex) = rsCat("CategoryID")
Loop
rsCat.Close
การแสดงค่าลักษณะดังกล่าวทำได้สะดวกใน DataCombo และ DataList ด้วยการตั้งค่า คุณสมบัติจำนวนหนึ่งในเวลาออกแบบ
DataCombo และ DataList อยู่ในไฟล์ MSDATLST.ocx ซึ่งต้องกระจายไปกับโปรแกรมประยุกต์ที่ใช้ตัว control นี้
Note: DataCombo และ DataList มีการทำงานคล้ายกับ DbCombo และ DbList (แนะนำใน Visual Basic 5) แต่ต่างกันที่ DataCombo และ DataList ทำงานกับ ADO Data control ส่วน DbCombo และ DbList ทำงานกับ Data control และ Remote Data control
การตั้งคุณสมบัติเมื่อออกแบบ
การประยุกต์เครื่องมือ lookup table กับ DataCombo และ DataList จำเป็นต้องวาง ADO Data control 2 ตัวลงบนฟอร์ม ตัวหนึ่งสำหรับชี้ไปที่ table หลัก (ตามตัวอย่างคือ Products ) และอีกตัวชี้ไปที่ lookup table (ตามตัวอย่างคือ Categories ) แล้วตั้งค่าคุณสมบัติ ดังนี้
- DataSource อ้างถึง ADO Data control หลัก ที่ชี้ไปยัง table หลัก
- DataField เป็นชื่อของฟิลด์ใน Table ที่อ้างถึงโดยคุณสมบัติ DataSource และเป็นข้อมูลที่รวมกับตัว control ฟิลด์ที่จะได้รับการปรับปรุงเพื่อค่าใหม่ ได้รับการเลือกในรายการ
- RowSource เป็นการอ้างถึง ADO Data control ตัวที่สอง ที่ชี้ไปยัง lookup table แสดงรายการของตัว control ที่จะได้รับการเติมข้อมูลจาก lookup table
- BoundColumn เป็นชื่อของฟิลด์ใน lookup table เพื่อผู้ใช้เลือกค่าในรายการฟิลด์ DataField ใน table หลักจะได้รับค่าจากคอลัมน์นี้ ถ้าไม่กำหนดค่าให้คุณสมบัตินี้ จะใช้ชื่อฟิลด์เดียวกับคุณสมบัติ ListField
1. ให้สร้างADO Data control (adodc1) ตั้งค่าชี้ไปที่ table "Products" ของฐานข้อมูล NWind.mdb ในแท็บ RecordSource ของ Property Pages
แล้วเพิ่ม Text box จำนวนหนึ่งเพื่อแสดงข้อมูลของฟิลด์ จาก table โดย Text box ทุกตัวให้กำหนด DataSouce เป็น Adodc1 ส่วน DataField ขึ้นกับการแสดงข้อมูลของฟิลด์ เช่น ชื่อสินค้า ให้กำหนดด้วยฟิลด์ "ProductName" ราคาต่อหน่วยกำหนดด้วยฟิลด์ "UnitPrice"
2. ADO Data control อีก 1 ตัว (Adodc2) และตั้งค่าให้ดึงข้อมูลจาก table "Categories" แล้วเพิ่ม DataList ตั้งชื่อว่า "dblCategory" และตั้งคุณสมบัติตามนี้ DataSource = adodc1, DataField = CategoryID, RowSource = adodc2, BoundColumn = CategoryID, ListField = CategoryName
3. ใน table "Products" มี Foreign key คือ SupplierID ซึ่ง Suppliers สามารถสร้างกลไกการ lookup คือ 1 ชุดโดยการเพิ่ม ADO Data control (Adodc3) ตั้งค่าชี้ไปที่ table "Suppliers" และ DataCombo ตั้งชื่อว่า "dblSupplier" และกำหนดคุณสมบัติดังต่อไปที่ DataSource = adodc1, DataField = SupplierID, RowSource = adodc3, BoundColumn = SupplierID, ListField = CompanyName
Note: DataCombo และ DataList มีคุณสมบัติอีก 2 อย่าง คือ DataMember และ RowNumber ซึ่งจะมีการกำหนดเมื่อใช้ อ๊อบเจค Command ของ DataEnvironment designer ในฐานะ data source หลักหรืออันดับที่สอง
การทำงานเมื่อเรียกใช้
การทำงาน DataCombo และ DataList ในเวลาเรียกใช้คล้ายกับ Combo box และ List box แต่มีความแตกต่างเล็กน้อย เช่น ไม่มีคุณสมบัติ ListIndex และ ListCount หรือ เมรอด AddItem สำหรับการเพิ่มข้อมูลในรายการ เมื่อเรียกใช้ การเพิ่มรายการทำได้ด้วยการใช้ ADO Data control หรือ แหล่งข้อมูลอื่น ๆ เช่น Recordset หรือ instance ของ DataEnvironment
DataCombo และ DataList มีคุณสมบัติพิเศษ ได้แก่ คุณสมบัติ MatchWithList ซึ่งเป็นคุณสมบัติอ่านอย่างเดียว ส่งออกค่า True ถ้าค่าที่ป้อนใน DataCombo ตรงกับข้อมูลในรายการ คุณสมบัตินี้เป็น True เสมอ ถ้าคุณสมบัติ Style ของ DataCombo และ DataList เป็น 2-dbcDropDownList คุณสมบัติ BoundText ส่งออกหรือตั้งค่าของชื่อฟิลด์ตามคุณสมบัติ BoundColumn ซึ่งเป็นค่าที่จะกำหนดให้กับคอลัมน์ DataField ใน table หลัก
' ในส่วนการประกาศของโมดูลฟอร์ม
Dim rsCategory As New ADODB.Recordset
Dim rsSupplier As New ADODB.Recordset
' ใน sub procedure
rsCategory.Open "Categories", adoProducts.Recordset.ActiveConnection, _
adOpenDynamic, adLockOptimistic
Set dblCategory.RowSource = rsCategory
rsSupplier.Open "Suppliers", adoProducts.Recordset.ActiveConnection, _
adOpenDynamic, adLockOptimistic
Set dbcSupplier.RowSource = rsSupplier
การแสดงสารสนเทศ lookup เบื้องต้น
คุณสมบัติ SelectedItem ส่งออก bookmark ไปที่ lookup table ที่ตรงกับข้อมูลที่ไฮไลต์ในรายการ ตามปกติการใช้คุณสมบัติเพื่อแสดงสารสนเทศเพิ่มเติมเกี่ยวกับข้อมูลที่เรียก
Private Sub dbcSupplier_Click(Area As Integer)
' ย้ายไปที่เรคคอร์ดที่ถูกต้องใน lookup table.
' หมายเหตุ: ฟิลด์ ContactName
' ต้องรวมอยู่ในรายการของฟิลด์ที่ส่งออกโดย adoProducts
ShowSupplierInfo
End Sub
Click และ Dblcick event ของ DataCombo รับพารามิเตอร์ Area เพื่อระบุตำแหน่งของตัว control ที่ได้รับการเลือก ค่าของพารามิเตอร์ได้แก่ 0-dbcAreaButton, 1-dbcAreaEdit และ 2-dbcAreaList
กรณีที่ไม่เกิดขึ้น Click event ของ DataCombo เมื่อมีการแสดงเรคคอร์ดในฟอร์ม การแก้ไขต้องใช้การจับ MouseComplete event ของ ADO Data control อันดับแรก
Private Sub adoProducts_MoveComplete(ByVal adReason As ADODB.EventReasonEnum, ByVal pError As ADODB.Error, _
adStatus As ADODB.EventStatusEnum, ByVal pRecordset As ADODB.Recordset)
' บังคับให้ปรับปรุง DataCombo
On Error Resume Next
dbcSupplier.BoundText = adoProducts.Recordset("SupplierID")
ShowSupplierInfo
End Sub
การบันทึก Connection
ADO Data control มีการใช้ทรัพยากร Connection น้อยกว่า Data control ซึ่งการติดต่อของ Data control ในกรณีที่เป็นหลาย Data control ไม่สามารถพื้นที่เดียวกับของทรานแซคชัน และแต่ละ Connection ต้องใช้ทรัพยากรของเครื่องแม่ข่าย ในขณะที่ ADO Data control ลดการใช้ทรัพยากรลง เช่น DataCombo และ DataList ไม่จำเป็นต้องมองเห็น Data control เพราะผู้ใช้ไม่เคยเลื่อนดู lookup table ดังนั้น สามารถให้ผลลัพธ์เดียวกันด้วยการใช้อ๊อบเจค ADO Recordset ตั้งค่าคุณสมบัติของ DataCombo และ DataList ให้รวม ADO Data control สำหรับ lookup table แต่ทำให้คุณสมบัติ RowSource ว่างโดยการกำหนดคุณสมบัตินี้ในเวลาเรียกใช้หลังจากการสร้าง
อ๊อบเจค Recordset ใช้ Connection ร่วมกับ ADO Data control หลัก
' ในส่วนการประกาศของโมดูลฟอร์ม
Dim rsCategory As New ADODB.Recordset
Dim rsSupplier As New ADODB.Recordset
Private Sub Form_Load()
adoProducts.ConnectionString = "Provider=Microsoft.Jet.OLEDB.3.51; Persist Security Info=False;Data Source=" & DB_PATH
adoProducts.Refresh
rsCategory.Open "Categories", adoProducts.Recordset.ActiveConnection, adOpenDynamic, adLockOptimistic
Set dblCategory.RowSource = rsCategory
rsSupplier.Open "Suppliers", adoProducts.Recordset.ActiveConnection, adOpenDynamic, adLockOptimistic
Set dbcSupplier.RowSource = rsSupplier
ShowSupplierInfo
' เริ่มต้นทรานแซคชัน
adoProducts.Recordset.ActiveConnection.BeginTrans
IsDirty = False
End Sub
ดาวน์โหลดตัวอย่าง (CboSample.vbp)
ดาวน์โหลดตัวอย่าง (DataCbo.vbp)
|