www.oocities.org/pontipa001

หน้าแรก อุปกรณ์ที่ประกอบเป็นเครื่องคอมพิวเตอร์ เกาเหลาเทคนิคการใช้ HTML วิธีทำสร้าง Shortcut บน Desktop ปัญหาใหญ่ของ Data transfer

DAO และ Data Control

หัวข้อนี้จะแนวนำการใช้ VB กับฐานข้อมูล Access เริ่มตั้งแต่การสร้างฐานข้อมูล การเปิดใช้งาน การค้นหา การเพิ่ม แก้ไขและลบ เรคคอร์ด   หวังว่าจะมีประโยช์นสำหรับผู้ที่เริ่มศึกษา  

  การสร้างฐานข้อมูล Access จาก VB
  การการเปิดใช้งาน Data Control
  การเปิดใช้งาน Data Access Object (DAO)
  การอ้างชื่อฟิลด์
  การเลื่อนตำแหน่งเรคคอร์ดภายใต้ Recordset
  การค้นหาข้อมูล
  การใช้ Data Control ร่วมกับ DAO
  การเพิ่ม แก้ไข และ ลบข้อมูล
  การใช้ Execute Method เพื่อเพิ่ม ปรับปรุง หรือ ลบข้อมูลจำนวนมาก
  การเปิดใช้ Security Database
  ปัญหาการใช้ RecordCount
  ปัญหาเกี่ยวกับค่า Null
  ตัวอย่างโปรแกรมเก็บรูปใน Access
  การเปิดใช้แฟ้ม Text Delimited โดยตรง

การสร้างฐานข้อมูล 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

การใช้งาน Data Control

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

่นี้คือการเปิดใช้ 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 เองละกัน

 

ปัญหาการใช้ RecordCount

การใช้ 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

ปัญหาเกี่ยวกับค่า 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