Range.replace sur des listes non definies
Bonjour,
J'ai un onglet excel avec des listes classiques comprenant chacune n items dont les libellés sont par exemple a, b, c (3 items)
Dans des tableaux de saisie d'enregistrements, je fais appel à des listes de validation des données rappelant une de ces listes.
Les utilisateurs remplissent leurs tableaux de données au fur et à mesure en utilisant ces listes de données.
J'ai cependant un problème d'intégrité de la base au fur et à mesure du temps, car les utilisateurs changent parfois les libellés des listes pour corriger une faute d'orthographe ou en préciser le sens. Le libellé "a" devient par exemple "ax" (ou "z").
Pour les saisies futures, pas de problèmes mais pour les saisies passées, il y a pour les enregistrements précédents concernés noté en dur "a" et non pas "ax". Je voudrais donc chaque fois que je touche aux libellés de ma liste pour en modifier un, changer dans les tableaux concernés pour les enregistrements passés tous les "a" en "ax".
je sais le faire en vérifiant les conditions sur chaque cellule de chacune de mes listes prises une à une avec RANGE.REPLACE mais c'est très fastidieux donc je me disais qu'il devait exister une méthode plus intelligente.
J'espère que vous pourrez m'aider,
Bien cordialement,
Bonjour,
tu aurais pu mettre un classeur exemple qu'on sache comment il est constitué exactement.
Un exemple par macro, les listes sont sur une autre feuille.
Sur une modification de liste la macro parcoure toutes les cellules de Feuil1 avec validation par liste, s'assure que c'est bien le bon nom de liste, et modifie si c'est l'item modifié qui était sélectionné.
Sauf en cas de suppression pour limiter les erreurs irrécupérables. Il faudra sans doute d'autres garde-fous...
Pas le temps de fignoler plus, il faudra que tu adaptes à ton classeur car je m'absente qq jours.
eric
Merci beaucoup Eric. J'ai testé ton fichier et ça marche très bien. C'est exactement ce que je voulais comme comportement.
Mon problème est que je ne comprends pas "comment" ton code marche et que donc je ne suis pas capable de l'adapter à mes besoins.
Est ce que toi ou un autre sachant pourrait éclairer ma lanterne ?
Je comprends tout à fait la première partie de ton code:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim nomListe As String, avant As String, apres As String
Dim pl As Range, c As Range, nb As Long
If Target.Row = 1 Then Exit Sub
nomListe = Cells(1, Target.Column)
apres = Target
If apres = "" Then MsgBox "suppression, pas de mise à jour": Exit Sub
Application.EnableEvents = False
Application.Undo
avant = Target
Target = apres
Application.EnableEvents = TrueLa partie de code que je ne comprends pas est :
With Sheets("Feuil1")
Set pl = .Cells.SpecialCells(xlCellTypeAllValidation)
If Not pl Is Nothing Then
For Each c In pl
If c.Validation.Formula1 = "=" & nomListe Then
If c.Value = avant Then c = apres: nb = nb + 1
End If
Next c
MsgBox nb & " modifications effectuées"
End If
End WithMerci d'avance,
J'ai essayé de faire un bout de code mais qui ne fonctionne pas. L'idée est toujours d'aller modifier un libellé dans un tableau si le libellé d'origine a été modifié dans une liste. ça ne fonctionne pas mais j'espère que l'idée y est :
Sub Worksheet_Change(ByVal Target As Range)
Static Nom_col As String
Nom_col = Cells(1, Target.Column).Value
Application.EnableEvents = True
Dim oldvalue As String
Dim newvalue As String
Application.EnableEvents = False
newvalue = Target.Value
Application.Undo
oldvalue = Target.Value
Application.Undo
Dim Range_feuil1 As Range
Dim col_ID_1 As Range
Dim col_feuil1 As Range
Set Range_feuil1 = Feuil1.Rows(1)
For Each col_ID_1 In Range_feuil1.Columns
If Cells(1, col_ID_1.Column).Value = Nom_col Then
Set col_feuil1 = col_ID_1.Columns
col_feuil1.Replace What:=oldvalue, Replacement:=newvalue, lookat:=xlWhole, searchorder:=xlByColumns
End If
Next col_ID_1
End sub()Merci d'avance pour vos commentaires et corrections éventuelles
Bonjour,
vite fait avant de partir :
With Sheets("Feuil1") ' avec la Feuil1
Set pl = .Cells.SpecialCells(xlCellTypeAllValidation) ' cellules avec validation
If Not pl Is Nothing Then
' s'il y a des cellules avec validation dans Feuil1
For Each c In pl ' pour chaque cellules avec validation
If c.Validation.Formula1 = "=" & nomListe Then ' si la liste utilisée est celle modifiée
' et si l'item est l'item modifié le mettre à jour
If c.Value = avant Then c = apres: nb = nb + 1
End If
Next c
MsgBox nb & " modifications effectuées"
End If
End Witheric
Merci beaucoup pour ces précisions.
J'aurai juste besoin d'une amélioration :
je ne peux pas utiliser
nomListe = Cells(1, Target.Column)parce que j'ai trop de noms de liste et j'ai besoin de leur mettre des noms parlants mais pas utilisables pour des entêtes de colonnes excel.
est ce qu'il y a une instruction qui me permettrait simplement d'identifier le nom de la plage à laquelle appartient la cellule du genre:
nomListe=Target.Cells.Name.NameMerci d'avance,
Merci encore Eriic, ta solution fonctionne parfaitement et j'ai bien compris tes explications
J'ouvre un nouveau sujet pour mon dernier problème (=identifier la plage dans laquelle je me situe)
Bonjour,
Je suis sur tablette donc pas d'excel pour tester.
À mon avis il faut balayer tous les noms et voir s'il y a une intersection avec la cellule modifiée.
Sinon tu peux prévoir 2 lignes de titre. Une pour le libellé utilisateur et une pour le nom de liste.