समय की विशिष्ट राशि के लिए कैसे रोकें? (एक्सेल / VBA)


103

मेरे पास एक एक्सेल वर्कशीट है जिसमें निम्नलिखित मैक्रो है। मैं इसे हर पल लूप करना चाहता हूं, लेकिन अगर मुझे ऐसा करने के लिए फंक्शन मिल सकता है। क्या यह संभव नहीं है?

Sub Macro1()
'
' Macro1 Macro
'
Do
    Calculate
    'Here I want to wait for one second

Loop
End Sub

जवाबों:


129

प्रतीक्षा विधि का उपयोग करें :

Application.Wait Now + #0:00:01#

या (एक्सेल 2010 और बाद के लिए):

Application.Wait Now + #12:00:01 AM#

मुझे यकीन नहीं है कि आप इसका क्या मतलब है, लेकिन मुझे लगता है कि आप DoEventsयहाँ डेमो के रूप में चाहते हैं dailydoseofexcel.com/archives/2005/06/14/stopwatch
रयान शैनन

3
@Benoit और @Keng, आप टेक्स्ट को तारीख में बदलने से बचते हुए सीधे 1 सेकंड लगा सकते हैं। मेरे लिए अधिक साफ है: Application.Wait(Now + #0:00:01#)चीयर्स!
A.Sommerh

29
यह प्रारूप Excel 2010 में काम नहीं कर रहा था। यह काम करता है:Application.Wait (Now + TimeValue("0:00:01"))
ZX9

1
DateAdd ("s", 1, Now) सही काम करता है। और किसी भी लंबे समय तक सेकंड के लिए सामान्यीकृत किया जा सकता है: DateAdd ("s", nSec, Now) समय शाब्दिक का उपयोग किए बिना। 1 सेकंड से कम सोने के लिए कर्नेल 32 में स्लीप एपीआई का उपयोग करें
एंड्रयू डेनिसन

1
@ ZX9 टाइमवेल्यू ("00:00:01") = 0.0000115740 ... तो Application.wait (अब + 0.00001) एक सेकंड के बारे में है। मुझे Application.wait(now + 1e-5)एक सेकंड के लिए, Application.wait(now + 0.5e-5)आधे सेकंड के लिए उपयोग करना पसंद है
Some_Guy

61

इसे अपने मॉड्यूल में जोड़ें

Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

या, 64-बिट सिस्टम उपयोग के लिए:

Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)

इसे अपने मैक्रो में कॉल करें जैसे:

Sub Macro1()
'
' Macro1 Macro
'
Do
    Calculate
    Sleep (1000) ' delay 1 second

Loop
End Sub

1
कर्नेल32.dll का उपयोग करने के बजाय ऐसा करने के लिए VBA विधि का उपयोग क्यों नहीं किया?
बेन एस

10
मैंने इस पद्धति का उपयोग किया है क्योंकि यह एक्सेस जैसे विभिन्न कार्यालय उत्पादों के बीच पोर्टेबल है और एक्सेल विशिष्ट नहीं है।
बुग्गाबिल

एक और वीबीए एप्लिकेशन (ईआरएस) भी है जो मैं उपयोग करता हूं जिसमें भाषा का बहुत सीमित उपसमूह है।
बुग्गाबिल 13

18
+1, क्योंकि Sleep()आप 1 सेकंड से कम का प्रतीक्षा समय निर्दिष्ट करते हैं। Application.Waitकभी-कभी बहुत दानेदार होता है।
ब्रैडेक

2
@JulianKnight:Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)
वेगार्ड

42

के बजाय का उपयोग करने का:

Application.Wait(Now + #0:00:01#)

मैं पसंद करता हूं:

Application.Wait(Now + TimeValue("00:00:01"))

क्योंकि बाद में पढ़ना बहुत आसान है।


7
और यह काम करता है, जबकि कार्यालय 2013 में, # 0: 0: 1 # प्रारूप मध्यरात्रि के बाद 1 सेकंड में परिवर्तित हो जाता है।
जूलियन नाइट

1
चेतावनी: 'Application.Wait' का उपयोग करने वाले सभी समाधानों में 1 सेकंड की खराबी है। यह विधि उन मिलीसेकंडों पर विचार नहीं करती है जो पहले से ही चालू सेकंड के बाद से शुरू हो गए हैं ... उदाहरण के लिए, यदि समय सेकंड बदलने तक केवल 1 मिलिसेकंड बचा है, तो आप केवल 1 मिलिसेकंड के लिए सोएंगे। आप केवल 1 सेकंड की प्रतीक्षा करने के बजाय 2 गोल संख्याओं की तुलना कर रहे हैं!
साइबरपोन्क

18

यह मेरे लिए निर्दोष रूप से काम करता है। "जब तक" लूप से पहले या बाद में कोई भी कोड डालें। अपने मामले में, अपने अंत छोर के अंदर 5 लाइनों (time1 = & time2 = & "अंत तक" लूप) डालें "

sub whatever()
Dim time1, time2

time1 = Now
time2 = Now + TimeValue("0:00:01")
    Do Until time1 >= time2
        DoEvents
        time1 = Now()
    Loop

End sub

2
मुझे यह समाधान सबसे अधिक पसंद है क्योंकि मैं संदेश कतार को रोकना नहीं चाहता था।
डैनियल फुच्स

यह समाधान सटीक है और नींद-एपीआई-फ़ंक्शन की घोषणा की आवश्यकता नहीं है। मैं एक ही परिणाम के साथ डबल मानों में समय स्टोर करता था और माइक्रोसेकंड का उपयोग करता था।
DrMarbuse

यह समाधान उस उपयोग से नीचे के समान समाधानों की तुलना में बेहतर काम करता है Timerक्योंकि Timerदृष्टिकोण आधी रात से पहले विफल हो जाता है।
vknowles

1
यह समाधान सटीक नहीं है, यह उस मिलीसेकंड को ध्यान में नहीं रखता है जो पहले से ही वर्तमान समय से समाप्त हो गया है ... उदाहरण के लिए, यदि अब सेकंड बदलने तक केवल 1 मिलिसेकंड बचा है, तो आप केवल 1 मिलिसेकंड के लिए सोएंगे।
साइबरपोंक

जब अन्य समाधान एक गैर-एमएस कार्यालय आधारित VBA मैक्रो के लिए एक लंबा समय ले रहे थे, तो यह पूरी तरह से काम करता था - धन्यवाद!
जिज्ञासु

12

कर्नेल 32.dll में स्लीप की घोषणा 64-बिट एक्सेल में काम नहीं करेगी। यह थोड़ा और सामान्य होगा:

#If VBA7 Then
    Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#Else
    Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If

2
Office 2013 में संकलित करने में विफल रहता है। Office 2013 के लिए VBA में त्रुटि चेकर कंपाइलर कथनों को अनदेखा करता है।
जूलियन नाइट

2
मेरे लिए कार्यालय 2013 में संकलन ठीक है।
जॉन पेल्टियर

ज्यादातर लोग इस बात से सहमत हैं कि Win64 / VBA7 dwMilliseconds Long है, LongPtr नहीं। एक्सेल VBA बाहरी कॉल के बाद स्टैक करेक्शन करके इस तरह की त्रुटियों को छिपाता है, लेकिन इस तरह की त्रुटियां ओपन ऑफिस के अधिकांश संस्करणों को क्रैश कर देंगी
david

6

क्लीमो के कोड का केवल एक साफ किया गया संस्करण - एक्सेस में काम करता है, जिसमें Application.Wait फ़ंक्शन नहीं है।

Public Sub Pause(sngSecs As Single)
    Dim sngEnd As Single
    sngEnd = Timer + sngSecs
    While Timer < sngEnd
        DoEvents
    Wend
End Sub

Public Sub TestPause()
    Pause 1
    MsgBox "done"
End Sub

2
यदि Timerआधी रात के बाद से सेकंड की संख्या देता है, तो यह दृष्टिकोण विफल हो जाता है यदि इसे आधी रात से पहले निष्पादित किया जाता है (यानी, ऐसा है sngEnd= = 86,400)। आधी रात को, Timer0 पर रीसेट करता है और इस तरह sngEndहमेशा के लिए कम रहता है।
vknowles

PS ऊपर @ अंक से कोड दिन के किसी भी समय काम करता है।
vknowles

@vknowles, आपने जो कहा वो बिल्कुल सच है। और नीचे विधि में भी मुआवजा दिया जा सकता है। चूंकि यह विधि मिलीसेकंड संभालती है, मुझे लगता है कि यह एक सुरक्षित शर्त है। `` `सार्वजनिक उप नींद (sngSecs के रूप में एकल) मंद sngEnd के रूप में एकल sngEnd = टाइमर + (sngSecs / 1000) जबकि टाइमर <sngEnd DoEvents हैं (sngEnd - टाइमर)> 50000 तब sngEnd = sngEnd - 86400 समाप्ति तो बीतना End Sub` ` `
प्रवीणदास

5

प्रस्तुत समाधानों में से अधिकांश Application.Wait का उपयोग करते हैं, जो कि समय (मील के सेकंड) को ध्यान में नहीं रखता है क्योंकि पहले से ही दूसरी गणना शुरू होने के बाद से समाप्त हो गया है, इसलिए उनके पास 1 सेकंड तक का आंतरिक इंप्रेशन है

टाइमर दृष्टिकोण सबसे अच्छा समाधान है , लेकिन आपको आधी रात को रीसेट को ध्यान में रखना होगा, इसलिए यहां टाइमर के लिए एक बहुत ही सटीक नींद विधि है:

'You can use integer (1 for 1 second) or single (1.5 for 1 and a half second)
Public Sub Sleep(vSeconds As Variant)
    Dim t0 As Single, t1 As Single
    t0 = Timer
    Do
        t1 = Timer
        If t1 < t0 Then t1 = t1 + 86400 'Timer overflows at midnight
        DoEvents    'optional, to avoid excel freeze while sleeping
    Loop Until t1 - t0 >= vSeconds
End Sub

किसी भी समारोह का परीक्षण करने के लिए इस का उपयोग करें: (खुली डिबग तत्काल विंडो: CTRL + G)

Sub testSleep()
    t0 = Timer
    Debug.Print "Time before sleep:"; t0   'Timer format is in seconds since midnight

    Sleep (1.5)

    Debug.Print "Time after sleep:"; Timer
    Debug.Print "Slept for:"; Timer - t0; "seconds"

End Sub

3

Application.Wait Second(Now) + 1


चेतावनी: 'Application.Wait' का उपयोग करने वाले सभी समाधानों में 1 सेकंड की खराबी है। यह विधि उन मिलीसेकंडों पर विचार नहीं करती है जो पहले से ही चालू सेकंड के बाद से शुरू हो गए हैं ... उदाहरण के लिए, यदि समय सेकंड बदलने तक केवल 1 मिलिसेकंड बचा है, तो आप केवल 1 मिलिसेकंड के लिए सोएंगे। आप केवल 1 सेकंड की प्रतीक्षा करने के बजाय 2 गोल संख्याओं की तुलना कर रहे हैं!
साइबरपोंक

2
Function Delay(ByVal T As Integer)
    'Function can be used to introduce a delay of up to 99 seconds
    'Call Function ex:  Delay 2 {introduces a 2 second delay before execution of code resumes}
        strT = Mid((100 + T), 2, 2)
            strSecsDelay = "00:00:" & strT
    Application.Wait (Now + TimeValue(strSecsDelay))
End Function

1
चेतावनी: 'Application.Wait' का उपयोग करने वाले सभी समाधानों में 1 सेकंड की खराबी है। यह विधि उन मिलीसेकंडों पर विचार नहीं करती है जो पहले से ही चालू सेकंड के बाद से शुरू हो गए हैं ... उदाहरण के लिए, यदि समय सेकंड बदलने तक केवल 1 मिलिसेकंड बचा है, तो आप केवल 1 मिलिसेकंड के लिए सोएंगे। आप केवल 1 सेकंड की प्रतीक्षा करने के बजाय 2 गोल संख्याओं की तुलना कर रहे हैं!
साइबरपॉन्क

2

यहाँ सोने का विकल्प है:

Sub TDelay(delay As Long)
Dim n As Long
For n = 1 To delay
DoEvents
Next n
End Sub

निम्नलिखित कोड में मैं एक "ग्लो" इफ़ेक्ट ब्लिंक को स्पिन बटन पर लगाता हूँ ताकि उपयोगकर्ताओं को यह निर्देशित किया जा सके कि अगर उन्हें "परेशानी" हो रही है, तो लूप में "स्लीप 1000" का उपयोग करने से कोई दृश्यमान ब्लिंकिंग नहीं हुई, लेकिन लूप बढ़िया काम कर रहा है।

Sub SpinFocus()
Dim i As Long
For i = 1 To 3   '3 blinks
Worksheets(2).Shapes("SpinGlow").ZOrder (msoBringToFront)
TDelay (10000)   'this makes the glow stay lit longer than not, looks nice.
Worksheets(2).Shapes("SpinGlow").ZOrder (msoSendBackward)
TDelay (100)
Next i
End Sub

1

मैंने इस समस्या का जवाब देने के लिए यह किया था:

Sub goTIMER(NumOfSeconds As Long) 'in (seconds) as:  call gotimer (1)  'seconds
  Application.Wait now + NumOfSeconds / 86400#
  'Application.Wait (Now + TimeValue("0:00:05"))  'other
  Application.EnableEvents = True       'EVENTS
End Sub

चेतावनी: 'Application.Wait' का उपयोग करने वाले सभी समाधानों में 1 सेकंड की खराबी है। यह विधि उन मिलीसेकंडों पर विचार नहीं करती है जो पहले से ही चालू सेकंड के बाद से शुरू हो गए हैं ... उदाहरण के लिए, यदि समय सेकंड बदलने तक केवल 1 मिलिसेकंड बचा है, तो आप केवल 1 मिलिसेकंड के लिए सोएंगे। आप केवल 1 सेकंड की प्रतीक्षा करने के बजाय 2 गोल संख्याओं की तुलना कर रहे हैं!
साइबरपॉन्क

1

मैं आमतौर पर अनुप्रयोग को रोकने के लिए टाइमर फ़ंक्शन का उपयोग करता हूं । इस कोड को आप डालें

T0 = Timer
Do
    Delay = Timer - T0
Loop Until Delay >= 1 'Change this value to pause time for a certain amount of seconds

3
यदि Timerआधी रात के बाद से सेकंड की संख्या देता है, तो यह दृष्टिकोण विफल हो जाता है यदि इसे आधी रात से पहले निष्पादित किया जाता है (यानी, जैसे कि T0आधी रात से विलंब सेकंड की संख्या से कम है)। आधी रात को, Timerविलंब सीमा पूरी होने से पहले 0 तक रीसेट करता है। Delayदेरी की सीमा तक कभी नहीं पहुंचता है, इसलिए लूप हमेशा के लिए चलता है।
vknowles

चूंकि टाइमर गैर-पूर्णांक मानों का उत्पादन करता है, आपको उपयोग करना चाहिए Loop Until Delay >= 1, या आप 1 से अधिक होने का जोखिम उठाते हैं और कभी भी लूप से बाहर नहीं निकलते हैं।
जॉन पेल्टियर

1

प्रतीक्षा और नींद कार्य एक्सेल को बंद कर देते हैं और देरी खत्म होने तक आप कुछ और नहीं कर सकते। दूसरी ओर लूप देरी आपको प्रतीक्षा करने का सटीक समय नहीं देती है।

इसलिए, मैंने इस अवधारणा को दोनों अवधारणाओं में थोड़ा सा जोड़कर बनाया है। यह तब तक लूप करता है जब तक समय आप चाहते हैं।

Private Sub Waste10Sec()
   target = (Now + TimeValue("0:00:10"))
   Do
       DoEvents 'keeps excel running other stuff
   Loop Until Now >= target
End Sub

आपको बस Waste10Sec पर कॉल करने की आवश्यकता है जहां आपको देरी की आवश्यकता है



0

आप अब अनुप्रयोग का उपयोग कर सकते हैं। अब टाइमलाइन ("00:00:01") या एप्लिकेशन का उपयोग करें। अब + टाइमरियल (0,0,1)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.