หน้าแรก อุปกรณ์ที่ประกอบเป็นเครื่องคอมพิวเตอร์ เกาเหลาเทคนิคการใช้ HTML วิธีทำสร้าง Shortcut บน Desktop ปัญหาใหญ่ของ Data transfer
DAO และ Data Control
หัวข้อนี้จะแนวนำการใช้ VB กับฐานข้อมูล Access เริ่มตั้งแต่การสร้างฐานข้อมูล การเปิดใช้งาน การค้นหา การเพิ่ม แก้ไขและลบ เรคคอร์ด หวังว่าจะมีประโยช์นสำหรับผู้ที่เริ่มศึกษา
การสร้างฐานข้อมูล Access จาก VB
ตัวอย่างโปรแกรมให้ DownLoad
'1. กำหนดตัวแปร
Dim MyWs As Workspace
Dim MyDB As Database
Dim MyTable As TableDef '***สำหรับสร้างตาราง
Dim MyField(4) As Field '*** สำหรับสร้างฟิลด์
Dim MyIndex As Index '*** สำหรับสร้างดัชนีค้นหา
Dim MyIndexField As Field
'*************************************************************************************************
'2. ใช้ Create Database เมื่อเสร็จขั้นตอนนี้จะได้ฐานข้อมูลว่างๆ ในตัวอย่างจะสร้าง MyDb.mdb
Set MyWs = DBEngine.Workspaces(0)
Set MyDB = MyWs.CreateDatabase(App.Path & "\MyDb.mdb", dbLangGeneral, dbVersion25)
'*************************************************************************************************
'3. Create TableDef เพื่อสร้างTable ชื่อ Customers
Set MyTable = MyDB.CreateTableDef("Customers")
'*************************************************************************************************
'4. CreateFiled ในที่นี้สร้าง 5ฟิลด์ จึงกำหนดเป็น Array สำหรับProperties ดู Help ส่วน Field Collection
'*** Filed1
Set MyField(0) = MyTable.CreateField("CUSTID", dbLong)
MyField(0).Attributes = dbAutoIncrField
'*** Filed2
Set MyField(1) = MyTable.CreateField("Name", dbText)
MyField(1).Size = 50
'MyField(1).DefaultValue = ""
MyField(1).AllowZeroLength = True
'*** Field3
Set MyField(2) = MyTable.CreateField("Address", dbText)
MyField(2).Size = 50
'MyField(2).DefaultValue = ""
MyField(2).AllowZeroLength = True
'*** Field4
Set MyField(3) = MyTable.CreateField("Credit", dbCurrency)
MyField(3).DefaultValue = 0
Set MyField(4) = MyTable.CreateField("RunningNo", dbLong)
MyField(4).DefaultValue = 0
'*************************************************************************************************
'5. Append To Table and Append To Database
MyTable.Fields.Append MyField(0) '*** Append ฟิลด์ที่1
MyTable.Fields.Append MyField(1) '*** Append ฟิลด์ที่2
MyTable.Fields.Append MyField(2)
MyTable.Fields.Append MyField(3)
MyTable.Fields.Append MyField(4)
MyDB.TableDefs.Append MyTable '*** Append Table เข้าฐานข้อมูลจบข้อนี้จะได้ Table แล้ว
'*************************************************************************************************
'**** Create Index ขั้นต่อไปสร้างดัชนีค้นหาชื่อ CUSTID
Set MyIndex = MyTable.CreateIndex("CUSTID")
MyIndex.Primary = True
MyIndex.Unique = True
Set MyIndexField = MyIndex.CreateField("CUSTID") '** ใช้ฟิลด์ CUSTID
MyIndex.Fields.Append MyIndexField
MyTable.Indexes.Append MyIndex
MyDB.Close
1.1ลากเรื่องมือ Data Control ไปวางไว้บน ฟอร์ม แล้ว Properties ของData Control ดังนี้
Connect เช่นเลือก Acess
DatabaseName เลือก C:\VB\Biblio.MDBชื่อฐานข้อมูล
RecordType เลือก 1-Dynaset
RecordSource เลือก Titles เป็นตารางฐานข้อมูล
1.2ลาก TextBox วางบนฟอร์ม แล้วกำหนด Properties ของ TextBox ดังนี้
DataSource เช่นเลือก Data1
DataField เช่นเลือก Title
ทำตามข้อ 2 จนกว่าจะครบตาม Field ที่ต้องการแค่นี้คุณก็อ่านข้อมูลมาแสดงได้แล้ว
หรือจะลองใช้ Data Form Designer ตรง Add-Ins เข้ามาช่วยสร้างก็ได้
ถ้าหากต้องการนำ Data Control ไปใช้กับ DBGrid ให้ทำดังนี้
2.1 กำหนด Data Control ตามแบบ 1.1
2.2 ลาก DbGrid วางบนฟอร์ม แล้วกำหนด DataSource Data1
2.3 กดเมาส์ปุ่มขวาที่ DBGrid เลือก Retrive Fields แค่นี้ก็ใช้งานได้แล้ว
2.4 กดเมาส์ปุ่มขวาที่ DBGrid เลือก Edit เพื่อเพิ่มหรือลดขนาดช่อง เพื่อตกแต่งได้
2.5 กดเมาส์ปุ่มขวาที่ DBGrid เลือก Properties เพื่อกำหนดให้ Addnew, Delete ได้ หรือ อื่นๆการเปิดใช้งาน Data Access Object (DAO)
1. กำหนดตัวแปรดังนี้
Dim MyWs As Workspace
Dim MyDB As Database
Dim MyRs As Recordset
2.เปิดใช้งานฐานข้อมูล
Set MyWs = DBEngine.Workspaces(0)
Set MyDb = MyWs.OpenDatabase("BIBLIO.MDB")
Set MyRs = MyDb.OpenRecordset("Select * From Titles ", dbOpenSnapshot)
'***เราเลือกเปิดได้แบบ dbOpenTable,dbOpenDynaset หรือ dbOpenSnapshot (ใช้อ่านอย่างเดียว)
'***กรณีเปิดแบบตารางใช้ชื่อตารางเลยไม่ต้องมี Select
อนึ่งมีหลายท่านอาจไม่กำหนด Workspace ก็ได้ ดังนี้
Dim MyDB As Database
Dim MyRs As Recordset
Set MyDb = Workspaces(0).OpenDatabase("BIBLIO.MDB")
Set MyRs = MyDb.OpenRecordset("Select * From Titles ", dbOpenSnapshot)
1. MyRs!LastName แบบนี้ผมชอบใช้
2. MyRs![Last Name] เหมาะกับคนที่ชอบตั้งชื่อมีช่องว่าง
3. MyRs.Fields("LastName") หรือ MyRs("LastName") เหมาะกับชื่อที่ต้องใช้วนลูปตัวแปร เช่น M01 ถึง M12
4. MyRs.Fields(n) n= 0 ถึง FieldCount - 1
กรณีใช้ Data Control เปลี่ยนชื่อจาก MyRs เป็น Data1.Recordset
1. Data1.Recordset!LastName
2. Data1.Recordset![Last Name]
3. Data1.Recordset.Fields("LastName") หรือ MyRs("LastName")
4. Data1.Recordset.Fields(n) n= 0 ถึง FieldCount - 1การเลื่อนตำแหน่งเรคคอร์ดภายใต้ Recordset
การเลื่อนตำแหน่งเรคคอร์ดเราใช้ Method ดังนี้
1. MoveFirst
2. MoveNext
3. MovePrevious
4. MoveLast
และอย่าลืมใช้ Method EOF (End of File) และ BOF (Begin of File) เพื่อตรวจสอบว่าถึงท้ายแฟ้ม หรือต้นแฟ้มหรือยัง
ดังตัวอย่างDim MyDB As Database
Dim MyRs As Recordset
Set MyDb = Workspaces(0).OpenDatabase("BIBLIO.MDB")
Set MyRs = MyDb.OpenRecordset("Select * From Titles ", dbOpenSnapshot)
Do While Not MyRs.EOF
Print MyRs!Title
MyRs.MoveNext
Loop
การค้นหาข้อมูลที่เปิดแบบ Table จะต้องใช้ Seek หาตามดัชนีค้นหา (Index) มีรูปแบบ
table.Seek comparison, key1, key2,...
comparison มี "=", ">", ">=", "<" หรือ "<="
การใช้ key ค้นหาต้องระวังเรื่องตัวแปรด้วย จะต้องตรงกับ ฟิลด์ในฐานข้อมูลด้วย เช่น
ฟิลด์ในฐานข้อมูลเป็นตัวอักษร แต่ Key เป็นตัวเลข ต้องแปลงkeyเป็นตัวอักษรก่อนโดยใช้ Str()
ฟิลด์ในฐานข้อมูลเป็นตัวเลข แต่ Key เป็นตัวอักษร ต้องแปลงkeyเป็นตัวเลขก่อนก่อนโดยใช้ Val()
ก่อนใช้ Seek อย่าลืมกำหนด Index ที่จะค้นหา โดยใช้ table.Index = "ชื่อIndex"
หลังจากใช้ Seek แล้วต้องใช้ Method NoMatch เพื่อตรวจสอบว่าเจอหรือไม่ทุกครั้ง
ตัวอย่าง
Dim MyDB As Database
Dim MyRs As Recordset
Set MyDb = Workspaces(0).OpenDatabase("BIBLIO.MDB")
Set MyRs = MyDb.OpenRecordset("Authors", dbOpenTable)
MyRs.Index = "PrimaryKey" '*** กำหนดชื่อดัชนีที่จะค้นหา
MyRs.Seek "=",Val(txtAu_ID)
If MyRs.Nomatch Then
MsgBox "Not Found"
Else
MsgBox "Found = " & MyRs!Au_ID & " Name: " & MyRs!Author
Endif
สังเกตุการใช้ Val เพราะField ในฐานข้อมูลเป็นตัวเลข แต่ค่าจาก TextBox เป็นตัวอักษร
การค้นหาข้อมูลที่เปิดแบบ Dynaset หรือ Snapshot
จะต้องใช้ FindFirst, FindNext , FindPrevious หรือ FindLast
ตัวอย่าง
Dim MyDB As Database
Dim MyRs As Recordset
Set MyDb = Workspaces(0).OpenDatabase("BIBLIO.MDB")
Set MyRs = MyDb.OpenRecordset("Authors", dbOpenSnapshot)
MyRs.FindFirst " Au_ID = " & txtAu_ID
If MyRs.Nomatch Then
MsgBox "Not Found"
Else
MsgBox "Found = " & MyRs!Au_ID & " Name: " & MyRs!Author
Endif
ข้อระวังในการใช้ FindFirst เกี่ยวกับตัวเลขและตัวอักษร คือ ตัวอักษรต้องมี ' (แป้น ง) ปิดหัวท้าย เช่น
MyRs.FindFirst " FieldChar = '" & txtChar & "' "
การใช้งาน Data Control ร่วมกับ DAO
เราสามารถกำหนดให้ DAO ใช้ Recordset ของ Data Control ได้ดัง ตัวอย่างดังนี้
Dim MyDB As Database
Dim MyRs As Recordset
Set MyDB = Data1.Database '<--- ตรงนี้
Set MyRs = Data1.Recordset '<--- ตรงนี้
ในขณะเดียวกันเราสามารถกำหนดให้ Data Control ใช้ Recordset ของ DAO ได้ดังตัวอย่างดังนี้
Dim MyDB As Database
Dim MyRs As Recordset
Set MyDb = Workspaces(0).OpenDatabase("BIBLIO.MDB")
Set MyRs = MyDb.OpenRecordset("Authors", dbOpenSnapshot)
Set Data1.Recordset = MyRs '<--- ตรงนี้
เพิ่มข้อมูลใช้ Method Addnew และเมื่อจบการเพิ่มจะต้องปิดด้วย Method Update
การแก้ไขข้อมูล ใช้ Method Edit และเมื่อจบการแก้ไขจะต้องปิดด้วย Method Update
การลบข้อมูล ใช้ Method Delete
ตัวอย่างDim MyDB As Database
Dim MyRs As Recordset
Set MyDb = Workspaces(0).OpenDatabase("BIBLIO.MDB")
Set MyRs = MyDb.OpenRecordset("Authors", dbOpenTable)
MyRs.Index = "PrimaryKey" '*** กำหนดชื่อดัชนีที่จะค้นหา
MyRs.Seek "=",Val(txtAu_ID)
If MyRs.Nomatch Then
MyRs.AddNew '** <-- เพิ่ม
Else
MyRs.Edit '** <-- แก้ไข
Endif
MyRs!Au_ID = Val(txtAu_ID)
MyRs!Title = txtAuthor
MyRs.Update '** <-- อย่าลืมปิดด้วย Updateการใช้ Execute Method เพื่อเพิ่ม ปรับปรุง หรือ ลบข้อมูลจำนวนมาก
ในการเพิ่ม ปรับปรุง หรือ ลบข้อมูล ควรใช้ Execute Method เพื่อเรียกใช้คำสั่ง SQL สำหรับคำสั่งของ SQL ที่ใช้ได้คือ Insert, Update, Delete ดังตัวอย่างดังนี้
Dim MyDB As Database
Dim SQLText As String
Set MyDb = Workspaces(0).OpenDatabase("BIBLIO.MDB")
SQLText = " DELETE * FROM Ahthors WHERE Au_ID > 900 "
MyDb.Exceute SQLText '<-- ตรงนี้
่นี้คือการเปิดใช้ Security Database เฉพาะ 32Bit คือ Access 95 หรือ Access97 เท่านั้น เป็นPassword ที่ใช้เข้า Database ในตอนแรก ซึ่งจะมีแต่รหัสผ่านเท่านั้น ไม่มี UserID ดังนั้นไม่ต้องใช้แฟ้ม System.Mdw แต่ถ้ากำหนดรหัสที่มี UserID และ Password จะต้องใช้แฟ้ม System.Mdw ด้วย แต่อย่างไรก็ตาม ถ้าเราจะไปแก้รหัสผ่าน ใน Access จำเป็นที่จะต้องใช้แฟ้ม System.Mdw ด้วย ไม่ว่าจะกำหนดแบบมี UserID หรือไม่มีUserID ก็ตาม
Dim MyWs As Workspace
Dim MyDb As Database
Dim MyRs As Recordset
Set MyWs = MyDbEngine.Workspaces(0)
Set MyDb = MyWs.OpenDatabase(App.Path & "\Db1.mdb", False, False, ";PWD=12345") '*** มีรหัส 12345
Set MyRs = MyDb.OpenRecordset("Department", dbOpenTable)
สำหรับการกำหนดรหัสผ่านแบบที่มี UserID จะต้องใช้ CreateWorkSpace หาอ่านจาก Help เองละกัน
การใช้ ReccordCount เพื่อนับจำนวน Record นั้น มีบางครั้งเปิดใช้ฐานข้อมูล แล้วจะนับได้ 1 ตลอด ผมไม่ทราบว่าเป็น Bug หรือปล่าว ผมหาวิธีแก้ไขอยู่ตั้งนาน จึงนำมาบอกกันให้ทราบไว้
คือ ก่อนใช้ RecordCount ต้องใช้ MoveLast ก่อนใช้ RecordCount รับรองว่าคราวนี้จะนับได้ถูกต้องDim MyDB As Database
Dim MyRs As Recordset
Set MyDb = Workspaces(0).OpenDatabase("BIBLIO.MDB")
Set MyRs = MyDb.OpenRecordset("Authors", dbOpenSnapshot)
If Not MyRs.Eof Then MyRs.MoveLast '*** MoveLast ก่อน
MsgBox Str(MyRs.RecordCount)ปัญหาเกี่ยวกับค่า Null เป็นปัญหาเยอะทีเดียวสำหรับ ผู้ที่ใช้ VB ใหม่ๆ เพราะว่า TextBox ไม่สามารถรับค่า Null ได้
เหล่านี้คือตัวอย่างการแก้ปัญหา Null
ใช้ "" & Data1.Recordset!FieldName จะแก้ปัญาเรื่อง Null ได้แต่สำหรับผมส่วนใหญ่จะใช้ดังนี้
txtNumber = Format$(Val("" & Data1.Recordset!FieldNumber),"#,##0.00") '*** กรณีตัวเลขใช้ Val ช่วย
txtText = "" & Data1.Recordset!FieldText '*** กรณีตัวอักษร
txtDate= "" & Format$(Data1.Recordset!FieldDate,"dd/mm/yyyy") '*** กรณีวันที่
สำหรับวันที่ถ้าคุณให้ป้อนวันที่แบบภาษาไทยต้องแปลงปีก่อน อาจต้องใช้ Isnull ช่วย
If Isnull(Data1.Recordset!FieldDate) Then
txtDate = " / / "
Else
txtDate = Format$(Data1.Recordset!FieldDate,"dd/mm/") & Format$(Year(Data1.Recordset!FieldDate) + 543 ,"0000")
End Ifตัวอย่างโปรแกรมเก็บรูปไว้ใน Access
การเก็บรูปไว้ใน Access นั้นถ้าเราใช้แบบ Data Control จะง่ายมากเลย เราสามารถใช้ PictureControl หรือใช้ OLE ก็ได้ แต่มีข้อแม้ว่าถ้าเก็บแบบ OLE จะมาแสดงรูปโดยใช้ PictureControl ไม่ได้ ในกรณีที่ผู้ใช้ใส่รูป ในโปรแกรม Access เองนั้นรูปจะเก็บแบบ OLE ดังนั้นต้องใช้ OLE แต่ถ้าเราใช้แบบ Picture Control ใน VB4 จะใช้ Bmp เท่านั้น ลอง Download ตัวอย่างไปศึกษาละกัน
การเปิดใช้แฟ้ม Text Delimited โดยตรง
การเปิดใช้แฟ้ม Text Delimited มีประโยช์นมากในการโอนย้ายข้อมูล จากที่อื่นๆมาเข้าแฟ้ม Database ของเรา ปกติแล้วแฟ้ม Text มักขั้น ด้วย Comma หรือ Tab หรืออาจจะเป็นตัวอืนก็ได้เช่น | เป็นต้น
ในการเปิดใช้นั้นคุณจะต้องสร้าง SCHEMA.INI ก่อน แล้วเก็บไว้ที่เดียวกันกับแฟ้มที่จะเปิด เช่น จะเปิดใช้แฟ้ม tab.txt ใน C:\TEMP เราต้องเก็บ SCHEMA.INI ไว้ที่ C:\TEMP ด้วยตัวอย่าง
การเปิดใช้ แฟ้มที่ขั้นด้วย Tab ชื่อแฟ้ม tab.txt อยู่ที่ C:\TEMP โดยมีข้อมูลดังนี้
111 This is Rec 1 12345.00
222 This is Rec 2 222.00
333 This is Rec 3 333.00
444 This is Rec 4 444.00
555 This is Rec 5 555.00
สร้าง Schema.ini ดังนี้
[tab.txt] '<== ชื่อแฟ้ม tab.txt
ColNameHeader=False
Format=TabDelimited '<== ขั้นด้วย Tab ถ้า CSVDelimited ขั้นด้วย Comma
MaxScanRows=0
CharacterSet=OEM
Col1=F1 Integer '<== Col1 ใช้ชื่อฟิลด์เป็น F1 เป็น Integer
Col2=F2 Char Width 255 '<== Col2 ใช้ชื่อฟิลด์ F2 เป็นอักษร กว้าง 255
Col3=F3 Float
การเขียนโปรแกรมเพื่ออ่านข้อมูล โดยใช้ DAO
Dim mDb As Database
Dim mRs As Recordset
Set mDb = OpenDatabase("C:\TEMP", False, False, "TEXT;")
Set mRs = mDb.OpenRecordset("Tab")
Do While Not mRs.EOF
Print mRs!F1; mRs!F2; mrsF3
mRs.MoveNext
Loop
mRs.Close
mDb.Close
เมื่ออ่านมาถึงตรงนี้ท่านผู้อ่านคงหนักใจมากใช่ไหม ถ้าหากท่านจะต้องเขียน Schema.ini เอง ให้ผมเขียนเองนะผมเขียนไม่เป็นหรอก ท่านคงสงสัยว่าแล้วผมทำมาได้ไง ผมยังไม่บอกหรอกว่าทำอย่างไร ให้คิดดูก่อน
ลอง Download ตัวอย่างที่เขียนไปศึกษา
หน้าแรก อุปกรณ์ที่ประกอบเป็นเครื่องคอมพิวเตอร์ เกาเหลาเทคนิคการใช้ HTML วิธีทำสร้าง Shortcut บน Desktop ปัญหาใหญ่ของ Data transfer