doguies
Messages postés6Date d'inscriptionjeudi 11 décembre 2008StatutMembreDernière intervention17 décembre 2008
-
11 déc. 2008 à 21:17
cs_Orohena
Messages postés577Date d'inscriptionvendredi 26 septembre 2008StatutMembreDernière intervention20 novembre 2010
-
18 déc. 2008 à 01:21
Bonjour,
Débutant en VBA, je coince sur un problème au niveau d’un compte à rebours présent dans un userform.
Tout marche correctement si je laisse tourner le compte à rebours. En revanche, si je l’interromps en fermant le fichier, ce dernier n’arrête pas de s’ouvrir. J’ai pourtant essayé de bloquer la procédure en mettant un code dans « thisworkbook ».
Voici l’ensemble de mes codes :
<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" /??>
Dans un module
Dim mDate As Date ' Memo date de fin compte à rebour
Sub LanceCompteur()
UserForm3.Show False
mDate = Now + TimeSerial(0, 0, 30)
MajCompteur
End Sub
Sub MajCompteur() ' Procedure mise à jout compteur
Dim dRestant As Date
If mDate > 0 Then
dRestant = mDate - Now
If dRestant > 0 Then
lheure = Now + TimeValue("00:00:01")
Application.OnTime lheure, "MajCompteur" ' Auto-Rappel dans 1s pour Mise à jour
Else
MsgBox "Fin Compte à rebours"
mDate = 0
End If
UserForm3.Label1 = Format(dRestant, "hh:mm:ss")
End If
End Sub
Dans Thisworkbook
Private Sub Workbook_Open()
LanceCompteur
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
cs_Orohena
Messages postés577Date d'inscriptionvendredi 26 septembre 2008StatutMembreDernière intervention20 novembre 20104 16 déc. 2008 à 20:50
Bonjour
Chose promise...
Colle le code suivant un nouveau classeur, sauvegarde et ouvre-le.
Si tu le laisses ouvert 30 secondes, il t'affichera "Compte à rebours terminé". Si tu le fermes avant, le classeur ne se rouvrira pas.
Le code s'inspirant très fortement du tien, tu n'auras pas de mal à mettre au point ton programme.
<hr />
Dans ThisWorkbook
Option Explicit
Private Sub Workbook_Open()
decompte = 30 ' fixe le nombre de secondes du compte à rebours
majcompteur ' lance le compte a rebours
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
On Error Resume Next
Application.OnTime earliesttime:=quand, _
procedure:=quoi, schedule:=False ' annule la programmation en cours
End Sub
<hr />
Dans un module
Option Explicit
Public decompte As Integer ' compteur des secondes
' Il est important de bien respecter le type des deux declarations ci-dessous
' sans tenir compte de ce qui est écrit dans la doc en ligne de VBA / Excel,
' pour éviter toute réouverture intempestive du classeur
Public quand As Double ' premier parametre pour OnTime
Public Const quoi = "majCompteur" ' deuxieme parametre pour OnTime
'
Sub majcompteur()
decompte = decompte - 1 ' décrémente le compteur
If decompte >= 0 Then ' compteur non expiré ?
quand = Now + TimeValue("00:00:01") ' heure de programmation du prochain OnTime
Application.OnTime earliesttime:=quand, _
procedure:=quoi, schedule:=True ' programmation du prochain OnTime
Else
MsgBox "Compte à rebours terminé" ' affiche une boîte de dialogue quand le C-A-R est terminé
End If
End Sub
<hr />Amicalement
cs_Orohena
Messages postés577Date d'inscriptionvendredi 26 septembre 2008StatutMembreDernière intervention20 novembre 20104 12 déc. 2008 à 02:01
Bonjour Steph
Ton code n'est pas en cause. Excel ignore ta demande d'arrêt et rouvre donc le classeur si l'application Excel est encore active. C'est un problème (bug ?) identifié au niveau du type des paramètres de la méthode OnTime.
doguies
Messages postés6Date d'inscriptionjeudi 11 décembre 2008StatutMembreDernière intervention17 décembre 2008 12 déc. 2008 à 21:43
Bonjour Orohena,
Tout d'abord merci pour ta réponse.
Par contre, j'ai essayé et cela ne marche toujours pas.
Aurais tu une autre idée ? Y a-t-il un autre moyen que le "ontime" pour afficher un userform actif avec un compte à rebours ?
cs_Orohena
Messages postés577Date d'inscriptionvendredi 26 septembre 2008StatutMembreDernière intervention20 novembre 20104 12 déc. 2008 à 22:42
Bonjour doguies
Pour un traitement récursif comme le compte à rebours, j'utilise toujours OnTime.
Est-ce que ton application Excel doit faire d'autres tâches pendant le compte à rebours, ou simplement attendre ? auquel cas il y a une autre solution.
Amicalement
Vous n’avez pas trouvé la réponse que vous recherchez ?
cs_Orohena
Messages postés577Date d'inscriptionvendredi 26 septembre 2008StatutMembreDernière intervention20 novembre 20104 12 déc. 2008 à 23:04
J'ai voulu vérifier la syntaxe avant de t'exposer la solution.
La solution, c'est de suspendre Excel par Application.Wait
Par exemple, Application.Wait (Now + TimeValue("00:00:01")
Contrairement à OnTime, Wait suspend Excel. C'est donc une bonne solution si ton application ne doit rien faire pendant le compte à rebours, d'autant qu'elle ne consomme pas de temps machine.
cs_Orohena
Messages postés577Date d'inscriptionvendredi 26 septembre 2008StatutMembreDernière intervention20 novembre 20104 14 déc. 2008 à 23:34
Bonjour Steph
Il faut donc utiliser OnTime. Cette méthode fonctionne, à condition de respecter les types que je t'ai indiqués : Double pour le paramètre earliesttime, et Const pour le paramètre procedure.
Je ne peux bien sûr pas te dire pourquoi cela ne fonctionne pas chez toi. Peut-être me suis-je mal expliqué. Plutôt que me répéter, je te propose de te baser sur mon code Big Ben dans une feuille de calcul. Sinon, tu peux faire comme moi, et chercher sur google dans les forums de développeurs VB ango-saxons, puisque c'est là que j'ai trouvé la solution.
Si ça ne donne rien, fais-le moi savoir, je t'écrirai un petite appli de démo. A la louche, ça doit nécessiter une trentaine de lignes.
En tout cas, ton code est " nickel ", c'est à dire conforme à la documentation. Sauf que dans ce cas précis, il ne faut pas la suivre...
doguies
Messages postés6Date d'inscriptionjeudi 11 décembre 2008StatutMembreDernière intervention17 décembre 2008 15 déc. 2008 à 21:51
Bonjour Philippe,
Je suis désolé car j'ai vraiment l'impression d'abuser de ton temps.
En fait, j'imagine que ton message est clair pour quelqu'un qui maîtrise les procédures VBA. Malheureusement ce n'est pas mon cas car j'apprends petit à petit en regardant les forums mais sans jamais avoir eu la moindre formation. J'ai donc du mal à comprendre ce que tu m'indiques ou en tout où il faut placer tes instructions.Serait il possible que tu me détailles tes commentaires à l'intérieur du code que j'avais mentionné initialement ?
Merci encore.
cs_Orohena
Messages postés577Date d'inscriptionvendredi 26 septembre 2008StatutMembreDernière intervention20 novembre 20104 18 déc. 2008 à 01:21
Bonjour doguies
Super, ça fait toujours plaisir quand on trouve la solution.
Tu devrais faire "Réponse acceptée" sur mon dernier message, car cette question est assez souvent soulevée.
Option Explicit : cette option génère une erreur si tu utilises une variable non déclarée. Prenons l'exemple suivant :
Dim maVariable As String
maVarable = "Hello World"
Dans la 2e ligne, j'ai par erreur tapé maVarable au lieu de maVariable. Mon programme ne va pas fonctionner comme je le souhaite, puisque maVariable est vide, alors que je voulais qu'elle contienne "Hello World".
Grâce à Option Explicit, le compilateur va détecter que la variable maVarable n'a pas été déclarée, et donc générer une erreur "Variable non définie" sur la ligne 2.
Public veut dire que la variable ou la constante qui suit est "visible" depuis tous les modules du projet. comme decompte, quand et quoi sont déclarés dans un module utilisateur, mais sont utilisés par le module ThisWorkbook, je les ai mis en Public.
A l'inverse, si tu as des variables, constantes, etc que tu utilises dans un module spécifique (et uniquement dans ce module) tu as intérêt à les déclarer Private.
Perso, je n'utilise plus Dim en dehors des procédures Function et Sub.
Perso, je fais très attention à mettre Option Explicit, Public Private et Dim aux bons endroits, ça élimine pas mal de risques.
Pour en savoir plus, utilise l'aide sur Visual Basic : menu "?" dans la fenêtre Visual Basic Editor.