VBA Excel: Comptes à rebours imbriqués avec arrêt auto

Résolu/Fermé
Aude - 9 oct. 2014 à 08:13
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 - 14 oct. 2014 à 09:32
Bonjour,

Je suis sous Excel 2007 et j"aimerais pouvoir me programmer un compte à rebours pour mes séances de sport, qui tiendrait compte de la durée de l'exercice, du temps de récupération et du nombre de séries.
Ces 3 données seraient à saisir dans une fenêtre, puis, à l'enclenchement du programme, le compte à rebours de l'exercice démarrerait. Une fois terminé, un bip sonnerait pour annoncer la fin de l'exercice et le début de la récupération dont le décompte se lancerait automatiquement, puis un nouveau bip et rebelotte pour l'exercice... et ce, autant de fois que de séries saisies.
J'ai commencé à faire des essais, pour l'instant non concluants: http://cjoint.com/?0Jjip7oFdRe
Quelqu'un pourrait-il m'aider??

Merci beaucoup!
A voir également:

5 réponses

pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 2 751
Modifié par pijaku le 14/10/2014 à 09:34
Bonjour,

Voici deux fichiers (les mêmes) avec résolution du dernier bug :
https://www.cjoint.com/c/DJojLZ0g5rT => format .xlsm
https://www.cjoint.com/c/DJnikKBciRs => format .xls

tu dis...

EDIT : changement du fichier .xlsm

🎼 Cordialement,
Franck 🎶
3
Bonjour Pijaku,

C'est avec grand plaisir que je viens de prendre connaissance de tes messages! Je viens de tester les fichiers et le .xls me convient parfaitement!! Le .xlsm fonctionne aussi très bien mais j'ai une préférence pour les boutons "à l'ancienne" du .xls.

Merci encore pour ton investissement!!
0
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 2 751
14 oct. 2014 à 09:32
Salut,

Tu as bien fait, d'autant plus que le .xlsm est une mauvaise version bourrée de bugs...... Je la change de suite.

De rien et @++
0
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 2 751
9 oct. 2014 à 12:30
Salut Aude,

Mes tentatives avec Application.OnTime n'ont pas été concluantes. On arrive à un pseudo résultat ou les temps se chevauchent, avec une irrégularité du "rythme" des secondes.
Donc il a fallut compliquer un peu le bouzin.

Voici un exemple qui utilise un Timer plutôt que Application.OnTime :
https://www.cjoint.com/c/DJjmGNSi4yG

Tu m'en diras des nouvelles?
2
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 2 751
9 oct. 2014 à 12:55
Ci-joint une seconde version : https://www.cjoint.com/c/DJjm6tDGJrA

Améliorations : affichage du reste en hh:mm:ss + surprise finale
0
Salut Pijaku,

Un grand merci pour ton fichier qui tient parfaitement la route!

Penses-tu qu'il soit possible:
1. de pouvoir mettre le compte à rebours en pause?
2. d'afficher le nombre de séries restantes pour savoir où on en est en cours d'exercice?

Merci encore!
0
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 2 751
9 oct. 2014 à 13:08
Un grand merci pour ton fichier qui tient parfaitement la route!
Merci à toi.

La pause je ne penses pas.
Mais bon, je vais regarder quand même.
Pour les séries, cela ne devrait poser aucun souci, je penses...
0
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 2 751
9 oct. 2014 à 14:19
Pour la pause, c'est fait...
A tester car ça ne me semble pas hyper stable.
Pour le 2- aussi

https://www.cjoint.com/c/DJjowWoh9R3

Voili voilou
0
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 2 751
9 oct. 2014 à 16:47
Pas très stable en effet.

Il y aurait moyen d'améliorer tout ça avec l'api windows
Private Declare Function GetInputState Lib "user32" () As Long


Mais... Là je ne peux pas avant lundi.

On s'en reparle.
0
Merci, j'attends donc ton retour lundi.

Bon week-end!
0
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 2 751
10 oct. 2014 à 13:07
Salut,

Un peu en avance : Le fichier .xlsm
Les codes :
Module :
Option Explicit
Private Declare Function GetInputState Lib "user32" () As Long
Private Declare Function Beep Lib "kernel32" (ByVal Frequence As Long, ByVal Duree As Long) As Long
Private Declare Function SetTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Private Declare Function KillTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long) As Long

Dim TempsInter()
Dim NbSecondes As Long
Dim Indic As Integer
Dim Plage As Range
Dim iCounter As Integer
Dim lngTimerID As Long
Dim BlnTimer As Boolean
Dim pause As Boolean

Sub TimerProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal idEvent As Long, ByVal dwTime As Long)
Dim Reste As Long, Cel As Range

'En cas d'erreur quitte proprement le Timer
On Error GoTo Arret

'coloriage
For Each Cel In Plage
    If Cel.Address = TempsInter(2, Indic) Then Cel.Interior.ColorIndex = 3 Else Cel.Interior.ColorIndex = xlNone
Next Cel

'alimentation compteur si pas de pause
If pause = False Then iCounter = iCounter + 1
Reste = NbSecondes - iCounter
Range("J" & CInt(Split(TempsInter(2, Indic), "$")(2))) = Format((TempsInter(1, Indic) - iCounter) / 86400, "hh:mm:ss")

'FIN
If iCounter = NbSecondes Then
    pause = False
    Call Arret_Timer
    Exit Sub
End If
'BEEP et autres actions à faire
If iCounter = TempsInter(1, Indic) Then
    Call Beep(1500, 1000)
    Indic = Indic + 1
    iCounter = iCounter - 1
    If Indic Mod 2 = 0 Then Range("K" & CInt(Split(TempsInter(2, Indic), "$")(2))) = Range("K" & CInt(Split(TempsInter(2, Indic), "$")(2))) + 1
End If
Exit Sub

Arret:
pause = False
Call Arret_Timer
End Sub

'La procédure de commencement du Timer
Public Sub Lance_Timer()

'permet de déclencher le clic sur un bouton en cas de pause:
If GetInputState = 0 Then DoEvents
  
'1000 = intervalle en millisecondes => 1s
'TimerProc = nom de la procédure à relancer toutes les 1000ms
lngTimerID = SetTimer(0, 0, 1000, AddressOf TimerProc)
If lngTimerID = 0 Then
    MsgBox "Timer non créé. Fin du programme."
    Exit Sub
End If
BlnTimer = True
End Sub

'La procédure d'arrêt du Timer
Public Sub Arret_Timer()
    lngTimerID = KillTimer(0, lngTimerID)
    If lngTimerID = 0 Then
        MsgBox "Timer déjà arrêté."
        Exit Sub
    End If
    BlnTimer = False
    Plage.Interior.ColorIndex = xlNone
    Range("J5:K14").ClearContents
    Sheets("Sheet1").CommandButton3.Caption = "Pause"
    Call Beep(2500, 2500)
    MsgBox "Fini!! Ouffff......"
End Sub

'Bouton Start
Sub Lancement()
Dim Lig As Integer, Col As Integer, Cpt As Integer
Dim i As Integer

i = 1
NbSecondes = 0
iCounter = 0
pause = False
Set Plage = Range("F4:I14")
Plage.Interior.ColorIndex = xlNone
Range("J5:K14").ClearContents

ReDim Preserve TempsInter(1 To 2, 1 To i)
TempsInter(1, i) = 0
TempsInter(2, i) = "$F$4"
For Lig = 5 To 14
    If Cells(Lig, 7) = "" Then Exit For
    Cpt = Cells(Lig, 9)
    Do While Cpt > 0
        For Col = 7 To 8
            NbSecondes = NbSecondes + Hour(Cells(Lig, Col)) * 3600 + Minute(Cells(Lig, Col)) * 60 + Second(Cells(Lig, Col))
            i = i + 1
            ReDim Preserve TempsInter(1 To 2, 1 To i)
            TempsInter(1, i) = TempsInter(1, i - 1) + Hour(Cells(Lig, Col)) * 3600 + Minute(Cells(Lig, Col)) * 60 + Second(Cells(Lig, Col))
            TempsInter(2, i) = Cells(Lig, Col).Address
        Next Col
        Cpt = Cpt - 1
    Loop
Next Lig
Indic = 2
Range("K" & CInt(Split(TempsInter(2, Indic), "$")(2))) = 1
Lance_Timer
End Sub

'Bouton pause
Sub BtnPause()
    If Sheets("Sheet1").CommandButton3.Caption = "Pause" Then
        pause = True
        Sheets("Sheet1").CommandButton3.Caption = "Reprendre"
    Else
        Sheets("Sheet1").CommandButton3.Caption = "Pause"
        pause = False
    End If
End Sub


Feuille (3 boutons) :
Private Sub CommandButton1_Click()
Call Lancement
End Sub

Private Sub CommandButton2_Click()
Call Arret_Timer
End Sub

Private Sub CommandButton3_Click()
Call BtnPause
End Sub


Attention ne pas changer le nom de la feuille ni le texte du bouton pause. Sinon, adapter dans le code...

Bon sport!

A+
0
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 2 751
10 oct. 2014 à 13:19
ERRATUM : l'utilisation ici d'un Timer rend inutile l'utilisation de GetInputState.
Par conséquent,vous pouvez supprimer les trois lignes :
dans l'entête :
Private Declare Function GetInputState Lib "user32" () As Long

dans la Public Sub Lance_Timer() :
'permet de déclencher le clic sur un bouton en cas de pause:
If GetInputState = 0 Then DoEvents


Cordialement
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 2 751
10 oct. 2014 à 15:26
Après réflexion, un problème subsiste. Si tu clic deux fois sur le bouton start tu va lancer 2 Timer et tu ne pourras en arrêter qu'un seul.
Je rectifierais cela, mais, d'ici lundi, ne clic qu'une fois sur ce bouton.
Sinon il faudra attendre la fin des décomptes ou fermer Excel de manière plus "sauvage"...
0