Suivi, temps passé sur un classeur

Salut à tous !

J'ai une nouvelle fois besoin de votre aide.

J'aimerai pouvoir suivre le temps passé sur un classeur entre l'ouverture et la fermeture.

L'objectif est d'obtenir une durée en heure et minute. Je veux ensuite insérer cette durée dans une cellule afin que l'utilisateur renseigne la/les tâche(s) effectuée(s) durant ce laps de temps.

Je suis partie sur une macro de ce type :

---------------------------------------------------

Private Sub Workbook_Open()

Sheets("Temps").Range("A1") = Now()

Sheets("SYNTHESE").Activate

End Sub

Private Sub Workbook_Close()

Dim T_deb As String

T_deb = Sheets("Temps").Range("A1").Value

Dim temps As String

temps = Now() - Tdeb

Sheets("Temps").Range("A2") = temps

Sheets("Temps").Range("A1") = ""

End Sub

Le résultat obtenu est pas du tout satisfaisant autant vous dire que sa me renvoie la date de dans 6 jours. ^^

Je souhaiteriez que vous m'aidiez sur la syntaxe afin d'aboutir au bon résultat. Quel fonction utiliser ? Timer ? Time ? Et comment appliquer un format ? Si cela me donne le nombre d'heure en chiffre cela serait parfait.

Merci d'avance !

Bonjour,

D'abord les données date et heure sont des données de type Date, ne sont pas des données String, elles sont numériques, et vouloir calculer une différence avec du texte n'est pas la meilleure idée qui soit...

Ensuite il n'y a pas d'évènement Close du classeur, mais un évènement BeforeClose. La déclaration de procédure est donc inadéquate. Et apportant des modifications, il convient d'enregistrer le classeur à la suite.

Enfin, il est mieux de déclarer toutes ses variables et pas seulement la moitié, et en évitant le type String. Pour ma part, je laisse le plus souvent les variables destinées à accueillir des données date-heure en type Variant qui ne déclenchera pas d'erreur si un texte non reconnu comme Date lui parvient, qui permettra le cas échéant de convertir une donnée date-heure en type Long (date) ou Single (heure)...

Private Sub Workbook_BeforeClose(Cancel As Boolean)
    Dim T_deb, T_fin, T
    With Worksheets("Temps")
        T_fin = Now
        T_deb = .Range("A1")
        T = T_fin - T_deb
        With .Range("A2")
            .Value = T
            .NumberFormat = "h:mm"
        End With
    End With
    ThisWorkbook.Save
End Sub

Il reste que le résultat ne sera pas très abouti : il n'est pas prévu d'incrémentation pour les jours suivants, et il y aurait intérêt à conserver les données brutes date-heure début et date-heure fin au lieu de seulement la durée !

Nota : mettre le format "[h]:mm" si les sessions sont susceptibles de dépasser 24 heures...

Cordialement.

Ah merci, beaucoup ! Surtout pour les explications, j'utilise String (j'adore ça) depuis que j'ai commencé le VBA sa à toujours fonctionner jusque là ^^. Mais c'est vrai que je devrais commencer à m'intéresser au type de variable.

Tes préconisations sont très pertinentes ! et je n'étais qu'au début de ma macro, j'allez la compléter.

Je vais essayer ça et je te dit. Encore merci l'ami !

Re,

Alors la macro fonctionné parfaitement, jusqu'à ce que j'y mette mon grain de sel. ^^ !

Alors voilà, pour simplifier la chose je t'ai fait des capture d'écran qui seront plus parlante qu'une explication.

Avant exécution :

temps

Après exécution :

temps2

J'ai pas trop compris pourquoi sa m'a rentré les valeurs dans ces cellules là ^^.

Merci d'avance.

nn ne correspond à rien.

Et les formats de cellule doivent être affectés dans la langue de VBA : "dd/mm/yy" (si c'est jj/mm/aa (jour/mois/année) que tu veux)

J'ai réussi à rentrer les valeurs au bons endroits, mais j'aimerais maintenant poser une condition et je bloque. J'ai essayé de l'introduire à tout les endroits de la macro, sans succès ^^.

C'est l'instruction qui est au début, si le classeur n'a pas été ouvert plus de 5 minutes pas besoin d'exécuter cette macro.

Y'a t'il quelqu'un pour m'aider sur cette dernière étape SVP ?

Merci d'avance.

---------------------------------------------------------------------------------------------------

Private Sub Workbook_BeforeClose(Cancel As Boolean)

If T > 0.0034722222 Then

Dim tach As String

tach = InputBox("Renseignez la/les tâches réalisé(es)", "Fermeture de la fiche")

Rows("4:4").Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove

Dim T_deb, T_fin, T

With Worksheets("Temps")

T_fin = Now()

T_deb = .Range("A2")

T = T_fin - T_deb

With .Range("B4")

.Value = T

.NumberFormat = "h:mm"

End With

With .Range("C4")

.Value = T_deb

.NumberFormat = "h:mm"

End With

With .Range("D4")

.Value = T_fin

.NumberFormat = "h:mm"

End With

With .Range("E4")

.Value = Now()

.NumberFormat = "dd/mm/yy"

End With

End With

Sheets("Temps").Range("A2") = ""

Sheets("Temps").Range("A4") = tach

ThisWorkbook.Save

End Sub

RÉSOLU ! :

Private Sub Workbook_Open()

Sheets("Temps").Range("B1").Value = Now()

Sheets("SYNTHESE").Activate

End Sub

Private Sub Workbook_BeforeClose(Cancel As Boolean)

Dim T_deb, T_fin, T

With Worksheets("Temps")

T_fin = Now()

T_deb = .Range("B1")

T = T_fin - T_deb

End With

If T > 0.0034722222 Then

Dim tach As String

tach = InputBox("Renseignez la/les tâches réalisé(es)", "Fermeture de la fiche")

Rows("4:4").Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove

With Worksheets("Temps")

With .Range("B4")

.Value = T

.NumberFormat = "h:mm"

End With

With .Range("C4")

.Value = T_deb

.NumberFormat = "h:mm"

End With

With .Range("D4")

.Value = T_fin

.NumberFormat = "h:mm"

End With

With .Range("E4")

.Value = Now()

.NumberFormat = "dd/mm/yy"

End With

End With

Sheets("Temps").Range("A2") = ""

Sheets("Temps").Range("A4") = tach

ThisWorkbook.Save

Else

MsgBox ("Sa fait pas 5 minutes")

End If

End Sub

Dans un module Standard : déclarer une variable publique et mettre la procédure suivante :

Public noTemps As Boolean

Sub Temporisation()
    noTemps = False
End Sub

Dans Workbook_Open, ajouter ces deux lignes :

...
    noTemps = True
    Application.OnTime Now + TimeValue("00:05:00"), "Temporisation"

Dans Workbook_BeforeClose, ajouter au début (après les déclarations) :

...
    If noTemps Then Exit Sub
...

NB- Il est souhaitable :

1) que tu apprennes à utiliser les balises Code et les utilises dans tes posts, le code sera plus lisible et conservera l'indentation,

2) que tu respectes les bonnes pratiques en programmation VBA, et les conventions en font partie : Déclarer ses variables (toutes autant que possibles, en tête de procédure, avant tout code exécutable (les déclarations ne sont pas du code exécutable, elles servent à ce que VBA réserve l'espace mémoire nécessaire où il stockera le contenu de la variable, et il est préférable que ces opérations soient réalisées globalement au lancement de la macro).

Cordialement.

Re,

Merci pour tes conseils ! Je m'intéresserai au bonne pratique dés que possible.

En fait, je crée une application dans le cadre de mon mémoire, j'ai pas eu le temps de m'y intéresser de manière approfondie.

Mais je suis persuadé que c'est important, car c'est vrai que parfois je m'y retrouve plus dans mes macros.

En tout cas, .

Public signifie que la variable est utilisable dans l'ensemble des macros ?

Bonjour,

Pour y voir plus clair : les mots clés Public et Private permettent de définir la portée des procédures et des variables.

Dans VBA, toutes les procédures sont publiques par défaut, donc si on doit utiliser Private pour la rendre privée on n'a jamais besoin d'utiliser Public pour une procédure.

A l'inverse les variables sont privées par défaut, on remplace donc Dim par Public pour rendre la variable publique sinon on laisse Dim.

Il faut tenir compte aussi que les modules peuvent être privés ou public : les modules Standard sont publics, on peut les rendre privés en plaçant en tête de module la déclaration : Option Private Module.

Les modules d'objets (classeur, feuilles, Userforms) sont privés.

Une procédure publique peut être appelée de n'importe où dans le projet.

Si elle est dans un module Standard, son nom suffit : MaProc lancera la procédure de ce nom.

Si elle est dans un module privé, par exemple le module de Feuil1, elle sera lancée par l'instruction : Feuil1.MaProc.

(Note que Feuil1 n'est pas ici le nom de l'onglet, mais le nom de code de la feuille, que tu pourras voir dans l'éditeur VBA.)

Si elle est privée (déclarée avec le mot-clé Private) : Private Sub MaProc... ou Private Function MaFonction..., elle ne peut être appelée qu'à partir du module ou elle se trouve.

Un cas particulier est constitué par les procédures dites évènementielles dans les modules d'objets : ces procédures sont privées par définition, liées à l'objet concerné et destinée à se lancer automatiquement lorsque l'évènement correspondant à la déclaration de procédure (indiqué par son nom, qu'on évite de taper soi-même en laissant VBA le faire...). Ôter le mot-clé Private ne changerait rien...

C'est la même situation pour les variables : une variable publique est accessible à partir de tout le projet, une variable privée seulement à partir du module où elle est déclarée. Une variable publique déclarée dans un module privé restera accessible dans tout le projet sous la forme NomModule.NomVariable.

En ce qui concerne les variables déclarées et utilisées dans les procédures, elles n'ont d'existence que durant l'exécution de la procédure. Celle-ci achevée, elle disparaissent de la mémoire.

Un cas particulier, les variables de niveau Procédure déclarées avec le mot-clé Static : leur valeur est conservée en mémoire entre deux appels de la procédure...

Cordialement.

Rechercher des sujets similaires à "suivi temps passe classeur"