1
ห้อง MS Access / : ต้องการให้ user สามารถกำหนด path ของ table เองได้ (link table)
« เมื่อ: 11 พ.ค. 67 , 19:36:07 »
จะพยามอธิบายให้เข้าใจนะครับ เผื่อเป็นประโยชน์กับท่านอื่นๆด้วย
- ฟังก์ชั่นนี้เป็นการเปลี่ยนพาธของ Linked Table ที่มีอยู่แล้วในไฟล์เดิม ดังนั้นจะใช้ได้ต่อเมื่อมีการทำ Linked Table ในไฟล์ MS Access อยู่ก่อนแล้ว
- โดยฟังก์ชั่นนี้จะยึดชื่อตารางที่มีอยู่เดิมในการเปลี่ยนพาธตามที่กำหนดเท่านั้น ไม่ใช่เป็นการลิ้งค์พาธชื่อตารางใหม่
- สร้างฟังก์ชั่นขึ้นใหม่ดังนี้:
* ส่วนเสริมฟังก์ชั่นสำหรับการอ่านค่าลิ้งค์ของตารางก่อน หากไม่ตรงกับที่อยู่ปัจจุบันค่อยใช้ฟังก์ชั่นเปลี่ยน โปรแกรมจะได้ไม่ต้องเปลี่ยนลิ้งค์ทุกครั้งที่เปิดไฟล์
- การใช้งานฟังก์ชั่นร่วมกัน
<การใช้งาน>
- เนื่องจากการเปลี่ยนพาธลิ้งค์เทเบิ้ล ต้องทำก่อนการเรียก ตาราง คิวรี่ ฟอร์ม หรือ รายงาน ดังนั้นจึงต้องเรียกตั้งแต่ตอนเปิดไฟล์ MS Access
1. เลือกเมนูหัวข้อ Create > Macro
2. เลือกหัวข้อคำสั่ง RunCode
3. ใส่คำสั่ง iStartup() ลงในช่องว่าง
4. เซฟ Macro เป็นชื่อ Autoexec เท่านั้น (หากมีชื่อนี้อยู่แล้ว ให้ไปเพิ่มคำสั่งใหม่ที่ Macro Autoexec แทน)
<อธิบาย>
- For each TD .... ก็เป็นการวนลูป โดยกำหนด object variable TD ให้เป็นทีละเทเบิลในฐานข้อมูล
- TD.Attributes จะให้ค่าเท่ากับ dbAttachedTable เมื่อเทเบิลนั้นเป็น Linked Table ที่ลิงค์มาจากฐานข้อมูลประเภท Access ด้วยกันเอง (พวก .accdb, .mdb, .mda) แต่ถ้าลิ้งค์มาจาก ODBC จะให้เป็นค่า dbAttachedODBC โดยปกติคิดว่า 99.99% เราสามารถทดสอบด้วยคำสั่ง If TD.Attributes = dbAttachedTable then ได้โดยตรง แต่เนื่องจาก .Attributes อาจมีค่าเกิดจากการรวมหลายๆ option เข้าด้วยกัน ด้วย logical OR (แต่ก็ไม่ทราบเหมือนกันว่ามันจะรวมกับ option อื่นอย่างไรได้บ้าง) ดังนั้นเพื่อให้แน่ใจเต็ม 100% เวลาจะทดสอบกรองเอาเพื่อดูว่ามีค่าของ dbAttachedTable อยู่ในส่วนผสมนั้นหรือไม่ ก็ต้องทดสอบด้วย logical AND (ตรงนี้คิดว่าหลายๆท่านก็คงจะทราบดีอยู่แล้ว) คำสั่ง If ที่เขียนให้ดูเลยออกมาเป็นอย่างนั้น
- TD.Connect ก็เป็นการกำหนดชื่อพาธและไฟล์ที่จะลิ้งค์เข้ามา เนื่องจากเราลิงค์มาจากเทเบิลต้นทางที่ชื่อเดิมเสมอ (ชื่อเดียวกันกับที่เราลิงค์มาครั้งแรก) ดังนั้นจึงไม่ต้องบอกมันอีกว่ามาจากเทเบิลชื่ออะไร
- TD.RefreshLink เป็นการสั่งให้ทำการอ่านค่าใหม่ทั้งหมด
- DB.Close: Set DB = Nothing สั่งให้ปิด Database และยกเลิกการเซ็ท DB
<หมายเหตุ>
* การใช้ฟังก์ชั่นนี้ ต้องมีการสร้าง Link Table ของเดิมอยู่ก่อนแล้ว ลักษณะของฟังก์ชั่นจะเป็นการแก้ไขพาธของ Link Table ใหม่ให้เท่านั้น ไม่ใช่การสร้าง Link Table ขึ้นมาใหม่ แต่หากต้องการทำลิ้งค์ตารางขึ้นมาใหม่จากไฟล์ MS Access ภายนอกให
* หากไฟล์ข้อมูลที่ทำการลิ้งค์มีการตั้งรหัสผ่านไว้ จะทำให้การเปลี่ยนลิ้งค์ช้ากว่าปกติ
ลองทำความเข้าใจและปรับใช้ดูนะครับ
- ฟังก์ชั่นนี้เป็นการเปลี่ยนพาธของ Linked Table ที่มีอยู่แล้วในไฟล์เดิม ดังนั้นจะใช้ได้ต่อเมื่อมีการทำ Linked Table ในไฟล์ MS Access อยู่ก่อนแล้ว
- โดยฟังก์ชั่นนี้จะยึดชื่อตารางที่มีอยู่เดิมในการเปลี่ยนพาธตามที่กำหนดเท่านั้น ไม่ใช่เป็นการลิ้งค์พาธชื่อตารางใหม่
- สร้างฟังก์ชั่นขึ้นใหม่ดังนี้:
โค๊ด: [Select]
Public Function ChangeLinkedMDB()
Dim DB As DAO.Database
Dim TD As DAO.TableDef
On Error GoTo Err_Handler
Set DB = CurrentDb
'---หากไม่ต้องการลูป ต้องการแค่ชื่อตารางเป้าหมายเพียงชื่อเดียว-----------------------------------------
'Set TD = DB.TableDefs("ชื่อตารางเป้าหมาย")
'If (TD.Attributes And dbAttachedTable) = dbAttachedTable Then
'TD.Connect = ";DATABASE=" & CurrentProject.Path & "\1.accdb"
'TD.Connect = ";DATABASE=" & CurrentProject.Path & "\1.accdb" & ";pwd=1234"
'หากไฟล์มี password
'TD.RefreshLink
'End If
'--------------------------------------------------------------------------------------
For Each TD In DB.TableDefs
If (TD.Attributes And dbAttachedTable) = dbAttachedTable Then
TD.Connect = ";DATABASE=" & CurrentProject.Path & "\1.accdb" '1.accbd ชื่อไฟล์ Back End เป้าหมาย
'TD.Connect = ";DATABASE=" & CurrentProject.Path & "\1.accdb" & ";pwd=1234"
'หากไฟล์มี password
TD.RefreshLink
End If
Next TD
Exit_Handler:
DB.Close: Set DB = Nothing
Exit Function
Err_Handler:
Select Case Err.Number
Case 3024&, 3044&
MsgBox "ไม่พบไฟล์ในพาธที่กำหนด", , "พาธไฟล์ผิดพลาด"
Case 3011&
MsgBox "ไม่พบชื่อตารางเป้าหมายในไฟล์ที่กำหนด", , "ชื่อตารางผิดพลาด"
End Select
End Function
* ส่วนเสริมฟังก์ชั่นสำหรับการอ่านค่าลิ้งค์ของตารางก่อน หากไม่ตรงกับที่อยู่ปัจจุบันค่อยใช้ฟังก์ชั่นเปลี่ยน โปรแกรมจะได้ไม่ต้องเปลี่ยนลิ้งค์ทุกครั้งที่เปิดไฟล์
โค๊ด: [Select]
Private Function GetLinkedDBName(TableName As String) As String
Dim db As DAO.Database
Dim Ret As String
On Error GoTo DBNameErr
Set db = CurrentDb() 'Set db = DAO.OpenDatabase("PathFileName", False, False, ";pwd=Password")
Ret = db.TableDefs(TableName).Connect
GetLinkedDBName = Right(Ret, Len(Ret) - (InStr(1, Ret, "DATABASE=") + 8))
db.Close: Set db = Nothing
Exit Function
DBNameErr:
GetLinkedDBName = 0
db.Close: Set db = Nothing
End Function
- การใช้งานฟังก์ชั่นร่วมกัน
โค๊ด: [Select]
Public Function iStartup()
If GetLinkedDBName("Table1") <> CurrentProject.Path & "\1.accdb" Then
ChangeLinkedMDB
End If
'DoCmd.OpenForm "ชื่อฟอร์ม" 'หากต้องการเปิดฟอร์มเป้าหมายอัตโนมัติ
End Function
<การใช้งาน>
- เนื่องจากการเปลี่ยนพาธลิ้งค์เทเบิ้ล ต้องทำก่อนการเรียก ตาราง คิวรี่ ฟอร์ม หรือ รายงาน ดังนั้นจึงต้องเรียกตั้งแต่ตอนเปิดไฟล์ MS Access
1. เลือกเมนูหัวข้อ Create > Macro
2. เลือกหัวข้อคำสั่ง RunCode
3. ใส่คำสั่ง iStartup() ลงในช่องว่าง
4. เซฟ Macro เป็นชื่อ Autoexec เท่านั้น (หากมีชื่อนี้อยู่แล้ว ให้ไปเพิ่มคำสั่งใหม่ที่ Macro Autoexec แทน)
<อธิบาย>
- For each TD .... ก็เป็นการวนลูป โดยกำหนด object variable TD ให้เป็นทีละเทเบิลในฐานข้อมูล
- TD.Attributes จะให้ค่าเท่ากับ dbAttachedTable เมื่อเทเบิลนั้นเป็น Linked Table ที่ลิงค์มาจากฐานข้อมูลประเภท Access ด้วยกันเอง (พวก .accdb, .mdb, .mda) แต่ถ้าลิ้งค์มาจาก ODBC จะให้เป็นค่า dbAttachedODBC โดยปกติคิดว่า 99.99% เราสามารถทดสอบด้วยคำสั่ง If TD.Attributes = dbAttachedTable then ได้โดยตรง แต่เนื่องจาก .Attributes อาจมีค่าเกิดจากการรวมหลายๆ option เข้าด้วยกัน ด้วย logical OR (แต่ก็ไม่ทราบเหมือนกันว่ามันจะรวมกับ option อื่นอย่างไรได้บ้าง) ดังนั้นเพื่อให้แน่ใจเต็ม 100% เวลาจะทดสอบกรองเอาเพื่อดูว่ามีค่าของ dbAttachedTable อยู่ในส่วนผสมนั้นหรือไม่ ก็ต้องทดสอบด้วย logical AND (ตรงนี้คิดว่าหลายๆท่านก็คงจะทราบดีอยู่แล้ว) คำสั่ง If ที่เขียนให้ดูเลยออกมาเป็นอย่างนั้น
- TD.Connect ก็เป็นการกำหนดชื่อพาธและไฟล์ที่จะลิ้งค์เข้ามา เนื่องจากเราลิงค์มาจากเทเบิลต้นทางที่ชื่อเดิมเสมอ (ชื่อเดียวกันกับที่เราลิงค์มาครั้งแรก) ดังนั้นจึงไม่ต้องบอกมันอีกว่ามาจากเทเบิลชื่ออะไร
- TD.RefreshLink เป็นการสั่งให้ทำการอ่านค่าใหม่ทั้งหมด
- DB.Close: Set DB = Nothing สั่งให้ปิด Database และยกเลิกการเซ็ท DB
<หมายเหตุ>
* การใช้ฟังก์ชั่นนี้ ต้องมีการสร้าง Link Table ของเดิมอยู่ก่อนแล้ว ลักษณะของฟังก์ชั่นจะเป็นการแก้ไขพาธของ Link Table ใหม่ให้เท่านั้น ไม่ใช่การสร้าง Link Table ขึ้นมาใหม่ แต่หากต้องการทำลิ้งค์ตารางขึ้นมาใหม่จากไฟล์ MS Access ภายนอกให
* หากไฟล์ข้อมูลที่ทำการลิ้งค์มีการตั้งรหัสผ่านไว้ จะทำให้การเปลี่ยนลิ้งค์ช้ากว่าปกติ
ลองทำความเข้าใจและปรับใช้ดูนะครับ