A necessidade é um fato e pouca documentação há sobre isso. De fato as linguagens de programação mais usadas gozam facilmente de um método Sleep, que facilmente pausa a execução do código por algum momento.
No VBA isso não é tão intuitivo, mas existem algumas alternativas para fazê-lo.
Método 1: Usar um loop For… Next vazio
Uma desvantagem para este método é que não existe como determinar a quantidade exata de tempo que o programa leva para executar o executar um loop. A quantidade de tempo depende da velocidade do seu computador. O seguinte código executa um loop que faz nada, mas segura o processamento por algum tempo.
1 2 3 4 | Sub MyDelayMacro For iCount = 1 to 1000 Next iCount End Sub |
Método 2: Usar uma chamada API para suspender a execução
Utilizar um chamar API para suspender a execução por uma quantidade fixa de tempo.
O kernel32 contém uma função que pausa execução um programa do para uma quantidade especificada de tempo em milissegundos. Para que você possa usar a função, ele deve primeiro ser declarado na seção General Declarations do módulo no qual será usado:
1 2 | Declare Sub Sleep Lib "kernel32" Alias "Sleep" _ (ByVal dwMilliseconds As Long) |
Use a seguinte sintaxe para chamar a função Sleep :
1 2 3 | Sub Sleep() Sleep 1000 'Faz o código esperar por 1 segundo End Sub |
Método 3: Usar o método OnTime
Use o método OnTime para definir uma quantidade de tempo a pausa. O método OnTime usa a seguinte sintaxe:
Por requerer nome de uma macro para o argumento nome executar, você deve criar duas macros: a primeira macro para conter o chamar método OnTime e outros comandos relevantes para sua macro, e a segunda macro para executar quando o tempo alocado tiver passado. A segunda macro pode ser uma macro “fantasma” que não fará nada além de chamar o método OnTime para fazer o agendameto..
Este exemplo executa o macro nomeado ” MyDelayMacro ” 15 segundos desde o tempo é o exemplo executar.
1 2 3 4 5 6 7 8 | Sub MyMainMacro() ' Pausa por 15 segundos. Application.OnTime Now + TimeValue("00:00:15"), "MyDelayMacro" End Sub Public Sub MyDelayMacro() ' Macro executada sob o agendamento. MsgBox "Esta macro foi executada após 15 segundos." End Sub |
Método 4: Usar o método Application.Wait
Trabalha da mesma similar ao Sleep, porém é preciso “montar” um objeto TimeValue a ser passado com parâmetro, e o código esperará até o tempo definido neste para executar, simulando um comportamente de “esperar até”, ao contrário do Sleep que tem um comportamento “esperar por X tempo”
1 2 3 4 5 6 7 | Sub MyWaitMacro() newHour = Hour(Now()) newMinute = Minute(Now()) newSecond = Second(Now()) + 3 waitTime = TimeSerial(newHour, newMinute, newSecond) Application.Wait waitTime End Sub |
Para obter mais informações sobre como usar o método OnTime, leia este artigo: https://www.tomasvasquez.com.br/blog/microsoft-office/vba-agendando-a-execucao-de-macros-com-a-funcao-ontime
Bom proveito!
Me ajuda, não consigo utilizar o Application.ontime dentro do userform. O problema é que ele funciona, mas não chama a sub que eu peço.
Eu preciso é que a rotina espere um tempo e execute uma sub.
Pode me ajudar ?
Bruno,
Onde está a rotina que quer chamar? Dentro do código do Form? Em um módulo? Se for isso, ela está declarada como Public? Ela é uma Sub?
Abraços
Tomás
Oi Tomás,
Estou desenvolvendo uma macro que navega entre páginas de um website. Será que vc saberia como faço para que um determinado trecho de código seja executado apenas depois que uma determinada página for carregada? Não posso usar nenhuma das opções acima por serem muito estáticas, e o carregamento de uma página no browser varia de acordo com diversos parâmetros (velocidade conexão, processador, e outros).
Agradeço se puder ajudar.
Adriana,
É possível saber através do VBA trabalhando com o objeto Internet Explorer se a página já foi carregada completamente. Dê uma olhada neste post e veja se resta alguma dúvida:
https://www.tomasvasquez.com.br/blog/microsoft-office/vba-interagindo-com-o-objeto-internet-explorer
Abraços
Tomás
Oi,
Desculpe, pois eu realmente não conheco muita coisa de vba e preciso disso para finalizar um projeto.
Dei uma olhada no post que você sugeriu, mas não entendi o que seria o READYSTATE_COMPLETE, pois ao depurar, percebi que não possuia valor, travando a minha aplicação, e pesquisando na internet algumas pessoas atribuem o valor 4, e dessa maneira a aplicação não aguarda o carregamento completo da página.
Você pode me esclarecer esta dúvida?
Agradeço.
Estou tentando utilizar o Application.ontime porem indica que eu não possuo ele,
Public Sub IniciarTeste()
Alarme = Now TimeSerial(0, 0, IntervaloSegundos)
Application.OnTime EarliestTime:=Alarme, procedure:=”Macro1″, schedule:=True
Application
End Sub
Public Sub Macro1()
‘As suas rotinas
MsgBox “Olá!!! voltarei pelas ” & Format(Alarme, “hh:mm:ss”), _
vbInformation, “Timer em Vba”
Call IniciarTeste
End Sub
Public Sub PararTeste()
On Error Resume Next
Application.OnTime EarliestTime:=Alarme, _
procedure:=”Macro1″, _
schedule:=False
End Sub
Esta tudo declarado dentro de um formulário, isto esta correto?
Tenho que declarar em outro lugar ou algo assim?
Por que ele indica pra mim que não tenho o OnTime no meu projeto?
Att
Thomas
Thomas,
É preciso entender o que quer realmente fazer. No seu código, aparentemente há uma referência circular e isso deve ser tratado.
Respondendo a algumas perguntas:
Esta tudo declarado dentro de um formulário, isto esta correto?
O OnTime funcionará da mesma forma. Porém, é uma “boa prática” deixar funções em Módulos separados
Tenho que declarar em outro lugar ou algo assim?
Respondido acima
Por que ele indica pra mim que não tenho o OnTime no meu projeto?
Provável que haja algum erro no código. A função OnTime é nativa do VBA quando acesso pela maioria das aplicações do Office.
Abraços
Tomás
Thomas,
Acabei de publicar um artigo que explica como funciona o método OnTime. Dê uma olhada:
https://www.tomasvasquez.com.br/blog/microsoft-office/vba-agendando-a-execucao-de-macros-com-a-funcao-ontime
Abraços
Tomás
Bom dia Tomas,
Estou fazendo um cronometro , e preciso que ele seja regressivo e que tbm receba os valores em minutos que eu determinar, mais não consegui fazer pois entendo pouco de VBA, porém tenho esse código que montei:
Private Sub Resetar_Click()
dteStopped = 0
dteStart = 0
dteElapsed = 0
Label1 = “00:00:00”
boolResetPressed = True
End Sub
Private Sub iniciar_Click()
Start_timer:
dteStart = Time
boolStopPressed = False
boolResetPressed = False
Timer_Loop:
DoEvents
dteFinish = Time
dteElapsed = dteFinish – dteStart + dteStopped
If Not boolStopPressed = True Then
Label1 = dteElapsed
If boolResetPressed = True Then GoTo Start_timer
GoTo Timer_Loop
Else
Exit Sub
End If
End Sub
Private Sub parar_Click()
boolStopPressed = True
dteStopped = dteElapsed
End Sub
Private Sub btnReset_Click()
dteStopped = 0
dteStart = 0
dteElapsed = 0
Label1 = “00:00:00”
boolResetPressed = True
End Sub
Private Sub btnStart_Click()
Start_timer:
dteStart = Time
boolStopPressed = False
boolResetPressed = False
Timer_Loop:
DoEvents
dteFinish = Time
dteElapsed = dteFinish – dteStart + dteStopped
If Not boolStopPressed = True Then
Label1 = dteElapsed
If boolResetPressed = True Then GoTo Start_timer
GoTo Timer_Loop
Else
Exit Sub
End If
End Sub
Private Sub btnStop_Click()
boolStopPressed = True
dteStopped = dteElapsed
End Sub
gostaria de sua ajuda para deixa-lo da forma que preciso. recebendo valores em minutos e regredindo até zerar, e se possível qnd chegar a 00:00 ele alarme e apareça uma msg na tela.
DESDE JÁ, OBRIGADO, abraços
Colega,
Não tem lugar melhor para falarmos sobre isso:
http://www.tomasvasquez.com.br/forum
Nos vemos lá!
Tomás
Tomás, gostaria de implementar atraso em meu código que é direcionado a preencher dados em um WEBSite, atualmente uso a função Sleep o que faz ele dormir por alguns segundos até a pagina ser totalmente carregada. Tentei utilizar as 3 rotinas abaixo sem exito pois a pagina carrega alguns “TextBox” depois de carregada e a função Sleep não esta ajudando na produtividade de meu trabalho, Consegue me conceder esta ajuda? pensei em fazer um loop no textBox se ele estiver visível mas sem exito tbm. Grato pela atenção!
Do While ie.Busy
Loop
””””””””””””’
Do Until ie.Document.ReadyState = “complete”
Loop
””””””””””””’
Do Until ie.ReadyState = READYSTATE_COMPLETE
Loop