특정 시간 동안 일시 중지하는 방법은 무엇입니까? (Excel / VBA)


103

다음 매크로가있는 Excel 워크 시트가 있습니다. 매초마다 반복하고 싶지만 그 기능을 찾을 수 있다면 위험합니다. 가능하지 않나요?

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

Loop
End Sub

답변:


129

대기 방법을 사용하십시오 .

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

또는 (Excel 2010 이상) :

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

그게 무슨 뜻인지 정확히 모르겠지만 DoEvents여기에서 데모 한 것처럼 추측합니다. dailydoseofexcel.com/archives/2005/06/14/stopwatch
Ryan Shannon

3
@Benoit 및 @Keng, 텍스트를 날짜로 변환하지 않고 1 초를 직접 입력 할 수 있습니다. 나를 위해 더 깨끗합니다 : Application.Wait(Now + #0:00:01#)건배!
A.Sommerh 2014

29
이 형식은 Excel 2010에서 작동하지 않았습니다. 그래도 작동합니다.Application.Wait (Now + TimeValue("0:00:01"))
ZX9

1
DateAdd ( "s", 1, Now)는 옳은 일을합니다. 시간 리터럴을 사용하지 않고 DateAdd ( "s", nSec, Now)와 같이 긴 초 수 동안 일반화 할 수 있습니다. 잠을 1 개 초 미만 사용 KERNEL32의 절전 API에
앤드류 데니슨

1
@ ZX9 timevalue ( "00:00:01") = 0.0000115740 ... 따라서 Application.wait (now + 0.00001)은 약 1 초입니다. 내가 사용하려면 Application.wait(now + 1e-5), 초 동안 Application.wait(now + 0.5e-5)0.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
kernel32.dll을 사용하는 대신 VBA 방법을 사용하여이 작업을 수행하지 않는 이유는 무엇입니까?
Ben S

10
이 방법은 Access와 같은 다양한 사무용 제품간에 이식이 가능하고 Excel에만 국한되지 않기 때문에 사용했습니다.
Buggabill

언어 의 매우 제한된 하위 집합을 사용하는 또 다른 VBA 응용 프로그램 (ERS)도 있습니다.
Buggabill

18
+1, Sleep()1 초 미만의 대기 시간을 지정할 수 있기 때문 입니다. Application.Wait때로는 너무 세분화되어 있습니다.
BradC

2
@JulianKnight :Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)
Vegard

42

사용하는 대신:

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

나는 선호한다:

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

나중에 읽기가 훨씬 쉽기 때문입니다.


7
Office 2013에서는 # 0 : 0 : 1 # 형식이 자정 이후 1 초로 변환되는 반면 작동합니다.
Julian Knight

1
경고 : 'Application.Wait'를 사용하는 모든 솔루션은 1 초 부정확합니다. 이 방법은 현재 초가 시작된 이후 이미 경과 한 밀리 초를 고려하지 않습니다. 예를 들어, 시간 초가 변경 될 때까지 1 밀리 초 만 남으면 1 밀리 초 동안 만 절전 모드로 전환됩니다. 1 초를 기다리지 않고 2 개의 반올림 된 숫자를 비교하고 있습니다!
cyberponk

18

이것은 나를 위해 완벽하게 작동합니다. "do until"루프 앞이나 뒤에 코드를 삽입합니다. 귀하의 경우에는 do 루프 안쪽 끝에 5 줄 (time1 = & time2 = & "do until"루프)을 넣으십시오.

sub whatever()
Dim time1, time2

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

End sub

2
이 솔루션을 가장 좋아하는 이유는 메시지 대기열을 중지하고 싶지 않았기 때문입니다.
Daniel Fuchs

이 솔루션은 정확하며 sleep-API-Function의 선언이 필요하지 않습니다. 나는 시간을 이중 값으로 저장하고 동일한 결과로 대신 마이크로 초를 사용했습니다.
DrMarbuse

이 솔루션은 자정 직전에 접근이 실패 하기 Timer때문에 아래의 유사한 솔루션보다 더 잘 작동합니다 Timer.
vknowles

1
이 솔루션은 정확하지 않으며 현재 시간에서 이미 경과 한 밀리 초를 고려하지 않습니다. 예를 들어 Now 초가 변경 될 때까지 1 밀리 초 만 남아 있으면 1 밀리 초 동안 만 절전 모드로 전환됩니다.
cyberponk 2018

MS Office 기반이 아닌 VBA 매크로에 대해 다른 솔루션이 오랜 시간이 걸렸을 때이 매크로는 완벽하게 작동했습니다. 감사합니다!
호기심

12

kernel32.dll의 Sleep 선언은 64 비트 Excel에서 작동하지 않습니다. 이것은 좀 더 일반적입니다.

#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의 오류 검사기가 컴파일러 문을 무시하는 것 같습니다.
Julian Knight

2
오피스 2013에서 나를 위해 컴파일 벌금
존 펠티어

대부분의 사람들은 Win64 / VBA7 dwMilliseconds가 LongPtr이 아니라 Long이라는 데 동의합니다. Excel VBA는 외부 호출 후 스택 수정을 수행하여 이와 같은 오류를 숨기지 만 이와 같은 오류로 인해 대부분의 Open Office 버전이 중단됩니다
david

6

클레 모 코드의 정리 된 버전-Access에서 작동하며 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> = 86400)입니다. 자정 Timer에 0으로 재설정되므로 sngEnd영원히 남지 않습니다 .
vknowles

추신 : 위의 @clemo 코드는 하루 중 언제든지 작동합니다.
vknowles

@vknowles, 당신이 말한 것은 절대적으로 사실입니다. 또한 아래 방법으로 보상 할 수 있습니다. 이 방법은 밀리 초를 처리하기 때문에 안전한 방법이라고 생각합니다. ```Public Sub Sleep (sngSecs As Single) Dim sngEnd As Single sngEnd = Timer + (sngSecs / 1000) While Timer <sngEnd DoEvents If (sngEnd-Timer)> 50000 Then sngEnd = sngEnd-86400 End If Wend End Sub`` `
PravyNandas

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 개의 반올림 된 숫자를 비교하고 있습니다!
cyberponk

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 개의 반올림 된 숫자를 비교하고 있습니다!
cyberponk

2

다음은 수면의 대안입니다.

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

다음 코드에서는 스핀 버튼에 "글로우"효과를 깜빡이게하여 사용자가 "문제가있는"경우 해당 버튼으로 안내합니다. 루프에서 "sleep 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 개의 반올림 된 숫자를 비교하고 있습니다!
cyberponk

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

Timer는 정수가 아닌 값을 생성하므로를 사용해야합니다 Loop Until Delay >= 1. 그렇지 않으면 1을 넘어서 루프를 종료하지 않을 위험이 있습니다.
Jon Peltier

1

대기 및 절전 기능은 Excel을 잠그고 지연이 완료 될 때까지 다른 작업을 수행 할 수 없습니다. 반면에 루프 지연은 기다릴 정확한 시간을 제공하지 않습니다.

그래서 저는이 두 가지 개념을 약간 결합하여이 해결 방법을 만들었습니다. 시간이 원하는 시간이 될 때까지 반복됩니다.

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

지연이 필요한 곳에 Waste10Sec에 전화하면됩니다.


0

이 시도 :

Threading.thread.sleep(1000)

0

Application.wait now + timevalue ( "00:00:01") 또는 Application.wait now + timeserial (0,0,1)을 사용할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.