กระทู้เก่าบอร์ด อ.Yeadram
3,163 8
URL.หัวข้อ /
URL
Run Form อัตโนมัติ
1.Form ชื่อ All Customer จะมีข้อมูลลูกค้าทั้งหมด และมี Field ชื่อวันนัด Call รูปแบบ 00/00/00\ 00:00;00;_
2.สมมุติ User ได้ลงวันนัด call กับลุกค้าชื่อนาย ก ไว้เช่น 06/11/12 13:03:10 และเมื่อถึงเวลานัดให้เปิืดฟอร์มของลูกค้านาย ก ขึ้นมาอะครับ
ไม่ทราบต้องทำอย่างไรบ้างหรอครับ
2.สมมุติ User ได้ลงวันนัด call กับลุกค้าชื่อนาย ก ไว้เช่น 06/11/12 13:03:10 และเมื่อถึงเวลานัดให้เปิืดฟอร์มของลูกค้านาย ก ขึ้นมาอะครับ
ไม่ทราบต้องทำอย่างไรบ้างหรอครับ
8 Reply in this Topic. Dispaly 1 pages and you are on page number 1
2 @R14404
http://www.thai-access.com/yeadram_view.php?topic_id=1128
แต่อย่างคุณ Un บอกนะครับ ว่าฟอร์มที่ใช้เป็นตัวจับเวลาต้องทำงานอยู่ตลอดเวลา หากปิดไป ก็จะไม่มีการทำงานของนาฬิกาเกิดขึ้น วิธีนี้แม้จะง่ายตรงไปตรงมา แต่เป็นวิธีที่ไม่มีประสิทธิภาพสักเท่าไหร่ ตัว Access เองก็ไม่มีอะไรสนับสนุนงานด้านนี้โดยตรงเสียด้วย
ถ้าวิธีที่มีประสิทธิภาพ ควรต้องใช้ VBA เรียกใช้ตัว Windows Scheduler ผ่าน Schedule object เพื่อสร้าง task ตามเวลาที่กำหนดเข้าไปในระบบ schedule ของวินโดว์เอง http://msdn.microsoft.com/en-us/library/aa383665%28v=VS.85%29.aspx `แล้วงานที่ task นั้นทำก็คือเรียก Access โดยส่งพารามิเตอร์ที่ระบุลูกค้าที่ต้องการ วิธีนี้ตัว Access ไม่ต้องเปิดอยู่ตลอดเวลา แต่ค่อนข้างจะหลายขั้นตอนและยุ่งยากทีเดียว
แต่อย่างคุณ Un บอกนะครับ ว่าฟอร์มที่ใช้เป็นตัวจับเวลาต้องทำงานอยู่ตลอดเวลา หากปิดไป ก็จะไม่มีการทำงานของนาฬิกาเกิดขึ้น วิธีนี้แม้จะง่ายตรงไปตรงมา แต่เป็นวิธีที่ไม่มีประสิทธิภาพสักเท่าไหร่ ตัว Access เองก็ไม่มีอะไรสนับสนุนงานด้านนี้โดยตรงเสียด้วย
ถ้าวิธีที่มีประสิทธิภาพ ควรต้องใช้ VBA เรียกใช้ตัว Windows Scheduler ผ่าน Schedule object เพื่อสร้าง task ตามเวลาที่กำหนดเข้าไปในระบบ schedule ของวินโดว์เอง http://msdn.microsoft.com/en-us/library/aa383665%28v=VS.85%29.aspx `แล้วงานที่ task นั้นทำก็คือเรียก Access โดยส่งพารามิเตอร์ที่ระบุลูกค้าที่ต้องการ วิธีนี้ตัว Access ไม่ต้องเปิดอยู่ตลอดเวลา แต่ค่อนข้างจะหลายขั้นตอนและยุ่งยากทีเดียว
3 @R14412
คือจริงๆ มีแนวคิดอย่างนึง ผมขออธิบายไอเดียให้อ่านดูแล้วกันนะครับ
ผมคิดว่าเราน่าจะใช้การเซ็ท TimerInterval ให้มีค่าแปรผันตาม ค่าเวลา 2 ค่า แทนการใช้ On Time คอยตรวจสอบ จะทำให้ไม่กินแรงเครื่อง ยกตัวอย่าง เช่น ผมมีตาราง Table1 ดังนี้:
ID aName Date/Time
1 MR.A 1/1/2012 00:00:00
2 MR.B 1/1/2012 01:00:00
3 MR.C 1/1/2012 01:30:00
1. ผมจะกรองข้อมูล โดยจะใช้คิวรี่ หรือ ฟังก์ชั่นอะไรก็ได้ เพื่อเอาเฉพาะข้อมูลตรงกับวันปัจจุบันมาก่อน
2. ฟอร์ม ที่ Declarations ผมสร้างตัวแปรมา 1 ตัว ชื่อ TT2 as Integer
3. ฟอร์ม Event > On Open
Private Sub Form_Open(Cancel As Integer)
TT2 = 0
Me.TimerInterval = DateDiff("s", TimeValue(DLookup("Meet", "Table1", "id = " & TT2 & "+ 1")), TimeValue(DLookup("Meet", "Table1", "id = " & TT2 & "+2"))) * 1000
End Sub
4. ฟอร์ม Event > On Timer
Private Sub Form_Timer()
MsgBox DLookup("aName", "Table1", "id = " & TT2 & "+ 2")
Me.TimerInterval = DateDiff("s", TimeValue(DLookup("Meet", "Table1", "id = " & TT2 & "+ 1")), TimeValue(DLookup("Meet", "Table1", "id = " & TT2 & "+2"))) * 1000
TT2 = TT2 + 1
End Sub
- เท่านี้ ผมจะได้ Msgbox แสดงชื่อคนที่ผมนัดขึ้นมา ณ เวลาตามตาราง และจะได้ค่า TimerInterval เวลาต่อไป เซ็ทไปเรื่อยๆ โดยที่เราไม่ต้องกำหนด TimerInterval ค่าน้อยๆ แล้วใช้ On Timer คอยตรวจสอบตลอด
- TimerInterval รับค่าได้ 0 and 2,147,483,647 ซึ่ง 1 วันมีค่า 86,399,000
ซึ่งเป็นไอเดียนะครับ ยังต้องต่อเติมเพิ่มปรับอีกพอสมควร ผมลองเขียนเบื้องต้นก็พอใช้ได้อยู่ ลองปรับใช้ดูครับ
ผมคิดว่าเราน่าจะใช้การเซ็ท TimerInterval ให้มีค่าแปรผันตาม ค่าเวลา 2 ค่า แทนการใช้ On Time คอยตรวจสอบ จะทำให้ไม่กินแรงเครื่อง ยกตัวอย่าง เช่น ผมมีตาราง Table1 ดังนี้:
ID aName Date/Time
1 MR.A 1/1/2012 00:00:00
2 MR.B 1/1/2012 01:00:00
3 MR.C 1/1/2012 01:30:00
1. ผมจะกรองข้อมูล โดยจะใช้คิวรี่ หรือ ฟังก์ชั่นอะไรก็ได้ เพื่อเอาเฉพาะข้อมูลตรงกับวันปัจจุบันมาก่อน
2. ฟอร์ม ที่ Declarations ผมสร้างตัวแปรมา 1 ตัว ชื่อ TT2 as Integer
3. ฟอร์ม Event > On Open
Private Sub Form_Open(Cancel As Integer)
TT2 = 0
Me.TimerInterval = DateDiff("s", TimeValue(DLookup("Meet", "Table1", "id = " & TT2 & "+ 1")), TimeValue(DLookup("Meet", "Table1", "id = " & TT2 & "+2"))) * 1000
End Sub
4. ฟอร์ม Event > On Timer
Private Sub Form_Timer()
MsgBox DLookup("aName", "Table1", "id = " & TT2 & "+ 2")
Me.TimerInterval = DateDiff("s", TimeValue(DLookup("Meet", "Table1", "id = " & TT2 & "+ 1")), TimeValue(DLookup("Meet", "Table1", "id = " & TT2 & "+2"))) * 1000
TT2 = TT2 + 1
End Sub
- เท่านี้ ผมจะได้ Msgbox แสดงชื่อคนที่ผมนัดขึ้นมา ณ เวลาตามตาราง และจะได้ค่า TimerInterval เวลาต่อไป เซ็ทไปเรื่อยๆ โดยที่เราไม่ต้องกำหนด TimerInterval ค่าน้อยๆ แล้วใช้ On Timer คอยตรวจสอบตลอด
- TimerInterval รับค่าได้ 0 and 2,147,483,647 ซึ่ง 1 วันมีค่า 86,399,000
ซึ่งเป็นไอเดียนะครับ ยังต้องต่อเติมเพิ่มปรับอีกพอสมควร ผมลองเขียนเบื้องต้นก็พอใช้ได้อยู่ ลองปรับใช้ดูครับ
4 @R14438
2. ฟอร์ม ที่ Declarations ผมสร้างตัวแปรมา 1 ตัว ชื่อ TT2 as Intege
คุณ TTT ครับอันนี้ทำยังไงครับพอดียังไม่เก่งเรื่องนี้ครับ
คุณ TTT ครับอันนี้ทำยังไงครับพอดียังไม่เก่งเรื่องนี้ครับ
5 @R14439
คุณ Cooly ครับ ตัวอย่างคงใช้จริงยังไม่ได้หรอกครับ ที่ผมให้ได้คือแนวคิดครับ
เอางี้ครับ ไว้ช่วงดึกมีเวลาว่างผมจะค่อยๆเขียนยกตัวอย่างทีละขั้นให้ทำความเข้าใจและไปปรับใช้ดูแล้วกันนะครับ
เอางี้ครับ ไว้ช่วงดึกมีเวลาว่างผมจะค่อยๆเขียนยกตัวอย่างทีละขั้นให้ทำความเข้าใจและไปปรับใช้ดูแล้วกันนะครับ
6 @R14442
OK ก่อนอื่นตอบเรื่อง Declarations ก่อน จริงๆคือ Declarations Section ประกาศตัวแปรไว้ใน Class ที่สามารถติดต่อกับ Procedure ต่างๆได้ ช่วงนี้ตามรูปครับ
7 @R14443
อธิบายเรื่องแนวคิดก่อนนะครับ
การใช้เหตุการณ์ Timer Interval หรือ On Timer ใน MS Access หลักๆมีสองแนวคิดครับ คือ 1. การทำแบบเป็น Real Time และ 2. การทำเป็น Schedule (อันนี้แหละครับที่มักจะใช้ Real Time ทำเป็น Schedule ทำให้เครื่องทำงานหนัก)
1. การทำแบบ Real Time จะทำต่อเมื่อเราไม่ทราบว่าอะไรจะเกิดขึ้นข้างหน้า ซึ่งทำให้เราต้องใช้ Timer Interval ค่าน้อย เช่น 1000 (1 Sec) ในการตรวจสอบว่ามีอะไรเกิดขึ้นอย่างไร ตัวอย่างเช่น รายงานผลบอล เป็นต้น ซึ่งเราไม่รู้ว่าจะเกิดการยิงประตูขึ้นนาทีไหน เราจึงต้องใช้แบบ Real Time ค่อยตรวจสอบ ซึ่งก็ต้องแลกมาด้วยการทำงานของเครื่องตลอดเวลา
2. การทำแบบ Schedule จะทำต่อเมื่อเรารู้เหตุการณ์ข้างหน้าอยู่แล้วว่าจะเกิดขึ้นเมื่อไร กรณีคุณเป็นต้น เพราะเรามีตารางนัดหมาย เรารู้ว่านับจากนาทีนี้ ต่อไปอีกกี่นาทีจะได้เวลาไปพบกับใคร เป็นต้น ฉนั้น เราก็หาค่าช่วงนาทีนับจากเวลานี้จนถึงเวลานัด แล้วนำไปกำหนดใน Timer Interval ตามนั้น เมื่อถึงเวลาจึงทำที่ On Timer ซึ่งมันก็เหมือนการตั้งปลุกธรรมดาครับ ไม่กินแรงเครื่องเพราะมันไม่ได้มีเหตุการณ์อะไรให้ต้องคอยตรวจสอบทุกวินาทีเหมือนอย่าง Real Time
แนวคิดเป็นประมาณนี้นะครับ เดี๋ยวผมยกตัวอย่างการทำให้ดูครับ
การใช้เหตุการณ์ Timer Interval หรือ On Timer ใน MS Access หลักๆมีสองแนวคิดครับ คือ 1. การทำแบบเป็น Real Time และ 2. การทำเป็น Schedule (อันนี้แหละครับที่มักจะใช้ Real Time ทำเป็น Schedule ทำให้เครื่องทำงานหนัก)
1. การทำแบบ Real Time จะทำต่อเมื่อเราไม่ทราบว่าอะไรจะเกิดขึ้นข้างหน้า ซึ่งทำให้เราต้องใช้ Timer Interval ค่าน้อย เช่น 1000 (1 Sec) ในการตรวจสอบว่ามีอะไรเกิดขึ้นอย่างไร ตัวอย่างเช่น รายงานผลบอล เป็นต้น ซึ่งเราไม่รู้ว่าจะเกิดการยิงประตูขึ้นนาทีไหน เราจึงต้องใช้แบบ Real Time ค่อยตรวจสอบ ซึ่งก็ต้องแลกมาด้วยการทำงานของเครื่องตลอดเวลา
2. การทำแบบ Schedule จะทำต่อเมื่อเรารู้เหตุการณ์ข้างหน้าอยู่แล้วว่าจะเกิดขึ้นเมื่อไร กรณีคุณเป็นต้น เพราะเรามีตารางนัดหมาย เรารู้ว่านับจากนาทีนี้ ต่อไปอีกกี่นาทีจะได้เวลาไปพบกับใคร เป็นต้น ฉนั้น เราก็หาค่าช่วงนาทีนับจากเวลานี้จนถึงเวลานัด แล้วนำไปกำหนดใน Timer Interval ตามนั้น เมื่อถึงเวลาจึงทำที่ On Timer ซึ่งมันก็เหมือนการตั้งปลุกธรรมดาครับ ไม่กินแรงเครื่องเพราะมันไม่ได้มีเหตุการณ์อะไรให้ต้องคอยตรวจสอบทุกวินาทีเหมือนอย่าง Real Time
แนวคิดเป็นประมาณนี้นะครับ เดี๋ยวผมยกตัวอย่างการทำให้ดูครับ
8 @R14444
ตัวอย่าง ให้ลองสร้างตารางขึ้นมาดังนี้:
- ข้อมูลในตารางเวลาต้องไม่ซ้ำกัน แต่ไม่จำเป็นต้องเรียงวัน เวลา แต่อย่างไร
ตารางนัดหมาย: สมมุติชื่อ Table1
ID Meet aName
1 12/11/2012 9:29:49 Miss Elyoner
2 10/11/2012 10:30:00 Mr.Richard
3 10/11/2012 13:31:03 Miss Alison
4 12/11/2012 15:32:07 Miss Christien
5 11/11/2012 11:33:12 Mr.Leonard
6 10/11/2012 14:34:31 Mr.William
7 12/11/2012 8:35:44 Mr.Lyonell
8 11/11/2012 13:46:50 Mr.Gerard
9 10/11/2012 16:47:59 Mr.Andrewe
10 12/11/2012 8:45:52 Miss Phillis
- ที่ฟอร์ม Declarations Section ใส่โค๊ดดังนี้:
------------------------
'Option Explicit
Dim T2 As String
------------------------
- ที่ฟอร์ม Event > On Open ใส่โค๊ดดังนี้:
If Not IsNull(DLookup("Meet", "Table1", "DateValue(Meet) = Date() AND TimeValue(Meet) > TimeValue(time())")) Then
Dim T1 As String
'T1 เป็นค่าเวลาที่มากกว่าปัจจุบันที่น้อยที่สุดในตาราง
T1 = TimeValue(DLookup("Min(Meet)", "Table1", "DateValue(Meet) = Date() AND TimeValue(Meet) > TimeValue(time())"))
T2 = DLookup("aName", "Table1", "timevalue(meet) = #" & T1 & "# And datevalue(meet) = date()")
Me.TimerInterval = DateDiff("s", TimeValue(time()), T1) * 1000
Else
MsgBox "ไม่มีนัดหมายในวันนี้", , "เตือนนัดหมาย"
End If
- ที่ฟอร์ม Event > On Timer ใส่โค๊ดดังนี้:
If Not IsNull(DLookup("Meet", "Table1", "DateValue(Meet) = Date() AND TimeValue(Meet) > TimeValue(time())")) Then
MsgBox T2
Dim T1 As String
T1 = TimeValue(DLookup("Min(Meet)", "Table1", "DateValue(Meet) = Date() AND TimeValue(Meet) > TimeValue(time())"))
T2 = DLookup("aName", "Table1", "TimeValue(Meet) = #" & T1 & "# AND DateValue(Meet) = Date()")
Me.TimerInterval = DateDiff("s", TimeValue(time()), T1) * 1000
Else
Me.TimerInterval = 0
MsgBox T2 & " เป็นนัดหมายสุดท้ายในวันนี้", , "เตือนนัดหมาย"
End If
- เท่านี้นะครับ จากนั้นก็ลองแก้ไขเพิ่มเติมตารางดู แล้วทดสอบ ทำความเข้าใจดูนะครับ ว่าคุณจะปรับจากการแสดง MsgBox เป็นการเปิดฟอร์มยังไง จะต้องอ้างฐานข้อมูลอะไรเพิ่มเติม รายละเอียดคุณคงต้องไปปรับแต่งเองนะครับ
- ข้อมูลในตารางเวลาต้องไม่ซ้ำกัน แต่ไม่จำเป็นต้องเรียงวัน เวลา แต่อย่างไร
ตารางนัดหมาย: สมมุติชื่อ Table1
ID Meet aName
1 12/11/2012 9:29:49 Miss Elyoner
2 10/11/2012 10:30:00 Mr.Richard
3 10/11/2012 13:31:03 Miss Alison
4 12/11/2012 15:32:07 Miss Christien
5 11/11/2012 11:33:12 Mr.Leonard
6 10/11/2012 14:34:31 Mr.William
7 12/11/2012 8:35:44 Mr.Lyonell
8 11/11/2012 13:46:50 Mr.Gerard
9 10/11/2012 16:47:59 Mr.Andrewe
10 12/11/2012 8:45:52 Miss Phillis
- ที่ฟอร์ม Declarations Section ใส่โค๊ดดังนี้:
------------------------
'Option Explicit
Dim T2 As String
------------------------
- ที่ฟอร์ม Event > On Open ใส่โค๊ดดังนี้:
If Not IsNull(DLookup("Meet", "Table1", "DateValue(Meet) = Date() AND TimeValue(Meet) > TimeValue(time())")) Then
Dim T1 As String
'T1 เป็นค่าเวลาที่มากกว่าปัจจุบันที่น้อยที่สุดในตาราง
T1 = TimeValue(DLookup("Min(Meet)", "Table1", "DateValue(Meet) = Date() AND TimeValue(Meet) > TimeValue(time())"))
T2 = DLookup("aName", "Table1", "timevalue(meet) = #" & T1 & "# And datevalue(meet) = date()")
Me.TimerInterval = DateDiff("s", TimeValue(time()), T1) * 1000
Else
MsgBox "ไม่มีนัดหมายในวันนี้", , "เตือนนัดหมาย"
End If
- ที่ฟอร์ม Event > On Timer ใส่โค๊ดดังนี้:
If Not IsNull(DLookup("Meet", "Table1", "DateValue(Meet) = Date() AND TimeValue(Meet) > TimeValue(time())")) Then
MsgBox T2
Dim T1 As String
T1 = TimeValue(DLookup("Min(Meet)", "Table1", "DateValue(Meet) = Date() AND TimeValue(Meet) > TimeValue(time())"))
T2 = DLookup("aName", "Table1", "TimeValue(Meet) = #" & T1 & "# AND DateValue(Meet) = Date()")
Me.TimerInterval = DateDiff("s", TimeValue(time()), T1) * 1000
Else
Me.TimerInterval = 0
MsgBox T2 & " เป็นนัดหมายสุดท้ายในวันนี้", , "เตือนนัดหมาย"
End If
- เท่านี้นะครับ จากนั้นก็ลองแก้ไขเพิ่มเติมตารางดู แล้วทดสอบ ทำความเข้าใจดูนะครับ ว่าคุณจะปรับจากการแสดง MsgBox เป็นการเปิดฟอร์มยังไง จะต้องอ้างฐานข้อมูลอะไรเพิ่มเติม รายละเอียดคุณคงต้องไปปรับแต่งเองนะครับ
Time: 0.3379s
เลยเปลี่ยนมาเป็นวันอย่างเดียว โดยทำที่ Event OnOpen ที่ main เมนู
โดยเมื่อถึงวันที่นัดให้โชวข้อมูลวันที่นัด และเอาเวลามาโชด้วย
แต่ถ้าให้เป็นแบบ คำ ถามแล้วโปรแกรมไม่ต้องทำควนตลอดเวลา สงสัย
ต้องรออาจารย์มาตอบ อยากรู้เหมือนกัน