EXCEL - Savoir qui a modifié une cellule

Résolu
Galileo75 Messages postés 6 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
A voir également:

14 réponses

Mike-31 Messages postés 19571 Statut Contributeur 5 136
 
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)
1
Mike-31 Messages postés 19571 Statut Contributeur 5 136
 
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)
1
Galileo75 Messages postés 6 Statut Membre
 
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 !
0
tompols Messages postés 1325 Statut Contributeur 435
 
Bonjour
As-tu regardé du coté de la fonctionnalité fournie par Excel "Suivi des modifications" ?
0

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

Posez votre question
Mike-31 Messages postés 19571 Statut Contributeur 5 136
 
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)
0
Galileo75 Messages postés 6 Statut Membre
 
@ 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
0
tompols Messages postés 1325 Statut Contributeur 435
 
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
0
Galileo75 Messages postés 6 Statut Membre
 
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
0
jerome173 Messages postés 1 Statut Membre
 
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
0
tompols Messages postés 1325 Statut Contributeur 435
 
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é)
0
Galileo75 Messages postés 6 Statut Membre
 
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
0
tompols Messages postés 1325 Statut Contributeur 435
 
Re,
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 
0
dianet68
 
stp me dire pas à pas comment faire ça,car je ne sais pas programmer excel,mais j,ai besoin de ça comme de l'air.
merci beaucoup pour ton tepms. excel 2003
0
Galileo75 Messages postés 6 Statut Membre
 
Vi je confirme que ça marche : merci +++ !

Galileo
0
dianet68
 
Stp me dire pas à pas comment faire ça,car je ne sais pas programmer excel,mais j,ai besoin de ça comme de l'air.
merci beaucoup pour ton tepms. excel 2003
0
Mike-31 Messages postés 19571 Statut Contributeur 5 136
 
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)
0
tompols Messages postés 1325 Statut Contributeur 435
 
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 :
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à... :)
0