Bonjour pelletim,
merci pour ton retour ; j'ai supprimé la version v3 ; voici la v4 (qui est très fiable) :
https://www.cjoint.com/c/MAFjcMEHnr0
note : la v2 écrit les positions "après-coup", quand toutes les données ont été saisies en
C12:AJ28 ; la v4 écrit les positions au fur et à mesure pour une seule colonne à la fois,
celle où on saisit ou on modifie une donnée dans la plage C12:AJ28.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1) attention : la ligne 29 est très importante ! ne rien modifier !
pour la 1ère liste "Liste 1" :
a) la plage de cellules correspondantes pour la saisie est : C12:C28.
b) tu dois modifier une de ces cellules.
* une modif dans C12:C28 fait que ça efface la plage AM12:AM28, AO32:AQ48 ;
plus tard, il faudra faire Ctrl k quand les 34 listes seront pleines ET quand AO29
sera à 0 ; pour AO29, ça va être décrit au point d).
* si tu vois un "#" en C29, ça signifie que la plage C12:C28 n'est pas complète :
il manque un des nombres 1 à 17, donc il y a au moins une cellule vide dans
C12:C28 ; mais au départ, quand le tableau entier des données est vide :
C12:C28 est vide, sans "#" en C29 (ce qui ne gênera pas du tout).
* si tu effaces un nombre avec la touche Suppression : "#" en C29, et toutes
les positions de C32:C48 sont effacées (ça sera écrit de nouveau lors de la
prochaine saisie d'un nombre valide ; c'est grâce à cela que c'est très fiable,
même quand tu remplaceras un nombre valide par un autre nombre valide).
* si tu saisis une autre valeur que 1 à 17 (par exemple 20) : nb refusé et effacé
& "#" en C29 ; là aussi, toutes les positions de C32:C48 sont effacées (ça sera
écrit de nouveau lors de la prochaine saisie d'un nombre valide) ; idem pour
une valeur qui ne tient pas dans la plage d'un byte (ex : 300) ; rappel : pour
un byte (octet), la plage des nombres est : de 0 à 255.
* si tu saisis un doublon : nb refusé et effacé & "#" en C29 ; et là aussi, toutes
les positions de C32:C48 sont effacées (ça sera écrit de nouveau lors de la
prochaine saisie d'un nombre valide) ➯ y'a plus aucun problème concernant
les doublons vu qu'ils ne sont pas acceptés. :) de plus, si par exemple tu as
mis 5 en C18 et que tu veux le déplacer ailleurs (dans C12:C28), commence
par effacer ce 5 avant de le saisir de nouveau (sinon : doublon refusé).
* voici quand il n'y a pas de "#" en C29 (et donc pas d'erreur) : il n'y a pas de
cellule vide dans C12:C28 ; chaque cellule de C12:C28 contient un nombre ;
ce nombre est compris entre 1 et 17 inclus ; il n'y a pas de répétitions, donc
comme chaque nombre est unique, ça signifie qu'il y a les nombres 1 à 17
dans C12:C28 (quelque soit leur ordre) ; bien sûr, la somme de 1 à 17 est
toujours 153 (c'était le résultat de ton ancienne formule de C51).
* si un nombre saisi en C12:C28 est correct, ça met ce qu'il faut en C32:C48
(c'est-à-dire les positions pour chaque nombre de C12:C28) ; c'est très
fiable dans tous les cas (même pour un remplacement).
c) à droite de la colonne C (colonnes D à AJ), c'est pareil pour toutes
les autres colonnes de listes (Liste 2 à Liste 34).
d) en AO29 : =NBVAL(C29:AJ29) ; ça retourne le nombre de "#" de la ligne ;
attention : ce nombre sera testé par la sub SetClassement() ; il ne faut donc
surtout pas effacer cette formule !
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2) quand y'a aucun "#" dans C29:AJ29 :
* toutes les colonnes de données (C12:AJ28) sont bonnes : y'a aucune erreur.
* la plage C29:AJ29 est vide, et AO29 contient 0.
* Ctrl k ➯ ça remplit le tableau "classement" et la plage sur fond vert si le nombre de
données de C12:AJ28 = 578 (car 34 listes × 17 nbs = 578 nbs) ET si AO29 = 0.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3) quand y'a un "#" ou plusieurs "#" dans C29:AJ29 :
* une des colonnes au moins de C12:AJ28 n'est pas complète et AO29 > 0.
* Ctrl k ➯ ça vide le tableau "classement" et la plage sur fond vert si le nombre de
données de C12:AJ28 est différent de 578 (= 34 listes × 17 nbs) OU si AO29 > 0.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4) à propos de tout ce que j'ai décrit au point 1) :
pour que ça marche correctement, les événements d'Excel doivent être activés,
ce qui est déjà le cas par défaut ; mais si jamais ça n'agit pas comme d'habitude,
c'est probable que les événements ont été désactivés (en cas de plantage ou de
mauvaise manipulation) ; dans ce cas, fais Ctrl r pour réactiver les événements
d'Excel : ça appelle la sub Réactiv().
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
5) code VBA du module de Feuil1 (40 lignes) ; comme les doublons sont refusés,
j'ai pu faire plusieurs simplifications ; j'ai aussi ajouté plusieurs commentaires.
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo 1 'c'est pour une valeur hors byte
Dim T(1 To 17) As Byte, n As Byte, c%, s$
Dim v As Byte, r As Byte, k As Byte, i As Byte
With Target
If .CountLarge > 1 Then Exit Sub
If Intersect(Target, [C12:AJ28]) Is Nothing Then Exit Sub
c = .Column: s = .Value
End With
With Application
.ScreenUpdating = 0: .EnableEvents = 0
[AM12:AM28, AO32:AQ48].ClearContents: Cells(29, c) = "#"
Cells(32, c).Resize(17).ClearContents: v = Val(s)
If v < 1 Or v > 17 Then
'refus d'une valeur hors bornes, ou d'une valeur causant
'un dépassement de capacité (ne tenant pas dans un byte)
1 Target.ClearContents: GoTo 2
Else
For i = 1 To 17
k = Cells(i + 11, c): T(i) = k
If k = v Then
'refus d'une valeur si elle existe déjà => pas de doublon
n = n + 1: If n = 2 Then Target.ClearContents: GoTo 2
End If
Next i
'écrire toutes les positions (lignes 32 à 48, même colonne c) ;
'mais peut y'avoir des vides (si vide en lignes 12 à 28, col c)
For i = 1 To 17
k = T(i): If k > 0 Then Cells(k + 31, c) = Cells(i + 11, 2)
Next i
'comme y'a pas de doublons : si y'a 17 nombres, ils sont tous présents
'une seule fois (nbs 1 à 17) => on peut effacer le "#" de la colonne c
If .Count(Cells(12, c).Resize(17)) = 17 Then Cells(29, c).ClearContents
End If
2 .EnableEvents = -1 'on réactive les événements d'Excel
End With
End Sub
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6) code VBA de Module1 (25 lignes) ; c'est idem que pour l'ancienne v3 :
je n'y ai fait aucun changement.
Option Explicit
Sub SetClassement()
Dim n%: Application.ScreenUpdating = 0
n = Application.Count([C12:AJ28])
If n <> 578 Or [AO29] > 0 Then _
[AM12:AM28, AO32:AQ48].ClearContents: Exit Sub
Dim v#, r As Byte, i As Byte
For i = 1 To 17
r = i + 31
With Cells(r, "AO")
v = .Offset(, -2)
.Value = WorksheetFunction.Rank(v, [AM32:AM48], 1)
.Offset(, 1) = i: .Offset(, 2) = v
End With
Next i
[AO32:AQ48].Sort [AO32]
[AP32:AP48].Copy: [AM12].PasteSpecial -4163
Application.CutCopyMode = 0: [AO12].Select
End Sub
Sub Réactiv()
Application.EnableEvents = -1
End Sub
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
à propos des raccourcis claviers Ctrl r et Ctrl k : c'est normal que tu ne les
connaissais pas car c'est moi qui ai choisi ces lettres pour appeler les 2
subs que j'ai créées (situées dans Module1).
* r est l'initiale de Réactiv() : pour réactiver les événements d'Excel.
* k ressemble phonétiquement au c de classement et appelle la sub
SetClassement() ; j'ai évité volontairement le Ctrl c car il est souvent
utilisé pour faire le copier (d'un copier / coller).
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
à toi de faire plusieurs tests. :)
rhodo