EXCEL - Savoir qui a modifié une cellule
Résolu
Galileo75
Messages postés
6
Statut
Membre
-
jerome173 Messages postés 1 Statut Membre -
jerome173 Messages postés 1 Statut Membre -
Bonjour,
Très très grand débutant en programmation sous excel, je dois dans le cadre de mon travail créer un tableau permettant de lister un nombre important de contacts. Mis en ligne sur un disque dur partagé en réseau, il aura vocation à être complété et/ou corrigé par plusieurs personnes. Aussi, afin de permettre un suivi des modifications effectuées, j’ai besoin qu’apparaissent dans des cellules à côté du titre les éléments suivants :
• la date de la dernière modification (pas dernière ouverture)
• le nom de la personne qui a fait cette modification
Le premier problème je l’ai résolu en errant sur les forums où j’ai trouvé la formule =SI(NBVAL(B33:P939)>0;datation();"") que j’ai collée dans la cellule qui m’intéressait après avoir télécharger une macro qui s’appelle « datation » : ça marche parfaitement, merci +++ à celui qui l’a créé.
Je n’ai en revanche pas trouvé de solution au second problème, à savoir faire en sorte que dès qu’une modification est faite dans un tableau (B33:P939 en l’occurrence), le nom de la personne ayant fait en dernier la ou les modification(s) s’inscrive automatiquement dans une cellule de mon choix.
J’ai vaguement tâtonné avec la commande « Application.UserName », mais sans succès pour le moment…
Quelqu’un aurait-il une solution, idéalement sous la forme d’une macro que je pourrais copier/coller dans mon VBA sous Excel ?
Avec tous mes remerciements d’avance !
Galileo
PS : j'utilise Excel 2003 au bureau
Très très grand débutant en programmation sous excel, je dois dans le cadre de mon travail créer un tableau permettant de lister un nombre important de contacts. Mis en ligne sur un disque dur partagé en réseau, il aura vocation à être complété et/ou corrigé par plusieurs personnes. Aussi, afin de permettre un suivi des modifications effectuées, j’ai besoin qu’apparaissent dans des cellules à côté du titre les éléments suivants :
• la date de la dernière modification (pas dernière ouverture)
• le nom de la personne qui a fait cette modification
Le premier problème je l’ai résolu en errant sur les forums où j’ai trouvé la formule =SI(NBVAL(B33:P939)>0;datation();"") que j’ai collée dans la cellule qui m’intéressait après avoir télécharger une macro qui s’appelle « datation » : ça marche parfaitement, merci +++ à celui qui l’a créé.
Je n’ai en revanche pas trouvé de solution au second problème, à savoir faire en sorte que dès qu’une modification est faite dans un tableau (B33:P939 en l’occurrence), le nom de la personne ayant fait en dernier la ou les modification(s) s’inscrive automatiquement dans une cellule de mon choix.
J’ai vaguement tâtonné avec la commande « Application.UserName », mais sans succès pour le moment…
Quelqu’un aurait-il une solution, idéalement sous la forme d’une macro que je pourrais copier/coller dans mon VBA sous Excel ?
Avec tous mes remerciements d’avance !
Galileo
PS : j'utilise Excel 2003 au bureau
A voir également:
- Excel savoir qui a modifié une cellule
- Excel cellule couleur si condition texte - Guide
- Liste déroulante excel - Guide
- Proteger cellule excel - Guide
- Aller à la ligne dans une cellule excel - Guide
- Déplacer une colonne excel - Guide
14 réponses
Salut,
Colles ce code dans les propriétés de ta feuille,
Private Sub Worksheet_Change(ByVal Target As Range)
Dim Contrôle As String
Do
If Not (Target.Column > 1 And Target.Column < 17) Then Exit Sub
Contrôle = InputBox("Veuillez vous identifier", _
"Accès réglementé", "Votre Nom") ' Valeur de la variable.
If Contrôle = "Votre Nom" Or Contrôle = "" Then
MsgBox "Erreur de saisie !"
MyValue = MsgBox("Souhaitez-vous renoncer à la modification ?", _
vbYesNo + vbCritical + vbDefaultButton1, "Votre Décision")
If MyValue = vbYes Then
ThisWorkbook.Saved = True
ActiveWorkbook.Close
End If
Else
Range("A1000").End(xlUp).Select
ActiveCell.Offset(1, 0).Select
ActiveCell.FormulaR1C1 = "Fichier modifié par " & Contrôle & " Le " & Now
ActiveWorkbook.Save
End If
Loop Until Contrôle <> "" And Contrôle <> "Votre Nom"
End Sub
Avec ce lien un petit exemple de fichier, colonne A les noms de personnes apportant une motif de la colonne B à la colonne P est archivé
https://www.cjoint.com/?ikwjgs2EaI
A+
Mike-31
Un problème sans solution est un problème mal posé (Einstein)
Colles ce code dans les propriétés de ta feuille,
Private Sub Worksheet_Change(ByVal Target As Range)
Dim Contrôle As String
Do
If Not (Target.Column > 1 And Target.Column < 17) Then Exit Sub
Contrôle = InputBox("Veuillez vous identifier", _
"Accès réglementé", "Votre Nom") ' Valeur de la variable.
If Contrôle = "Votre Nom" Or Contrôle = "" Then
MsgBox "Erreur de saisie !"
MyValue = MsgBox("Souhaitez-vous renoncer à la modification ?", _
vbYesNo + vbCritical + vbDefaultButton1, "Votre Décision")
If MyValue = vbYes Then
ThisWorkbook.Saved = True
ActiveWorkbook.Close
End If
Else
Range("A1000").End(xlUp).Select
ActiveCell.Offset(1, 0).Select
ActiveCell.FormulaR1C1 = "Fichier modifié par " & Contrôle & " Le " & Now
ActiveWorkbook.Save
End If
Loop Until Contrôle <> "" And Contrôle <> "Votre Nom"
End Sub
Avec ce lien un petit exemple de fichier, colonne A les noms de personnes apportant une motif de la colonne B à la colonne P est archivé
https://www.cjoint.com/?ikwjgs2EaI
A+
Mike-31
Un problème sans solution est un problème mal posé (Einstein)
Salut Tompols,
Ca fait plaisir de voir qu’une discussion développe autant d’intérêt et comme les demandes se raréfient en périodes de vacances profitons en pour échanger quelques mots.
Si j’ai bien tout compris Galileo souhaitait enregistrer la date et l’heure en D4, et le Nom en F4 de la personne qui effectuait la modif.
Avec ce code, pour lancer automatiquement la macro avec une plage Nommée Zone_1 ou Range(("C6:F17") ou encore [C6:F17] je n’ai pas inclus la liste des noms en B
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect([Zone_1], Target) Is Nothing Then
UserForm1.Show
End If
End Sub
Une petite Userform avec un combobox qui permet de sélectionner le nom de la personne issue de la liste en B, et de coller le tout en bonne place
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
[D4] = Now
[F4] = ComboBox1
ActiveWorkbook.Save
End Sub
Toutes ces explications serviront également à dianet68 qui s’est invité dans la discussion.
Bonne soirée à toi et à la prochaine sur le forum
Cordialement
A+
Mike-31
Un problème sans solution est un problème mal posé (Einstein)
Ca fait plaisir de voir qu’une discussion développe autant d’intérêt et comme les demandes se raréfient en périodes de vacances profitons en pour échanger quelques mots.
Si j’ai bien tout compris Galileo souhaitait enregistrer la date et l’heure en D4, et le Nom en F4 de la personne qui effectuait la modif.
Avec ce code, pour lancer automatiquement la macro avec une plage Nommée Zone_1 ou Range(("C6:F17") ou encore [C6:F17] je n’ai pas inclus la liste des noms en B
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect([Zone_1], Target) Is Nothing Then
UserForm1.Show
End If
End Sub
Une petite Userform avec un combobox qui permet de sélectionner le nom de la personne issue de la liste en B, et de coller le tout en bonne place
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
[D4] = Now
[F4] = ComboBox1
ActiveWorkbook.Save
End Sub
Toutes ces explications serviront également à dianet68 qui s’est invité dans la discussion.
Bonne soirée à toi et à la prochaine sur le forum
Cordialement
A+
Mike-31
Un problème sans solution est un problème mal posé (Einstein)
Salut Mike,
Tout d'abord merci beaucoup pour le temps que tu bien voulu prendre pour me répondre.
J'ai testé ton code sur le lien que tu proposes : il a l'avantage de permettre de garder un historique détaillé, mais a l'inconvénient très lourd d'obliger l'utilisateur à taper lui-même son nom pour chaque modification qu'il fait dans chaque cellule. Donc si 10 modifications, tu dois taper dix fois ton nom (où ce que tu veux d'ailleurs...).
Idéalement il faudrait que le nom de la personne faisant la ou les modifs s'inscrive automatiquement à partir du nom d'utilisateur du logiciel Excel ou de Windows sans recquérir d'action supplémentaire de sa part.
Je mets ci-dessous un exemple type du tableau que je suis en train d'essayer de construire avec la macro datation, pour illustrer plus précisément ce dont j'ai besoin.
https://www.cjoint.com/?ill70ILAK6
Galileo
PS : je garde ton code ceci dit, bien que ne répondant pas à mon besoin actuel, il me servira pour d'autres fichiers de travail !
Tout d'abord merci beaucoup pour le temps que tu bien voulu prendre pour me répondre.
J'ai testé ton code sur le lien que tu proposes : il a l'avantage de permettre de garder un historique détaillé, mais a l'inconvénient très lourd d'obliger l'utilisateur à taper lui-même son nom pour chaque modification qu'il fait dans chaque cellule. Donc si 10 modifications, tu dois taper dix fois ton nom (où ce que tu veux d'ailleurs...).
Idéalement il faudrait que le nom de la personne faisant la ou les modifs s'inscrive automatiquement à partir du nom d'utilisateur du logiciel Excel ou de Windows sans recquérir d'action supplémentaire de sa part.
Je mets ci-dessous un exemple type du tableau que je suis en train d'essayer de construire avec la macro datation, pour illustrer plus précisément ce dont j'ai besoin.
https://www.cjoint.com/?ill70ILAK6
Galileo
PS : je garde ton code ceci dit, bien que ne répondant pas à mon besoin actuel, il me servira pour d'autres fichiers de travail !
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Salut,
Tu peux donner plus de détails sur le fonctionnement de ton tableau, exemple colonne B as tu tous les tous noms déjà saisis !
Ensuite la personne qui intervient, est elle celle qui figure en B sur la même ligne, il faut une logique pour afficher automatiquement le nom en F4
A+
Mike-31
Un problème sans solution est un problème mal posé (Einstein)
Tu peux donner plus de détails sur le fonctionnement de ton tableau, exemple colonne B as tu tous les tous noms déjà saisis !
Ensuite la personne qui intervient, est elle celle qui figure en B sur la même ligne, il faut une logique pour afficher automatiquement le nom en F4
A+
Mike-31
Un problème sans solution est un problème mal posé (Einstein)
@ Tompols
Oui mais c'est là aussi trop lourd, car cela implique la création de commentaires dans chaque cellule modifiée, qui doivent ensuite être validés un à un : je souhaiterais juste voir le nom de la dernière personne ayant fait une modif apparaître dans une cellule de mon choix (F4 dans le tableau que j'ai mis en exemple).
@ Mike
Le but du tableau que je dois construire pour mon travail est de recenser les coordonnées de +/- 900 personnes pour mener une action de relations extérieures efficace. Le tableau contient donc déjà leur noms (colonne B dans mon exemple) avec à côté leur titre, fonction, institution d'appartenance, adresse, email, téléphone, etc. Or les informations de ces contacts sont régulièrement appelées à changer (changement d'affectation, etc.) donc ce fichier devra être mis à jour dès que nous aurons connaissance d'un tel changement.
Comme il rasssemble en un seul document les contacts d'une soixantaine de personnes de mon entreprise, plusieurs de nos salariés pourront y accéder pour le modifier et le mettre à jour, car eux seuls sauront si leur interlocuteur habituel a changé. D'où l'importance de pouvoir savoir qui a fait la dernière modif et quand.
Pour le dire autrement en reprenant mon tableau "Exemple", il faudrait que toute modification du contenu d'une cellule comprise dans le champ entre B6 et F17 entraine automatiquement la mise à jour de la cellule D4 (date et heure du dernier changement, ce qui fonctionne déjà) et de la cellule F4 (nom d'utilisateur de la personne ayant fait ce changement, c'est ça qui me manque encore à ce jour).
Peut-être d'ailleurs que cette fonctionnalité est impossible à mettre en place, bien que j'imagine qu'en construisant une macro ça doit être faisable car il existe une commande pour faire apparaître le nom d'utilisateur d'Excel (Application.UserName), et que la "surveillance" du contenu des cellules est possible puisque la macro de datation (D4 dans mon exemple) existe et fonctionne... Mes compétences en programmation m'empêchent malheureusement de faire la synthèse des deux pour obtenir la macro dont j'ai besoin...
Merci sincérement à tous les deux pour votre aide.
Galileo
Oui mais c'est là aussi trop lourd, car cela implique la création de commentaires dans chaque cellule modifiée, qui doivent ensuite être validés un à un : je souhaiterais juste voir le nom de la dernière personne ayant fait une modif apparaître dans une cellule de mon choix (F4 dans le tableau que j'ai mis en exemple).
@ Mike
Le but du tableau que je dois construire pour mon travail est de recenser les coordonnées de +/- 900 personnes pour mener une action de relations extérieures efficace. Le tableau contient donc déjà leur noms (colonne B dans mon exemple) avec à côté leur titre, fonction, institution d'appartenance, adresse, email, téléphone, etc. Or les informations de ces contacts sont régulièrement appelées à changer (changement d'affectation, etc.) donc ce fichier devra être mis à jour dès que nous aurons connaissance d'un tel changement.
Comme il rasssemble en un seul document les contacts d'une soixantaine de personnes de mon entreprise, plusieurs de nos salariés pourront y accéder pour le modifier et le mettre à jour, car eux seuls sauront si leur interlocuteur habituel a changé. D'où l'importance de pouvoir savoir qui a fait la dernière modif et quand.
Pour le dire autrement en reprenant mon tableau "Exemple", il faudrait que toute modification du contenu d'une cellule comprise dans le champ entre B6 et F17 entraine automatiquement la mise à jour de la cellule D4 (date et heure du dernier changement, ce qui fonctionne déjà) et de la cellule F4 (nom d'utilisateur de la personne ayant fait ce changement, c'est ça qui me manque encore à ce jour).
Peut-être d'ailleurs que cette fonctionnalité est impossible à mettre en place, bien que j'imagine qu'en construisant une macro ça doit être faisable car il existe une commande pour faire apparaître le nom d'utilisateur d'Excel (Application.UserName), et que la "surveillance" du contenu des cellules est possible puisque la macro de datation (D4 dans mon exemple) existe et fonctionne... Mes compétences en programmation m'empêchent malheureusement de faire la synthèse des deux pour obtenir la macro dont j'ai besoin...
Merci sincérement à tous les deux pour votre aide.
Galileo
Oki,
Alors le code pour récuperer le username windows (je laisse Mike adapter son modèle ;) ):
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colComputer = objWMIService.ExecQuery _
("Select * from Win32_ComputerSystem")
For Each objComputer in colComputer
msgbox "Logged-on user: " & objComputer.UserName
Next
Alors le code pour récuperer le username windows (je laisse Mike adapter son modèle ;) ):
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colComputer = objWMIService.ExecQuery _
("Select * from Win32_ComputerSystem")
For Each objComputer in colComputer
msgbox "Logged-on user: " & objComputer.UserName
Next
Je clos moi-même ce topic : après deux nouvelles heures d'errance sur les fofos divers, j'ai enfin trouvé la solution ! (https://forums.commentcamarche.net/forum/affich-6641748-excel-extraire-un-nom-depuis-un-login
Pour ce que ça pourrait intéresser, la procédure est la suivante :
1- Ajouter un module dans VBA avec :
Function login() As String
login = Application.UserName
End Function
2- Entrer dans la cellule de votre choix dans votre tableau la formule suivante :
=SI(NBVAL(B33:P939)>0;login();"")
où "B33:P939" correspond à la zone que vous souhaitez "surveiller".
Merci +++ à nouveau à Mike et Tompols pour leur aide !
Galileo
Pour ce que ça pourrait intéresser, la procédure est la suivante :
1- Ajouter un module dans VBA avec :
Function login() As String
login = Application.UserName
End Function
2- Entrer dans la cellule de votre choix dans votre tableau la formule suivante :
=SI(NBVAL(B33:P939)>0;login();"")
où "B33:P939" correspond à la zone que vous souhaitez "surveiller".
Merci +++ à nouveau à Mike et Tompols pour leur aide !
Galileo
Bonjour, je viens de tester ce code dans un tableau. Tout fonctionne bien jusqu'au moment où utilise les filtres de selection. A ce Moment là, tout les champs devant contenir le nom des utilisateurs prennent le nom de l'utilisateur qui a utiliser les filtres.
Une idée pour contrer cela ?
En te remerciant d'avance
Une idée pour contrer cela ?
En te remerciant d'avance
Attention Galileo,
Si j'ai mis le code pour récuperer le username windows, ce n'est pas pour rien, le Application.UserName excel est celui que tu renseignes à l'installation/premiere utilisation (peux également etre modifié via les options...:s)....à bannir à mon avis....Tu n'as qu'à tester mais on trouve souvent le nom de la société ou des initiales etc (ds mon cas j'ai mis Tom comme j'aurai pu mettre Jo ou Bobby, le username windows est souvent lui bien mieux geré)
Si j'ai mis le code pour récuperer le username windows, ce n'est pas pour rien, le Application.UserName excel est celui que tu renseignes à l'installation/premiere utilisation (peux également etre modifié via les options...:s)....à bannir à mon avis....Tu n'as qu'à tester mais on trouve souvent le nom de la société ou des initiales etc (ds mon cas j'ai mis Tom comme j'aurai pu mettre Jo ou Bobby, le username windows est souvent lui bien mieux geré)
Hmm ok, je vais adapter ma macro pour remplacer le application.username par celui du windows, bien que chez nous le pack office soit configuré par le service informatique et que nos noms d'utilisateur d'excel soient donc bien paramétrés...
Merci à nouveau donc :)
Galileo
Merci à nouveau donc :)
Galileo
Re,
Ta fonction donnerai donc
Ta fonction donnerai donc
Function login() As String strComputer = "." Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") Set colComputer = objWMIService.ExecQuery _ ("Select * from Win32_ComputerSystem") For Each objComputer in colComputer login = objComputer.UserName Next End Function
Salut dianet68,
Cette discussion est terminée, tu aurais dû en ouvrir une autre.
Pour le résultat attendu par Galileo75, on aurai pu également écrire
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect([Zone_1], Target) Is Nothing Then
UserForm1.Show
End If
End Sub
exemple sur ce lien
https://www.cjoint.com/?imrLkfziUu
A+
Mike-31
Un problème sans solution est un problème mal posé (Einstein)
Cette discussion est terminée, tu aurais dû en ouvrir une autre.
Pour le résultat attendu par Galileo75, on aurai pu également écrire
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect([Zone_1], Target) Is Nothing Then
UserForm1.Show
End If
End Sub
exemple sur ce lien
https://www.cjoint.com/?imrLkfziUu
A+
Mike-31
Un problème sans solution est un problème mal posé (Einstein)
Re,
Bon alors voilà comment j'aurais fat ds l'exmple de Galileo("il faudrait que toute modification du contenu d'une cellule comprise dans le champ entre B6 et F17 entraine automatiquement la mise à jour de la cellule D4") :
dans le code de la feuille :
Et ds un module la fonction login()
voilà... :)
Bon alors voilà comment j'aurais fat ds l'exmple de Galileo("il faudrait que toute modification du contenu d'une cellule comprise dans le champ entre B6 et F17 entraine automatiquement la mise à jour de la cellule D4") :
dans le code de la feuille :
Private Sub Worksheet_Change(ByVal Target As Range) Dim user As String If Not Intersect(Range("B6:F17"), Target) Is Nothing Then user = login() ActiveSheet.Range("D4").Value = "Derniere modification le " & Now() & " par " & user End If End Sub
Et ds un module la fonction login()
Function login() As String strComputer = "." Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") Set colComputer = objWMIService.ExecQuery ("Select * from Win32_ComputerSystem") For Each objComputer in colComputer login = objComputer.UserName Next End Function
voilà... :)