Page 1 of 1

ตั้งเวลาใน VBA ให้รัน Marco เป็น 4 ช่วง แต่ไม่อยากให้มันตรวจสอบเวลาตลอดได้ไหมครับ

Posted: Thu Jun 29, 2017 11:54 am
by bpond
ตั้งเวลาใน VBA ให้รัน Marco เป็น 4 ช่วง แต่ไม่อยากให้มันตรวจสอบเวลาตลอดได้ไหมครับ

Code: Select all

Sub AutoTimer()
    
    Application.OnTime TimeValue("10:00:00"), "StartTimer"
    Application.OnTime TimeValue("12:30:00"), "StopTimer"
    Application.OnTime TimeValue("14:30:00"), "StartTimer"
    Application.OnTime TimeValue("16:30:00"), "StopTimer"
    
End Sub
คือ มันทำงานเรียก Marco ตามที่ต้องการนะครับ แต่เหมือนไฟล์มัน Refresh ข้อมูลเพื่อตรวจสอบเวลาตลอด
ทำให้เมื่อนำไปใส่ในไฟล์ที่ใช้งานจริง มีผลกระทบกับการทำงานของ Marco ตัวอื่นที่อิงกับ Marco "StartTimer"
เพราะ Sub StartTimer() ทำงานไปแป๊บเดียว ก็โดน Sub AutoTimer() เรียกตรวจสอบเวลาอีกแล้ว
ทำให้ Marco ตัวอื่นที่อิงกับ StartTimer หยุดการทำงาน แล้วเริ่มใหม่ตั้งแต่ต้นไปด้วย

*อยากให้พอ Sub AutoTimer() เรียกรัน Marco StartTimer ไปแล้วก็ไม่ต้องทำอะไร หรือ Refresh อีก
จนถึงเวลาที่ตั้งไว้ตอน 12:30:00 แล้วเรียกค่อย StopTimer แล้วก็ไม่ต้องทำอะไร
จนถึงเวลา 14:30:00 จึงเรียก StartTimer อีกครั้ง แล้วก็รอเรียก StopTimer อีกทีตอน 16:30:00 เป็นอันเสร็จการทำงาน

Code ของ StartTimer กับ StopTimer ครับ

Code: Select all

Sub StartTimer()
    Dim t As String
    With Sheets("VolCalculation")
        t = Format(.Range("G8").Value, "00")
        t = t & ":" & Format(.Range("H8").Value, "00")
        t = t & ":" & Format(.Range("I8").Value, "00")
    End With
    dTime = Now + TimeValue(t)
    Application.OnTime dTime, "ValueStore", Schedule:=True
End Sub

Sub StopTimer()
    On Error Resume Next
    Application.OnTime dTime, "ValueStore", Schedule:=False
End Sub
รบกวนช่วยชี้แนะด้วยครับ
ขอขอบคุณล่วงหน้านะครับ

Re: ตั้งเวลาใน VBA ให้รัน Marco เป็น 4 ช่วง แต่ไม่อยากให้มันตรวจสอบเวลาตลอดได้ไหมครับ

Posted: Thu Jun 29, 2017 1:00 pm
by snasui
:D การทำเช่นนั้นไม่สามารถทำได้ด้วย VBA โดยลำพัง หากทำด้วย VBA จะเกิดการตรวจสอบเวลาอยู่เสมอ

หากจะทำก็ต้องตั้ง Job ผ่าน Windows สามารถกำหนดเวลาให้ Run Job ได้ตามต้องการ ตัวอย่างเช่นตั้ง Job เพื่อให้เปิดไฟล์โปรแกรมนี้หรือเปิดไฟล์อื่นที่สามารถเรียก Procedure ในโปรแกรมนี้ เมื่อเปิดแล้วจะเกิดการ Run Macro แล้วปิดไฟล์โปรแกรมนั้นไป เมื่อถึงเวลาที่กำหนดก็จะทำเช่นเดิมไปเรื่อย ๆ เช่นนี้เป็นต้นครับ

Re: ตั้งเวลาใน VBA ให้รัน Marco เป็น 4 ช่วง แต่ไม่อยากให้มันตรวจสอบเวลาตลอดได้ไหมครับ

Posted: Thu Jun 29, 2017 5:42 pm
by bpond
ผมใช้วิธีนี้ได้ไหมครับ

ผมทดลองได้แค่ไฟล์ตัวอย่าง ซึ่งทำงานเรียกใช้ Sub และ Macro ต่างๆ และหยุด ได้ตามเวลาที่กำหนดไว้
แต่ผมไม่รู้ว่า ปัญหาที่มัน Refresh เพื่อตรวจสอบเวลา มันจะมีผลกระทบกับ Macro ตัวหลักที่อ้างอิงไหม(StartTimer)
เพราะไฟล์ที่ใช้งานจริง จะปล่อยข้อมูล real time เฉพาะช่วง 10:00 - 16:30 ทำให้ยังทดสอบจริงไม่ได้

แต่ผมอยากรบกวนช่วยดู Code ที่ผมปรับก่อนนะครับ ถ้าไม่ work จะได้หาทางอื่นต่อนะครับ
ขอบคุณมากครับ

Code: Select all

Sub AutoTimer()
    
    Application.OnTime TimeValue("17:22:00"), "AutoOn", Schedule:=True
    On Error Resume Next
    Application.OnTime TimeValue("17:22:01"), "AutoOn", Schedule:=False
    Application.OnTime TimeValue("17:23:00"), "AutoOff"
    Application.OnTime TimeValue("17:24:00"), "AutoOn", Schedule:=True
    On Error Resume Next
    Application.OnTime TimeValue("17:24:01"), "AutoOn", Schedule:=False
    Application.OnTime TimeValue("17:25:00"), "AutoOff"
    
End Sub

Code: Select all

Sub AutoOn()

    Call StartTimer
    
End Sub

Code: Select all

Sub AutoOff()
 
    Call StopTimer
    
End Sub

Re: ตั้งเวลาใน VBA ให้รัน Marco เป็น 4 ช่วง แต่ไม่อยากให้มันตรวจสอบเวลาตลอดได้ไหมครับ

Posted: Fri Jun 30, 2017 8:27 am
by logic
ความเห็นผม ontime มันตรวจเวลาอยู่ตลอดครับ ไม่ว่าจะให้มันหยุดหรือให้มันทำงาน ถ้าไม่ตรวจมันจะรู้ได้อย่างไรว่ามันต้อง run ถ้าไม่มีให้ลองก็ต้องทดสอบตอนเวลาจริงแล้วละครับ

Re: ตั้งเวลาใน VBA ให้รัน Marco เป็น 4 ช่วง แต่ไม่อยากให้มันตรวจสอบเวลาตลอดได้ไหมครับ

Posted: Fri Jun 30, 2017 10:24 am
by bpond
ขอบคุณ คุณsnasui กับ คุณlogic ครับ

แจ้งความคืบหน้าครับ ไฟล์ที่ผมแก้ไปแบบบ้านๆ ใช้งานได้ครับ
ผมสร้าง Sub ย่อย (AutoOn) ใน Sub AutoTimer อีกทีครับ โดยให้ไปเรียก Macro(StartTimer) ตัวหลักที่อิงกับหลายเงื่อนไขแทน
พอ Sub AutoTimer ตรวจสอบเวลา แล้วตรงกับเวลาที่กำหนดไว้ ก็จะเรียก Sub ย่อย AutoOn ให้ทำงาน หลังจากเรียกเสร็จ ก็ให้มันหยุดทำงานซะ
โดยที่ตัว Macro หลัก(StartTimer) ยังคงทำงานต่อไป ไม่มีผลกระทบจากการ Refresh ของ Sub AutoTimer

เอ่.. ผมก็อธิบายไม่เก่ง ไม่ทราบว่าพอจะเข้าใจไหมนะครับ แต่ตอนนี้ ช่วงแรกยังทำงานได้ดี แต่ยังต้องลองให้ Sub AutoTimer
ทำงานให้เสร็จทั้งหมดตามเวลาที่ตั้งไว้ก่อน เพื่อดูว่าจะเกิด Error อะไรไหม แล้วผมจะมา Update อีกทีนะครับ

ขอบคุณมากๆนะครับ

Re: ตั้งเวลาใน VBA ให้รัน Marco เป็น 4 ช่วง แต่ไม่อยากให้มันตรวจสอบเวลาตลอดได้ไหมครับ

Posted: Fri Jun 30, 2017 5:33 pm
by bpond
ไฟล์ทำงานสมบูรณ์ครับ ^^

Re: ตั้งเวลาใน VBA ให้รัน Marco เป็น 4 ช่วง แต่ไม่อยากให้มันตรวจสอบเวลาตลอดได้ไหมครับ

Posted: Sat Jul 01, 2017 12:53 pm
by bpond
อยากให้ VBA ตรวจสอบถ้าอยู่ในช่วงเวลาที่กำหนดไว้ ให้ทำงาน แต่ถ้ายังไม่ใช่ ให้รอ

ตอนนี้ เมื่อกดปุ่ม AutoREC แล้ว VBA จะรอถึงเวลาที่กำหนดไว้ ถึงจะทำงาน
แต่เราอยากกำหนดเป็นเวลาให้ทำงาน เช่น เมื่อกดปุ่ม AutoREC ถ้าอยู่ในช่วงเวลา 10:00 - 12:30 ให้ทำงานเลย
แต่ถ้ายังไม่ถึง 10:00 ก็ให้รอจนถึง 10:00 แล้วถึงทำงานน่ะครับ

Code ตอนนี้ผมเขียนแบบนี้ครับ

Code: Select all

Sub AutoTimer()
    
    Application.OnTime TimeValue("10:00:00"), "AutoOn", Schedule:=True
    On Error Resume Next
    Application.OnTime TimeValue("10:00:01"), "AutoOn", Schedule:=False
    Application.OnTime TimeValue("12:30:00"), "AutoOff"
    Application.OnTime TimeValue("14:30:00"), "AutoOn", Schedule:=True
    On Error Resume Next
    Application.OnTime TimeValue("14:30:01"), "AutoOn", Schedule:=False
    Application.OnTime TimeValue("16:30:00"), "AutoOff"
    
End Sub
รบกวนช่วยชี้แนะด้วยครับ
ขอบคุณครับ

Re: ตั้งเวลาใน VBA ให้รัน Marco เป็น 4 ช่วง แต่ไม่อยากให้มันตรวจสอบเวลาตลอดได้ไหมครับ

Posted: Sat Jul 01, 2017 1:01 pm
by snasui
:D Ontime ที่เขียนไว้คือการรอเมื่อถึงเวลาจึงจะทำงานครับ สำหรับ Code นี้จะตรวจสอบเวลาเมื่อคลิกเลยทันที เพียงแต่รอให้ถึงกำหนดตามเงื่อนไขจึงจะทำงานต่อไปจากนั้น

ถ้าหมายถึงว่าคลิกไปแล้วหากถ้าไม่อยู่ในช่วงเวลาที่กำหนดให้ข้ามไปก่อน หากอยู่ในช่วงเวลาที่กำหนดให้ทำการ Run เราสามารถใช้ If เข้ามาช่วยการตัดสินใจได้ แต่จะต้องคลิกตรวจสอบด้วยคนหรือโปรแกรมที่เขียนมาต่างหาก ถ้าตั้งเวลาให้ Run ก็จะเข้าลักษณะเดิม คือคลิกแล้วมันจะทำงานทันทีครับ

Re: ตั้งเวลาใน VBA ให้รัน Marco เป็น 4 ช่วง แต่ไม่อยากให้มันตรวจสอบเวลาตลอดได้ไหมครับ

Posted: Sat Jul 01, 2017 8:35 pm
by bpond
ตามที่ คุณ snasui แนะนำให้ใช้ IF เข้ามาช่วยการตัดสินใจ

ผมเลยลองเขียน Code VBA โดยใช้ความเข้าใจน้อยๆของผมดู
ส่วนเรื่องการประกาศค่าตัวแปร หรือ การ Dim อะไรลึกๆนั้นผมมั่วเอาล้วนๆ Code ก็ไม่มีขึ้น Error นะครับ

แต่ Macro ไม่ทำงาน ผมไม่รู้ว่าที่ไม่ทำงานนั้น เพราะผมเขียน VBA แทนค่าตัวแปรผิดชนิด หรือ เขียนโครงสร้างของ VBA ผิด
หรือ จริงๆแล้วไม่สามารถ ใช้ VBA เขียน Code เพื่อให้ทำงานในแบบที่ผมต้องการได้เลยน่ะครับ

รบกวนช่วยชี้แนะด้วยครับ
ขอบคุณครับ ^^

Code: Select all

Option Explicit
Public dTime As Date
Public aTime As Date
Public bTime As Date

Sub ValueStore()
Dim NC As Long

With Sheets("VolCalculation")
    NC = .Cells(2, .Columns.Count).End(xlToLeft).Column + 1
    .Cells(2, NC).Resize(2).Value = .Range("C2:C3").Value
    If NC > 30 Then .Range("D2:D3").Delete xlShiftToLeft
End With
Application.CutCopyMode = False

Call StartTimer

End Sub

Sub StartTimer()
    Dim t As String
    With Sheets("VolCalculation")
        t = Format(.Range("G8").Value, "00")
        t = t & ":" & Format(.Range("H8").Value, "00")
        t = t & ":" & Format(.Range("I8").Value, "00")
    End With
    dTime = Now + TimeValue(t)
    Application.OnTime dTime, "ValueStore", Schedule:=True
End Sub

Sub StopTimer()
    On Error Resume Next
    Application.OnTime dTime, "ValueStore", Schedule:=False
End Sub

Sub AutoOn()

    Call StartTimer
    
End Sub

Sub AutoOff()
 
    Call StopTimer
    
End Sub

Sub ConditionAuto()

aTime = Now()

If aTime >= TimeValue("10:00:00") And aTime <= TimeValue("12:30:00") Then
Call AutoTimer1
If aTime > TimeValue("12:30:00") And aTime <= TimeValue("14:30:00") Then
Call AutoTimer2
If aTime > TimeValue("14:30:00") And aTime <= TimeValue("16:30:00") Then
Call AutoTimer3
Else
Call AutoTimer0
End If
End If
End If

End Sub

Sub AutoTimer0()
    
    Application.OnTime TimeValue("10:00:00"), "AutoOn", Schedule:=True
    On Error Resume Next
    Application.OnTime TimeValue("10:00:01"), "AutoOn", Schedule:=False
    Application.OnTime TimeValue("12:30:00"), "AutoOff"
    Application.OnTime TimeValue("14:30:00"), "AutoOn", Schedule:=True
    On Error Resume Next
    Application.OnTime TimeValue("14:30:01"), "AutoOn", Schedule:=False
    Application.OnTime TimeValue("16:30:00"), "AutoOff"
    
End Sub

Sub AutoTimer1()

    aTime = Now()
    bTime = Now + TimeValue("00:00:01")
    
    Application.OnTime aTime, "AutoOn", Schedule:=True
    On Error Resume Next
    Application.OnTime bTime, "AutoOn", Schedule:=False
    Application.OnTime TimeValue("12:30:00"), "AutoOff"
    Application.OnTime TimeValue("14:30:00"), "AutoOn", Schedule:=True
    On Error Resume Next
    Application.OnTime TimeValue("14:30:01"), "AutoOn", Schedule:=False
    Application.OnTime TimeValue("16:30:00"), "AutoOff"
    
End Sub

Sub AutoTimer2()

    Application.OnTime TimeValue("14:30:00"), "AutoOn", Schedule:=True
    On Error Resume Next
    Application.OnTime TimeValue("14:30:01"), "AutoOn", Schedule:=False
    Application.OnTime TimeValue("16:30:00"), "AutoOff"

End Sub

Sub AutoTimer3()

    aTime = Now()
    bTime = Now + TimeValue("00:00:01")
    
    Application.OnTime aTime, "AutoOn", Schedule:=True
    On Error Resume Next
    Application.OnTime bTime, "AutoOn", Schedule:=False
    Application.OnTime TimeValue("16:30:00"), "AutoOff"

End Sub

Re: ตั้งเวลาใน VBA ให้รัน Marco เป็น 4 ช่วง แต่ไม่อยากให้มันตรวจสอบเวลาตลอดได้ไหมครับ

Posted: Sat Jul 01, 2017 9:09 pm
by snasui
:D ผมอ่านจากใน Comment มีคำถามตามด้านล่างครับ

Procedure ConditionAuto ถูกเรียกด้วย Procedure ใดหรือทำงานเมื่อใด ทำงานตลอดเวลาหรือทำงานครั้งเดียวครับ

หากทำงานครั้งเดียวเมื่อคลิกหรือเมื่อเกิดเหตุการณ์ใดก็จะเป็นเช่นที่ผมโพสต์ไปแล้วว่ามันจะ Run แค่ครั้งนั้น ๆ ที่คลิกหรือเกิดเหตุการณ์นั้น ไม่ได้เช็คอยู่ตลอดเวลาครับ

Re: ตั้งเวลาใน VBA ให้รัน Marco เป็น 4 ช่วง แต่ไม่อยากให้มันตรวจสอบเวลาตลอดได้ไหมครับ

Posted: Sat Jul 01, 2017 10:47 pm
by bpond
ผมไม่แน่ใจนะครับว่า ผมเข้าใจคำถามคุณ snusui ถูกไหม แต่ผมจะพยายามอธิบายนะครับ ^^

Macro "ConditionAuto" ถูกเรียกให้ทำงานครั้งเดียวเมื่อคลิ้กปุ่ม "Auto REC"
เพื่อเลือก ว่า "aTime(เวลา ณ.ขณะนั้น)" ตรงกับ Condition ใด

ถ้า aTime อยู่ในช่วงเวลาใดที่กำหนดไว้ ก็ให้เรียก Sub AutoTimer1, 2, 3 ตามนั้น ถ้าไม่อยู่ในช่วงเวลาใดๆที่กำหนดไว้เลย ก็ให้เรียก Sub AutoTimer0

**Sub AutoTimer0() นั้น ในไฟล์ Excel ก่อนหน้านี้ ถูกกำหนดให้เป็น Macro ในปุ่ม "Auto REC" และเรียกให้ทำงานเมื่อกดปุ่ม (ซึ่งกดปุ่มเพียงครั้งเดียว แต่ Macro นี้จะรันและเช็คเวลาตลอด และทำงานจนหมดช่วงเวลาที่กำหนดไว้)

ซึ่งก็ทำงานตามแบบที่ต้องการเลย คือ Macro "AutoTimer0" จะเช็คเวลาตลอด และจะรอจนถึง เวลาที่กำหนดไว้ คือ 10:00:00 ก็จะเรียก Sub "AutoOn" ให้ทำงาน ซึ่ง "AutoOn" จะไปเรียก "StartTimer" ให้ทำงานอีกต่อนึง หลังจากนั้น 1 วินาที "AutoOn" ก็หยุดทำงาน แต่ "StartTimer" ยังคงทำงานต่อไป

โดยที่ Macro "AutoTimer0" ซึ่งยังคงเช็คเวลาอยู่ พอถึงเวลา 12:30:00 ตรงตามกำหนดไว้ ก็เรียก Sub "AutoOff" เพื่อให้เรียก "StopTimer" ทำงานอีกที และ Macro "AutoTimer0" ก็ยังคงเช็คเวลาต่อและเรียก Sub ที่เหลือและให้ทำงานจนหมดช่วงเวลาที่กำหนดไว้

แต่นั่น เราจะต้องกดปุ่ม "AutoTimer" ก่อนเวลา 10:00:00 เพราะถ้ากดหลังจาก 10:00:00 เราจะต้องรอไปจนถึง 14:30:00 เพื่อให้มันเรียกรัน "AutoOn" ตามที่เรากำหนดไว้ให้


ดังนั้น ผมจึงเอา Code ของ "AutoTimer0" มาปรับใช้กับ AutoTimer1, 2 และ 3 และใส่เงื่อนไข เพื่อให้เวลาเรากดปุ่ม "Auto REC" ปุ๊บ VBA จะตรวจสอบว่าเวลาตอนนั้นตรงกับ เงื่อนไขช่วงเวลาใดก่อน แล้วจึงสั่งให้เรียก Sub นั้นๆทำงานอีกที

ซึ่งตรงจุดนี้ครับ ที่ผมไม่แน่ใจว่า

1. ผมแทนค่าตัวแปร aTime กับ bTime ใน AutoTimer1 กับ 3 ถูกวิธีไหม และ
2. จุดที่ผมแทนค่า aTime และ TimeValue เพื่อเปรียบเทียบช่วงเวลา และใช้ IF ตัดสินใจใน "ConditionAuto" ตอนแรกสุดนั้น ถูกต้องด้วยไหมครับ

รบกวนชี้แนะด้วยครับ
ขอบคุณมากๆครับ

Re: ตั้งเวลาใน VBA ให้รัน Marco เป็น 4 ช่วง แต่ไม่อยากให้มันตรวจสอบเวลาตลอดได้ไหมครับ

Posted: Sat Jul 01, 2017 11:20 pm
by snasui
:D Code น่าจะเป็นลักษณะด้านล่างจึงจะเช็คทุกเงื่อนไขและถ้าไม่เข้าเงื่อนไขใดจะ Run AtoTimer0 ครับ

Code: Select all

Sub ConditionAuto()
    aTime = Now()
    If aTime >= TimeValue("10:00:00") And aTime <= TimeValue("12:30:00") Then
        Call AutoTimer1
    ElseIf aTime > TimeValue("12:30:00") And aTime <= TimeValue("14:30:00") Then
        Call AutoTimer2
    ElseIf aTime > TimeValue("14:30:00") And aTime <= TimeValue("16:30:00") Then
        Call AutoTimer3
    Else
        Call AutoTimer0
    End If
End Sub
เท่าที่ดูการตั้งค่าตัวแปรสามารถใช้ได้ หากต้องการทราบว่าค่าตัวแปรเป็นค่าใดเราสามารถใช้ Immediate Window ตรวจสอบได้ในขั้นตอน Debug การเปิด Immediate Window กดแป้น Ctrl+G และหากจะเช็คค่าตัวแปร ให้คีย์ที่ Immediate Window เป็นเช่น ?aTime ก็จะทราบว่าตัวแปร aTime มีค่าเป็นเท่าไร เช่นนี้ครับ

Re: ตั้งเวลาใน VBA ให้รัน Marco เป็น 4 ช่วง แต่ไม่อยากให้มันตรวจสอบเวลาตลอดได้ไหมครับ

Posted: Sat Jul 01, 2017 11:23 pm
by bpond
ขอบคุณมากๆครับ เดี๋ยวผมจะทดลอง Code พรุ่งนี้
เสร็จแล้วได้ผลอย่างไร จะรีบมาแจ้งนะครับ

กู๊ดไนท์นะครับ คุณ snasui ^^

Re: ตั้งเวลาใน VBA ให้รัน Marco เป็น 4 ช่วง แต่ไม่อยากให้มันตรวจสอบเวลาตลอดได้ไหมครับ

Posted: Sun Jul 02, 2017 12:06 am
by bpond
ผมรอจนพรุ่งนี้ไม่ไหวครับ มันคาใจ ^^

การตรวจสอบเงื่อนไขใน "ConditionAuto" ตาม Code ที่ให้มานั้น ไม่ทำงานครับ
ผมสงสัยว่า หรือว่าจริงๆแล้ว "AutoTimer1, 2 และ 3" นั้นไม่ทำงานกันแน่

ผมจึงลองกำหนด "AutoTimer1, 2 และ 3" ให้เป็น Macro ในปุ่ม "Auto REC" แทน
ซึ่ง Macro มันก็ทำงานตามที่กำหนดไว้สมบูรณ์

ดังนั้น ปัญหาเดียวที่เหลือ คือ การเลือก Condition ของ IF เพื่อที่จะไปเรียกแต่ล่ะ Sub ให้ทำงานน่ะครับ

รบกวนช่วยชี้แนะอีกนิดนึงนะครับ ใกล้จะ work แล้วครับ
ขอขอบคุณ คุณ snasui อย่างสุดซึ้งครับ ^^

Re: ตั้งเวลาใน VBA ให้รัน Marco เป็น 4 ช่วง แต่ไม่อยากให้มันตรวจสอบเวลาตลอดได้ไหมครับ

Posted: Sun Jul 02, 2017 4:03 am
by bpond
ผมมานอนคิดดู หรือว่าจะเกี่ยวกับ Time format ที่มันไม่ตรงกัน ระหว่าง Format ของ Time system ของ Windows ที่เราใช้ กับ Time format ที่เราระบุไว้เป็นเงื่อนไข จะใช่แบบนี้หรือเปล่าครับ

ถ้าเป็นเพราะเหตุนี้ จะมีวิธีไหนไหมครับ ที่เราสั่งให้ VBA เรียก aTime = Now() แล้วบังคับให้แปลงเป็น Format แบบ 24 Hr (23:59:59) เลยน่ะครับ

ขอบคุณครับ ^^

Re: ตั้งเวลาใน VBA ให้รัน Marco เป็น 4 ช่วง แต่ไม่อยากให้มันตรวจสอบเวลาตลอดได้ไหมครับ

Posted: Sun Jul 02, 2017 5:02 am
by bpond
ดูเหมือนปัญหาเรื่อง Time format จะแก้ได้แล้วนะครับ

โดยใช้ Code แบบนี้น่ะครับ

Code: Select all

aTime = FORMAT(Now(), "HH:mm:ss")
ผมลองรันแล้ว ดูเหมือนจะใช้ได้นะครับ
เดี๋ยวผมตืนพรุ่งนี้ แล้วจะลองทดสอบดูดีๆอีกทีครับ ^^*

Re: ตั้งเวลาใน VBA ให้รัน Marco เป็น 4 ช่วง แต่ไม่อยากให้มันตรวจสอบเวลาตลอดได้ไหมครับ

Posted: Sun Jul 02, 2017 6:48 am
by snasui
:o การกำหนดค่าตัวแปร aTime = Now() ตัวแปร aTime จะไม่ใช่เฉพาะเวลาครับ

Now() คือวันที่และเวลา หากจะเอาเฉพาะเวลาอย่างเดียวจะใช้ Time ครับ

หรือจะใช้ Formt ตามที่โพสต์มาด้านบน :roll: เข้ามาช่วยก็ได้เช่นกันครับ

Re: ตั้งเวลาใน VBA ให้รัน Marco เป็น 4 ช่วง แต่ไม่อยากให้มันตรวจสอบเวลาตลอดได้ไหมครับ

Posted: Sun Jul 02, 2017 8:52 am
by bpond
แจ้งผลการทดสอบไฟล์ครับ :')

ไฟล์ทำงานได้ตรงตามที่กำหนด และสมบูรณ์ครับ

ผมไม่ได้เปลี่ยน Now() เป็น Time() นะครับ
เพราะกลัวว่าพอเอา Code นี้ ไปใส่ในไฟล์ที่ใช้งานจริงจะต้องไล่เปลี่ยนทั้งหมด

ขอขอบคุณ คุณ snasui สำหรับคำแนะนำนะครับ ^^
ด้วยความเคารพครับ

*ป.ล. ด้านล่าง คือ ตัวอย่าง Code และไฟล์ ที่ใช้งานได้สมบูรณ์
เผื่อว่าพอจะประโยชน์บ้าง ไม่มาก ก็น้อย

Code: Select all

Option Explicit
Public dTime As Date
Public aTime As Date
Public bTime As Date
Public OpenT1 As Date
Public OpenT2 As Date
Public BreakT As Date
Public CloseT As Date

Sub ValueStore()
Dim NC As Long

With Sheets("VolCalculation")
    NC = .Cells(2, .Columns.Count).End(xlToLeft).Column + 1
    .Cells(2, NC).Resize(2).Value = .Range("C2:C3").Value
    If NC > 30 Then .Range("D2:D3").Delete xlShiftToLeft
End With

Application.CutCopyMode = False
Call StartTimer

End Sub

Sub StartTimer()
Dim t As String
    
With Sheets("VolCalculation")
    t = Format(.Range("G8").Value, "00")
    t = t & ":" & Format(.Range("H8").Value, "00")
    t = t & ":" & Format(.Range("I8").Value, "00")
End With

    dTime = Now + TimeValue(t)
    Application.OnTime dTime, "ValueStore", Schedule:=True
    
End Sub

Sub StopTimer()

    On Error Resume Next
    Application.OnTime dTime, "ValueStore", Schedule:=False
    
End Sub

Sub ResetTimer()

With Sheets("VolCalculation")
    .Range("D2:XFD3").ClearContents
End With
    
End Sub

Sub AutoOn()

    Call StartTimer
    
End Sub

Sub AutoOff()
 
    Call StopTimer
    
End Sub

Sub ConditionAuto()
    aTime = Format(Now(), "HH:mm:ss")
    OpenT1 = Format(TimeValue("08:20:00"), "HH:mm:ss")
    BreakT = Format(TimeValue("08:22:00"), "HH:mm:ss")
    OpenT2 = Format(TimeValue("08:35:00"), "HH:mm:ss")
    CloseT = Format(TimeValue("08:36:00"), "HH:mm:ss")
    
    If aTime >= OpenT1 And aTime <= BreakT Then
    Call AutoTimer1
    ElseIf aTime > BreakT And aTime < OpenT2 Then
    Call AutoTimer2
    ElseIf aTime >= OpenT2 And aTime <= CloseT Then
    Call AutoTimer3
    Else
    Call AutoTimer0
    End If
    
End Sub

Sub AutoTimer0()

    OpenT1 = Format(TimeValue("08:20:00"), "HH:mm:ss")
    BreakT = Format(TimeValue("08:22:00"), "HH:mm:ss")
    OpenT2 = Format(TimeValue("08:35:00"), "HH:mm:ss")
    CloseT = Format(TimeValue("08:36:00"), "HH:mm:ss")
    
    Application.OnTime OpenT1, "AutoOn", Schedule:=True
    On Error Resume Next
    Application.OnTime OpenT1 + TimeValue("00:00:01"), "AutoOn", Schedule:=False
    Application.OnTime BreakT, "AutoOff"
    Application.OnTime OpenT2, "AutoOn", Schedule:=True
    On Error Resume Next
    Application.OnTime OpenT2 + TimeValue("00:00:01"), "AutoOn", Schedule:=False
    Application.OnTime CloseT, "AutoOff"
    
End Sub

Sub AutoTimer1()
    aTime = Now()
    bTime = Now + TimeValue("00:00:01")

    BreakT = Format(TimeValue("08:22:00"), "HH:mm:ss")
    OpenT2 = Format(TimeValue("08:35:00"), "HH:mm:ss")
    CloseT = Format(TimeValue("08:36:00"), "HH:mm:ss")
    
    Application.OnTime aTime, "AutoOn", Schedule:=True
    On Error Resume Next
    Application.OnTime bTime, "AutoOn", Schedule:=False
    Application.OnTime BreakT, "AutoOff"
    Application.OnTime OpenT2, "AutoOn", Schedule:=True
    On Error Resume Next
    Application.OnTime OpenT2 + TimeValue("00:00:01"), "AutoOn", Schedule:=False
    Application.OnTime CloseT, "AutoOff"
    
End Sub

Sub AutoTimer2()

    OpenT2 = Format(TimeValue("08:35:00"), "HH:mm:ss")
    CloseT = Format(TimeValue("08:36:00"), "HH:mm:ss")
    
    Application.OnTime OpenT2, "AutoOn", Schedule:=True
    On Error Resume Next
    Application.OnTime OpenT2 + TimeValue("00:00:01"), "AutoOn", Schedule:=False
    Application.OnTime CloseT, "AutoOff"

End Sub

Sub AutoTimer3()

    aTime = Now()
    bTime = Now + TimeValue("00:00:01")

    CloseT = Format(TimeValue("08:36:00"), "HH:mm:ss")
    
    Application.OnTime aTime, "AutoOn", Schedule:=True
    On Error Resume Next
    Application.OnTime bTime, "AutoOn", Schedule:=False
    Application.OnTime CloseT, "AutoOff"

End Sub