Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Validation de l'unicité sur plusieurs colonnes

11 réponses
Avatar
René R.
Bonjour (Bonsoir) tout le monde,

J'ai un cas pas facile (en tout cas pour moi) =E0=20
solutionner.

J'ai un tableau de 6 colonnes, de D =E0 I.
La ligne 1 est une ligne d'ent=EAte.

Je cherche =E0 faire une macro qui valide que pour chaque=20
valeur de la colonne E, si d'autres lignes ont une valeur=20
identique sous la m=EAme colonne, que la valeur des autres=20
colonnes (D, G, H et I) soit =E9galement identique, sauf=20
pour la colonne F.

Donc:
Si E2=3DE3 alors il faut que=20
D2=3DD3 et G2=3DG3 et H2=3DH3 et I2=3DI3
sinon afficher la valeur de E2 =E0 l'=E9cran

Faut v=E9rifier la ligne 2 avec toute les lignes du tableau=20
et ensuite recommencer la v=E9rification en comparant E3 =E0=20
E4 et ainsi de suite.

J'arrive =E0 le faire avec des For Next mais j'aimerais une=20
solution utilisant des variables, il me semble que =E7=E0=20
serait plus vite.

Alors si quelqu'un comprend mes explications et sait=20
comment s'y prendre, alors je l'en remercie =E0 l'avance.

Cordialement.

Ren=E9 R.

10 réponses

1 2
Avatar
AV
Alors si quelqu'un comprend mes explications ....


Essayons ......

Sub zz_Values()
For i = 2 To [E65536].End(3).Row - 1
If Cells(i + 1, 5).Value = Cells(i, 5).Value Then
Cells(i, 4).Value = Cells(i + 1, 4).Value
Range(Cells(i, 7), Cells(i, 9)).Value = (Range(Cells(i + 1, 7), Cells(i +
1, 9)))
End If
Next
End Sub

AV

Avatar
Vincent.
Bonjour René, AV,
Je vous propose une solution sans vba, par le menu
Données/Validation Autoriser Personnalisé.
Pour la colonne E, c'est facile, il n'y a pas de
validation à mettre.
Pour les colonnes D, G et H et I, l'utilisation de la
formule suivante (appliquée ici à la ligne 4 colonne F) :
=OU(ESTERREUR(RECHERCHEV($D4;$D1:$D10000;1;FAUX));F4=INDEX
(F1:F10000;EQUIV($D4;$D1:$D10000;0);0))
permet une saisie libre pour si la valeur D4 n'est nulle
part ailleurs dans le tableau et uniquement la valeur
saisie en colonne F de la première occurence de la valeur
D4 sinon.
Pour la colonne FE pour éviter les doublons, il est
possible d'utiliser :
=SOMMEPROD((D1:D10000Ô)*(E1:E10000ä))<=1
Je n'ai pas testé dans tous les sens, mais à partir de ton
exemple, cela semblait fonctionner correctement.
Cela te convient-il ?
A+

V.

-----Message d'origine-----
Bonjour (Bonsoir) tout le monde,

J'ai un cas pas facile (en tout cas pour moi) à
solutionner.

J'ai un tableau de 6 colonnes, de D à I.
La ligne 1 est une ligne d'entête.

Je cherche à faire une macro qui valide que pour chaque
valeur de la colonne E, si d'autres lignes ont une valeur
identique sous la même colonne, que la valeur des autres
colonnes (D, G, H et I) soit également identique, sauf
pour la colonne F.

Donc:
Si E2ã alors il faut que
D2Ó et G2=G3 et H2=H3 et I2=I3
sinon afficher la valeur de E2 à l'écran

Faut vérifier la ligne 2 avec toute les lignes du tableau
et ensuite recommencer la vérification en comparant E3 à
E4 et ainsi de suite.

J'arrive à le faire avec des For Next mais j'aimerais une
solution utilisant des variables, il me semble que çà
serait plus vite.

Alors si quelqu'un comprend mes explications et sait
comment s'y prendre, alors je l'en remercie à l'avance.

Cordialement.

René R.
.



Avatar
AV
Ave Vincent,

J'ai pas testé ta soluce mais comme le Mr a dit :
"...Je cherche à faire une macro ..."

ben voilà...;-)
AV
Avatar
Vincent.
Ave ô Maître !
Je proposais cette soluce parce qu'il me semble que c'est
le genre de macro à ramer un moment dès qu'un grand nombre
de lignes doit être traité. En plus, le Mr en question
n'avait peut-être pas du tout envisagé une solution basée
sur la validation...
J'ai regardé ta soluce qui marche au poil (évidemment ;-) )
A+

V.

-----Message d'origine-----
Ave Vincent,

J'ai pas testé ta soluce mais comme le Mr a dit :
"...Je cherche à faire une macro ..."

ben voilà...;-)
AV


.



Avatar
Vincent.

J'ai pas testé ta soluce mais comme le Mr a dit :
"...Je cherche à faire une macro ..."



Et puis, j'y pense : si vraiment il s'agit de repérer les
données fausses via macro, en complément de la validation
suscitée (sic!), tu peux les visualiser au moyen de :
Application.CircleInvalid
et les sélectionner (ou les traiter) au moyen de :

Sub yalah()
Dim cellules As Range
ActiveSheet.CircleInvalid
For Each c In Intersect(Range("C:I"), Range
("C2").SpecialCells _
(xlCellTypeSameValidation)).Cells
If Not c.Validation.Value Then
If cellules Is Nothing Then
Set cellules = c
Else
Set cellules = Union(cellules, c)
End If
End If
Next c
cellules.Select

End Sub

Ok Ok, c'est moyen propre, mais ça marche...

Et j'ai repéré une coquille dans les références de la
validation que j'avais donnée tout à l'heure. La formule
corrigée est :
=OU(SOMMEPROD(($D$1:$D$10000=$D2)*1)<=1;C2=INDEX
(C$2:C$10000;EQUIV($D2;$D$2:$D$10000;0);0))
pour la cellule C2, en ayant sélectionner la plage située
sur les colonnes C, G, H et I.
Ouala...

V.

Avatar
Vincent.

J'ai pas testé ta soluce mais comme le Mr a dit :
"...Je cherche à faire une macro ..."



Et puis, j'y pense : si vraiment il s'agit de repérer les
données fausses via macro, en complément de la validation
suscitée (sic!), tu peux les visualiser au moyen de :
Application.CircleInvalid
et les sélectionner (ou les traiter) au moyen de :

Sub yalah()
Dim cellules As Range
ActiveSheet.CircleInvalid
For Each c In Intersect(Range("C:I"), Range
("C2").SpecialCells _
(xlCellTypeSameValidation)).Cells
If Not c.Validation.Value Then
If cellules Is Nothing Then
Set cellules = c
Else
Set cellules = Union(cellules, c)
End If
End If
Next c
cellules.Select

End Sub

Ok Ok, c'est moyen propre, mais ça marche...

Et j'ai repéré une coquille dans les références de la
validation que j'avais donnée tout à l'heure. La formule
corrigée est :
=OU(SOMMEPROD(($D$1:$D$10000=$D2)*1)<=1;C2=INDEX
(C$2:C$10000;EQUIV($D2;$D$2:$D$10000;0);0))
pour la cellule C2, en ayant sélectionner la plage située
sur les colonnes C, G, H et I.
Ouala...

V.

Avatar
René R.
Bonjour Vincent et Alain,

D'abord merci de votre aide. Comme le disent les enfants
par chez nous, vous êtes "full gentils".

Cependant, les solutions que vous me proposées ne
répondent pas tout à fait à ce que j'ai besoin. Je
m'explique:

° J'ai omis de mentionner que le tableau était déjà
existant. C'est donc dire qu'une validation lors de la
saisie est adéquate pour les modifications ou les
nouvelles entrées, mais inefficace pour les données déjà
saisies.

° La méthode utilisée, ne doit pas modifier les valeurs,
mais simplement afficher un message ou inscrire les
anomalies dans un onglet distinct. Par exemple: "Les
valeurs des lignes 7 et 56 sont identiques pour la
colonnes E mais différentes pour l'une ou plusieurs des
colonnes D, G,H ou I."

° Le tableau que je reçois est occasionnellement "écrasé"
par un nouveau tableau. Je perd donc tout format
particulier ou toute validation que j'aurais appliquée
directement dans le tableau.

° La validation d'une ligne ne doit pas être faite qu'avec
la ligne qui la suit mais avec toutes les lignes qui la
suivent jusqu'à la fin du tableau. Si j'ai 100 lignes (de
2 à 101) alors je dois valider E2 avec E3, E4, E5, E6 ...
jusqu'à E101. Ensuite, je dois valider E3, avec E4, E5, E6
et ainsi de suite jusqu'à 101. Et je continue ainsi
jusqu'à ce que toutes les valeurs sous la colonne E aient
été validées. Évidemment, le nombre de lignes est
variables et beaucoup plus nombreux que dans mon exemple.

Ce sont les raisons pour lesquelles je souhaite une
solution par macro VBA utilisant la notion de "tableau
variant".

J'ai écris une procédure qui fait présentement le travail
avec des For/Next. Cette procédure fonctionne mais je ne
suis pas programmeur et je suis persuadé qu'il est
possible de l'optimiser afin d'en accélérer l'exécution.

Encore merci de votre collaboration.

René R. dit le Mr :)

-----Message d'origine-----
Ave Vincent,

J'ai pas testé ta soluce mais comme le Mr a dit :
"...Je cherche à faire une macro ..."

ben voilà...;-)
AV


.



Avatar
Bonjour

Voici à quoi ressemble la macro que j'utilise. Elle réside
dans un classeur distinct du tableau à valider. Pour
l'utiliser, je me positionne dans le classeur et l'onglet
qui contient le tableau (pour que ce soit la feuille
active) et je lance la macro.

Sub Valide()
' Validation
Application.ScreenUpdating = False
Valide = "OK"
' Recherche la dernière ligne du tableau
DernLign = Cells(Cells.Rows.Count, "A").End(xlUp).Row
' Déboule colonne E
For ligne = 2 To DernLign
' Met les valeurs des cinq colonnes dans des
variables. Peut être pas nécessaire
Nom1 = Range(Cells(ligne, 4), Cells(ligne,
4)).Value
Nom2 = Range(Cells(ligne, 5), Cells(ligne,
5)).Value
Type_Metr = Range(Cells(ligne, 7), Cells(ligne,
7)).Value
Unite_Metr = Range(Cells(ligne, 8), Cells(ligne,
8)).Value
Regroup = Range(Cells(ligne, 9), Cells(ligne,
9)).Value
' Par la vérif avec toutes les autres lignes du
tableau
For verif = ligne + 1 To DernLign
If Range(Cells(verif, 5), Cells(verif,
5)).Value = Nom2 Then
If Range(Cells(verif, 4), Cells(verif,
4)).Value = Nom1 And _
Range(Cells(verif, 7), Cells(verif,
7)).Value = Type_Metr And _
Range(Cells(verif, 8), Cells(verif,
8)).Value = Unite_Metr And _
Range(Cells(verif, 9), Cells(verif,
9)).Value = Regroup Then
Valide = "OK" ' si les valeurs des
deux lignes sont égales alors tout est beau
Else
Valide = "Bad"
End If
If Valide = "Bad" Then
Application.ScreenUpdating = True
Msg = "Erreur métrique = " & Nom2
& "Ligne : " & ligne ' Définit le message.
Style = vbOKOnly '
Définit les boutons.
Title = "Attention !!!" ' Définit
le titre.
' Affiche le message.
Reponse = MsgBox(Msg, Style, Title)
Application.ScreenUpdating = False
Valide = "OK"
End If
End If
Next verif
Next ligne
End Sub

René R.
Avatar
AV
Le moins qu'on puisse dire, est que, entre la question de départ et sa suite, il
n'y a vraiment que peu de similitude !
;-)

AV
Avatar
René R.
Désolé, je n'étais pas mal intentionné ...

René
-----Message d'origine-----
Le moins qu'on puisse dire, est que, entre la question de
départ et sa suite, il

n'y a vraiment que peu de similitude !
;-)

AV


.



1 2