กระทู้เก่าบอร์ด อ.Yeadram
6,043 10
URL.หัวข้อ /
URL
ตั้งให้รันคิวรี่ตามเวลาที่กำหนด
ขอถามผู้รู้ครับ คืออยากเขียน VB หรือ มาโคร ก็ได้ครับแบบว่าอยากให้รันคิวรี่ตัวนึงเมื่อเวลาของระบบ เท่ากับ 11:00:00 ครับ (เป็น append คิวรี่ครับ)
10 Reply in this Topic. Dispaly 1 pages and you are on page number 1
2 @R04893
วิธีที่อาจารย์บอกมาลองทำดูแล้วเราตั้ง timeinterval ให้นับได้ตามเวลาที่กำหนดยากจริงๆครับโดยเฉพาะ property นี้มันจะเริ่มนับตั้งแต่เปิดฟอร์มแล้ววนทำตสมคำสั่ง timer ที่กำหนดตามรอบไปเรื่อยๆเช่นตั้งให้ refresh ทุกๆ15 นาที แต่ผมอยากให้ทำตามคำสั่งก็ต่อเมื่อเวลาของระบบ เท่ากับ 11:00:00 ผมเลยลองเขียนโค้ดขึ้นโดยให้มีตัวแปร เช่น
Dim MyTime
Dim MyStr As String
Dim stDocName As String
stDocName = "Qr_TruckReport"
MyTime = Format(Time, "hh:mm") 'ใส่เวลาแล้วมันเติม AM:PM ให้มันไม่ทำงาน
MyStr = "11:00"
If MyStr = MyTime Then
DoCmd.OpenQuery stDocName, acViewNormal, acEdit
End If
โดยเขียนที่ property oncurent พอเวลาระบบเท่ากับ 11:00 'ตั้งเป็น short time' มันก็ยังไม่ทำงานทันทีแต่ต้องเปลี่ยน form ไปมาให้ form มันแอคทีฟ อีกครั้งแล้วลองไปดูที่ table ที่ตั้งให้ข้อมูล append ก็พบว่ามันทำงานแล้วครับ
ตอนนี้เลยอยากทราบว่าผมควรเอาโค้ดดังกล่าวไปวางไว้ที่ property อะไรดีมันถึงจะทำงานอัตโนมัติเมื่อถึงเวลาทันที ไม่ต้องมาสลับหน้า form เพื่อแอคทีฟมัน
อยากให้อาจารย์ช่วย modify โค้ดให้หน่อยคร้บ พ่วงกับ msgbox แจ้งการทำงานได้ยิ่งดีเลยครับ ขอบคุณครับ
Dim MyTime
Dim MyStr As String
Dim stDocName As String
stDocName = "Qr_TruckReport"
MyTime = Format(Time, "hh:mm") 'ใส่เวลาแล้วมันเติม AM:PM ให้มันไม่ทำงาน
MyStr = "11:00"
If MyStr = MyTime Then
DoCmd.OpenQuery stDocName, acViewNormal, acEdit
End If
โดยเขียนที่ property oncurent พอเวลาระบบเท่ากับ 11:00 'ตั้งเป็น short time' มันก็ยังไม่ทำงานทันทีแต่ต้องเปลี่ยน form ไปมาให้ form มันแอคทีฟ อีกครั้งแล้วลองไปดูที่ table ที่ตั้งให้ข้อมูล append ก็พบว่ามันทำงานแล้วครับ
ตอนนี้เลยอยากทราบว่าผมควรเอาโค้ดดังกล่าวไปวางไว้ที่ property อะไรดีมันถึงจะทำงานอัตโนมัติเมื่อถึงเวลาทันที ไม่ต้องมาสลับหน้า form เพื่อแอคทีฟมัน
อยากให้อาจารย์ช่วย modify โค้ดให้หน่อยคร้บ พ่วงกับ msgbox แจ้งการทำงานได้ยิ่งดีเลยครับ ขอบคุณครับ
3 @R04894
- โค้ดจะอยู่ใน procedure ครับ ไม่ใช่เรียกว่า property
- บอกแล้วว่า มันจะไปทำงานที่ Form_Timer event procedure ครับ ไม่ใช่ Form_OnCurrent event procedure ดังนั้นจึงไม่มีการมานั่งคลิกให้มันต้องเป็นแอคทีฟฟอร์มอะไรทั้งสิ้น
- ใช้ฟังก์ชั่น Timer( ) ซึ่งจะให้ผลเป็นจำนวนวินาทีตั้งแต่เที่ยงคืน มาเป็นตัวทดสอบเวลา 11 น. ได้ (เท่ากับ 39600 วินาทีหลังเที่ยงคืน) นั่นคือ
Private Sub Form_Timer()
Static Done As Boolean
If (Timer( ) <= 39600) and (Done) then
Done = False
ElseIf (Timer( ) > 39600) and (Not Done) then
DoCmd.OpenQuery ....
Done = True
End If
End Sub
- บอกแล้วว่า มันจะไปทำงานที่ Form_Timer event procedure ครับ ไม่ใช่ Form_OnCurrent event procedure ดังนั้นจึงไม่มีการมานั่งคลิกให้มันต้องเป็นแอคทีฟฟอร์มอะไรทั้งสิ้น
- ใช้ฟังก์ชั่น Timer( ) ซึ่งจะให้ผลเป็นจำนวนวินาทีตั้งแต่เที่ยงคืน มาเป็นตัวทดสอบเวลา 11 น. ได้ (เท่ากับ 39600 วินาทีหลังเที่ยงคืน) นั่นคือ
Private Sub Form_Timer()
Static Done As Boolean
If (Timer( ) <= 39600) and (Done) then
Done = False
ElseIf (Timer( ) > 39600) and (Not Done) then
DoCmd.OpenQuery ....
Done = True
End If
End Sub
4 @R04896
อาจารย์ครับจากที่บอกมาถ้ามีการเปลี่ยนกะของผู้ใช้โปรแกรมตัวนี้ต้อง logoff เครื่องแล้วเปิดใหม่เพื่อเข้ารหัสของตนเอง หรือบางครั้งถ้าจำเป็นต้องปิดเครื่องแล้วถ้าเปิดมาใหม่ฟอร์มจะนับเวลาใหม่และฟังชั่นนี้จะมีผลก็ต่อเมื่อนับครบ 39600 มิลลิวินาทีอีกครั้งจึงจะทำคำสั่งนี้หรือเปล่าครับเพราะเราไม่สามารถทราบได้ว่าผู้ใช้จะปิดเครื่องและเปิดอีกทีเมื่อไหร่ครับ
5 @R04898
โปรแกรมนี้ทำงานภายใต้ Access ถ้าไม่เปิดก็ทำงานไม่ได้ ถ้า logoff แล้ว logon ใหม่ ก็ทำให้รันคิวรี่ซ้ำก็ได้เช่นกัน .. ถ้าอย่างนั้นคุณควรจะตั้งให้โปรแกรมถูกเรียกใช้จาก Windows Scheduling แทน และโปรแกรมก็ไม่ต้องมีฟอร์มอะไรเลย ทำเป็นแค่แมโคร ซึ่งมีเฉพาะคำสั่งเพื่อรันคิวรี่และออกจากโปรแกรมเท่านั้น ส่วน command-line ที่เรียกก็ใช้ drive:\path\path\...\msaccess.exe /x ชื่อแมโคร
6 @R04902
อาจารย์ครับผมลองเอาโค้ดของผมไปวางไว้ที่ event procedure ของ Timer
ครับแล้วตั้ง Time Interval = 1000 (1นาที)เพื่อให้มันตรวจสอบว่าถึงตามที่กำหนดหรือยัง และเปลี่ยน format ของเวลาเป็น Long Time ที่ต้องเปลี่ยนเพราะเวลาผมคีย์ #11:00:00# มันจะเปลี่ยนเป็น #11:00:00 AM# ไม่ก้อ #23:00:00PM# อัตโนมัติเลยครับทั้งที่ผมเปลี่ยนเวลาระบบเป็น Short Time แล้วตอนนี้ลองใช้แล้วไม่มีปัญหาครับ แต่ผมไม่เก่งเรื่องโค้ดเลยอาจยังหาวิธีเขียนหรือฟังชั่นที่กระชับกว่านี้ไม่ได้ครับ รู้สึกว่าน่าจะใช้พวก select case จะสั้นกว่านี้
ถ้ามีปัญหาอีกจะขอเข้ามาถามอีกนะครับ
Private Sub Form_Timer()
Dim MyTime
Dim MyStr1, MyStr2, MyStr3, MyStr4, MyStr5, MyStr6, MyStr7, MyStr8 As String
Dim stDocName As String
stDocName = "Qr_TruckReport"
MyTime = Format(Time, "hh:mm:ss")
MyStr1 = "08:00:00"
MyStr2 = "11:00:00"
MyStr3 = "14:00:00"
MyStr4 = "17:00:00"
MyStr5 = "20:00:00"
MyStr6 = "23:00:00"
MyStr7 = "02:00:00"
MyStr8 = "05:00:00"
If MyStr1 = MyTime Or MyStr2 = MyTime Or MyStr3 = MyTime Or MyStr4 = MyTime Or MyStr5 = MyTime Or MyStr6 = MyTime Or MyStr7 = MyTime Or MyStr8 = MyTime Then
MsgBox "This time is ontime, press OK ", vbInformation + vbOKOnly, "Confirmation Box"
DoCmd.OpenQuery stDocName, acViewNormal, acEdit
End If
End Sub
ครับแล้วตั้ง Time Interval = 1000 (1นาที)เพื่อให้มันตรวจสอบว่าถึงตามที่กำหนดหรือยัง และเปลี่ยน format ของเวลาเป็น Long Time ที่ต้องเปลี่ยนเพราะเวลาผมคีย์ #11:00:00# มันจะเปลี่ยนเป็น #11:00:00 AM# ไม่ก้อ #23:00:00PM# อัตโนมัติเลยครับทั้งที่ผมเปลี่ยนเวลาระบบเป็น Short Time แล้วตอนนี้ลองใช้แล้วไม่มีปัญหาครับ แต่ผมไม่เก่งเรื่องโค้ดเลยอาจยังหาวิธีเขียนหรือฟังชั่นที่กระชับกว่านี้ไม่ได้ครับ รู้สึกว่าน่าจะใช้พวก select case จะสั้นกว่านี้
ถ้ามีปัญหาอีกจะขอเข้ามาถามอีกนะครับ
Private Sub Form_Timer()
Dim MyTime
Dim MyStr1, MyStr2, MyStr3, MyStr4, MyStr5, MyStr6, MyStr7, MyStr8 As String
Dim stDocName As String
stDocName = "Qr_TruckReport"
MyTime = Format(Time, "hh:mm:ss")
MyStr1 = "08:00:00"
MyStr2 = "11:00:00"
MyStr3 = "14:00:00"
MyStr4 = "17:00:00"
MyStr5 = "20:00:00"
MyStr6 = "23:00:00"
MyStr7 = "02:00:00"
MyStr8 = "05:00:00"
If MyStr1 = MyTime Or MyStr2 = MyTime Or MyStr3 = MyTime Or MyStr4 = MyTime Or MyStr5 = MyTime Or MyStr6 = MyTime Or MyStr7 = MyTime Or MyStr8 = MyTime Then
MsgBox "This time is ontime, press OK ", vbInformation + vbOKOnly, "Confirmation Box"
DoCmd.OpenQuery stDocName, acViewNormal, acEdit
End If
End Sub
7 @R04908
- 1000 มิลลิวินาที = 1 วินาทีครับ ไม่ใช่ 1 นาที
- การเช็คเวลา (หรือวันที่ หรือวันที่พร้อมเวลา) ไม่ควรเปรียบเทียบตรวจสอบในรูปแบบของ string มันไม่ใช่รูปแบบที่เหมาะสม ควรใช้ฟังก์ชั่น Time หรือ Timer (อย่างที่ผมในตัวอย่างก่อนหน้า) เพราะนำไปเปรียบกับค่าคงที่ที่มีรูปแบบแน่นอนได้ง่ายกว่า เช่นฟังก์ชั่น Time จะคืนค่าเป็นประเภทข้อมูลของ Variant (มี sub data type เป็นประเภท Date) ซึ่งเอาไปเปรียบกับค่าคงที่ของเวลาในรูปแบบ #ชม:นาที:วินาที# ได้เหมาะสมกว่า (เวลาป้อนค่าคงที่ของเวลา (หรือวันที่) แล้วมันแปลงให้ มี AM , PM ออกมาก็ช่างมันนะครับ ไม่เป็นไร) ดังนั้นถ้าเทียบกับโค้ดที่คุณเขียนแล้ว ก็น่าได้เป็น
Dim T As Variant
T = Time
If (T = #8:00:00 AM#) Or (T = #10:00:00 AM#) Or (T = #2:00:00 PM#) Then
...
...
...
End If
แต่อย่างที่ผมบอก การจะทดสอบเวลาให้ได้ตรงเปี๊ยะๆในระดับวินาที มันอาจไม่ได้อย่างที่คิด ทำให้คิวรี่ไม่ทำงานก็เป็นไปได้
- การเช็คเวลา (หรือวันที่ หรือวันที่พร้อมเวลา) ไม่ควรเปรียบเทียบตรวจสอบในรูปแบบของ string มันไม่ใช่รูปแบบที่เหมาะสม ควรใช้ฟังก์ชั่น Time หรือ Timer (อย่างที่ผมในตัวอย่างก่อนหน้า) เพราะนำไปเปรียบกับค่าคงที่ที่มีรูปแบบแน่นอนได้ง่ายกว่า เช่นฟังก์ชั่น Time จะคืนค่าเป็นประเภทข้อมูลของ Variant (มี sub data type เป็นประเภท Date) ซึ่งเอาไปเปรียบกับค่าคงที่ของเวลาในรูปแบบ #ชม:นาที:วินาที# ได้เหมาะสมกว่า (เวลาป้อนค่าคงที่ของเวลา (หรือวันที่) แล้วมันแปลงให้ มี AM , PM ออกมาก็ช่างมันนะครับ ไม่เป็นไร) ดังนั้นถ้าเทียบกับโค้ดที่คุณเขียนแล้ว ก็น่าได้เป็น
Dim T As Variant
T = Time
If (T = #8:00:00 AM#) Or (T = #10:00:00 AM#) Or (T = #2:00:00 PM#) Then
...
...
...
End If
แต่อย่างที่ผมบอก การจะทดสอบเวลาให้ได้ตรงเปี๊ยะๆในระดับวินาที มันอาจไม่ได้อย่างที่คิด ทำให้คิวรี่ไม่ทำงานก็เป็นไปได้
8 @R04914
ผมเขียนผิดครับต้องเป็น 1 วินาทีตามที่อาจารย์บอกครับแต่โค้ดที่ผมเขียนใช้ได้ปกติตามเวลาที่กำหนดเลยครับเพราะทุกวินาทีที่กำหนดตรง timeinterval ถ้าเงื่อนไขตรงตามโค้ดมันจะทำงานทันทีเลยครับและมี msgbox ขึ้นเตือนว่ามีการทำงานตอนแรกมันเตือนในเรื่อง actionquery ด้วยครับผมเลยเอาติ๊กใน tool,option,actionquery ออกมันก็เลยเตือนเฉพาะที่ต้องการแล้วหลังจากใช้มาจนถึงวันนี้ยังไม่มีปัญหาอะไรขอแค่ ณ เวลาตามที่โค้ดกำหนด อย่า backup,ปิดเครื่อง,และภาวนาอย่าให้ไฟดับก็พอครับ พอลองเข้าไปตรวจใน table ที่มีการ append ก็พบข้อมูลตามต้องการเนื่องจากผมเพิ่ม field ให้ขึ้นเวลาปัจจุบันที่ทำการ append ไว้ด้วย แต่จะลองใช้โค้ดของอาจารย์ดูครับจะได้ลดขั้นตอนการเขียนโค้ดลงไม่ต้องแปลงเป็น string ก่อน ขอบคุณครับตอนนี้ผมเริ่มจะศึกษาเรื่องโค้ดมากขึ้นเพราะรู้สึกว่ามันทำอะไรได้เยอะแต่ยังมีโค้ดอีกเยอะที่ไม่รู้จักและไม่รู้ว่ามันใช้ทำอะไรถ้ามีหนังสือที่ลงรายละเอียดเกี่ยวกับ codelist อย่างละเอียดคงดีครับเพราะคนที่ไม่ได้เรียนมาทางนี้แต่จำเป็นต้องใช้ในการทำงานจะได้ใช้ประโยชน์ได้เต็มที่
9 @R04915
ลองปรับตามแบบของอาจารย์แล้วครับสุดยอดไปเลยครับตอบโจทย์เลยครับแถมยังเขียนโค้ดน้อยลงไม่ต้องแปลง format ให้ยุ่งยากแต่กลับให้ผลสำเร็จเหมือนกันแล้วตอนนี้ผมลองเอาบรรทัดของ msgbox ลงมาวางต่อจากบรรทัดที่ให้ append query
ยิ่งทำให้เวลาที่บรรทึกใน table ตรงเป็ะเลยครับ ก่อนหน้านี้มันหย่อน 2 วินาทีครับอาจเป็นเพราะก่อนนี้ต้องกด ok ที่ msgbox ก่อนค่อยมาทำ query แต่พอสลับบรรทัดมันเลยทำ query ณ เวลาที่กำหนดไว้ตามเวลาก่อนแล้วค่อยโชว์ msgbox
คราวหน้าคงต้องขอรบกวนอีกนะครับอย่าเพิ่งรำคาญ ขอบคุณครับ
ยิ่งทำให้เวลาที่บรรทึกใน table ตรงเป็ะเลยครับ ก่อนหน้านี้มันหย่อน 2 วินาทีครับอาจเป็นเพราะก่อนนี้ต้องกด ok ที่ msgbox ก่อนค่อยมาทำ query แต่พอสลับบรรทัดมันเลยทำ query ณ เวลาที่กำหนดไว้ตามเวลาก่อนแล้วค่อยโชว์ msgbox
คราวหน้าคงต้องขอรบกวนอีกนะครับอย่าเพิ่งรำคาญ ขอบคุณครับ
10 @R04916
ระวังไว้นะครับ ยังไงผมก็ยืนยันว่ามันอาจตรวจสอบไม่ได้ตรงเวลาอย่างที่ว่าไว้ เพราะว่า ระบบ Time Interval ของ Access เอง มันจะทำงานได้ตรงเวลาก็ต่อเมื่อเครื่องว่างจากงานอื่นๆแล้วเท่านั้น ถ้ายังใช้อัลกอริธึมแบบเดิม คุณต้องยอมรับในผลที่ว่าบางช่วงเวลา คิวรี่ของคุณอาจไม่ได้ทำงานนะครับ
Time: 0.3462s
สิ่งที่ต้องระวังก็คือ
1) การตรวจสอบว่าเท่ากับเวลา 11 น.ตรงเป๋งนั้น เป็นสิ่งที่เกิดขึ้นได้ยาก แนะนำว่าให้ทดสอบว่าอยู่ในช่วงหลัง 11 น.เป็นต้นไปน่าจะถูกต้องกว่า
2) ต้องเขียนให้โปรแกรมรู้ว่า วันนี้ทำงานไปแล้ว ไม่ต้องทำงานซ้ำอีก
ลองเอาหลักการนี้ไปเขียนดูก่อนนะครับ ติดขัดตรงไหนค่อยมาว่ากันอีกที หรือลองค้นกระทู้เก่าด้วยคำว่า Timer ก็ได้ครับ