Tri de données dans une plage avec incrémentation
Bonjour,
Dans le classeur ci-joint, je souhaite que la plage A2:E41 se trie automatiquement par ligne en fonction du nombre entré dans la plage A2:A41.
J'ai inséré un contrôle obligeant à entrer un nombre compris entre 1 et 40 et fait une macro de tri des données.
Le problème, c'est que si l'on saisit un nombre, ce sera forcément un nombre déjà inscrit dans une des cellules de la plage A2:A40.
Aussi, il me semble qu'il faudrait que le nombre saisi (par exemple 20) dans l'une des cellules (par exemple A31 qui contenait initialement la valeur 30) incrémente automatiquement de 1 tous les nombres compris dans la plage A2:A41 à partir du nombre saisi(20 dans l'exemple) et ce jusqu'au nombre initialement contenu dans la cellule dans laquelle un nombre a été saisi (30 en A31 dans l'exemple) et ce sans toucher la valeur saisie (20 en A31) tout en effectuant le tri des données à chaque incrémentation (pour éviter de mélanger tout le tableau).
Question bonus : Obliger la saisie d'un nombre entier
J'espère avoir été assez clair.
Merci pour votre aide.
Bonjour,
Pour la saisie d'un nombre entier entre 1 et 40, je passerais part la validation des données.
- Sélectionner la plage A2:A41
- Données - Validation des données.
- Choisir nombre entier entre 1 et 41.
Bonjour,
Merci pour ce premier élément de réponse
Bonjour,
Es ce qu'un filtre sur la colonne A ne suffirai pas à solutionner ton problème ?
Bonjour,
Non car lorsque l'on modifie un numéro dans la colonne A, il y a forcément un doublon. Alors, pour peu qu'on en modifie 10...
Le tableau deviendrait peu lisible...
Bonjour,
Sans VBA pas facile. Mais pour le fun...
J'ai ajouté 3 Colonnes G H et I
H est la colonne dans la quelle tu modifies.
Si pas de modif Colonne I --> Pas de modif
Sinon,
en colonne G : 0 devant ta modification.
en colonne I nouvelle numérotation
Reste à faire un collage des valeur de la colonne I en colonne 1.
Puis le tri de ton tableau
et enfin un collage de la colonne 1 en colonne H pour la modif à venir.
A améliorer en VBA ou avec au minimum avec l'éditeur de macro pour automatiser un peu.
@+
Merci Bernard, je vais regarder ta proposition.
Mais pourquoi as-tu indiqué, "sans VBA pas facile" ?
Car c'est ce que j'aurais préféré !
Bonjour,
Sans VBA : Parce que j'ai confondu avec un autre post qui ne voulait pas de VBA
Je revois donc la copie....
@+
Ahh d'accord !
Bon bien j'attends la version VBA avec impatience.
Mille mercis
Bonjour,
Désolé, je me perds un peu dans l'analyse et je vais manquer de temps aujourd'hui.
Je relance pour passer la main à plus compétent que moi.
NB je suis sur le forum pour aider et surtout pour apprendre.
Je regarderai les propositions et retravaillerai demain le cas échéant.
@+
J'ai un peu avancé et vous joins la dernière version du classeur (les plages ont été un peu modifiées par rapport à la V1).
J'ai réussi à suivre la cellule modifiée initialement jusqu'à son emplacement après le tri.
ThoThème m'a fourni une macro qui incrémente de 1 la valeur de la cellule se trouvant dans la plage (A8:A54) ayant la valeur de la cellule sélectionnée.
Le problème est que je ne sais pas comment repartir sur la première fonction une fois que l'incrémentation est effective.
Et est-ce bien cela qu'il faut faire... ? Car j'avoue que je m'y perds un peu !
Peut-être est-il possible ou nécessaire de regrouper les 2 subs ? Si oui, comment...
Je suis un ultra débutant donc le code doit regorger de termes inutiles et peux certainement être synthétisé et amélioré.
Si toutefois certains peuvent me donner des conseils, ils sont les bienvenus.
Merci d'avance
Résolu par ThauThème (que je remercie encore) dans un autre post. Voici la solution.
ThauThème a écrit :Re,
Belle galère ! Mais je crois que c'est fonctionnel.
Commence par ajouter tout en haut du module [Tri_plage] la ligne :
Public AV As Byte 'déclare la variable AV (ancienne Valeur)Puis les deux événementielles ci-dessous dans le composant Feuil2(Affectations possibles).
Pour-être sûr que ça fonctionne, il faut qu'au moins la première fois tu cliques d'abord dans la cellule A1 (pour définir l'ancienne valeur AV)... Après tout se fait automatiquement...
Private TEST As Boolean 'déclare la variable TEST Private Sub Worksheet_SelectionChange(ByVal Target As Range) 'au changement de selection dans l'onglet Dim PL As Range 'déclare la variable PL Set PL = Range("A2:A41") 'définit la plage PL If Intersect(PL, Target) Is Nothing Then Exit Sub 'si le changement a lieu ailleurs que dans la plage PL, sort de la procédure If Target.Count > 1 Then Exit Sub 'si le changement a lieu dans plusieurs cellules de la plage PL, sort de la procédure If TEST = True Then Exit Sub 'si TEST est [Vrai], sort de la procédure (je préfère ça à EnableEvents = False) AV = Target.Value 'définit l'ancienne Valeur AV (déclarée publique dans le module [Tri_plage] End Sub Private Sub Worksheet_Change(ByVal Target As Range) 'au changement dans l'onglet Dim PL As Range 'déclare la variable PL Dim CEL As Range 'déclare la variable CEL (CELlule) Dim LD As Byte 'declare la variable LD (Ligne de Départ) Dim LF As Byte 'declare la variable LF (Ligne de Fin) Dim LI As Byte 'declare la variable LI (LIgne) Set PL = Range("A2:A41") 'définit la plage PL If Intersect(PL, Target) Is Nothing Then Exit Sub 'si le changement a lieu ailleurs que dans la plage PL, sort de la procédure If Target.Count > 1 Then Exit Sub 'si le changement a lieu dans plusieurs cellules de la plage PL, sort de la procédure If TEST = True Then Exit Sub 'si TEST est [Vrai], sort de la procédure (je préfère ça à EnableEvents = False) If Not IsNumeric(Target.Value) Or 40 < Target.Value Or 1 > Target.Value Then 'condition : si la cellule modifié contient une valeur inférieure à 1 ou supérieure à 40 MsgBox "Merci de saisir une valeur numérique comprise entre 1 et 40 !!! " 'message With Application 'prend en compte l'Application .EnableEvents = False 'n'autorise plus les procédures événementielles .Undo 'annule de vient d'être fait .EnableEvents = True 'autorise les procédure événementielles End With 'fin de la prise e compte de l'Apllication End If 'fin de la condition TEST = True 'définit la variable TEST Target.Value = Target.Value \ 1 'si une valeur décimale est éditée, remplace par la valeur entière If AV < Target.Value Then 'condition : si l'ancienne valeur de la cellule modifiée est inférieure à la nouvelle valeur LD = Target.Row + 1 'définit la ligne de départ LD Else 'sinon For Each CEL In PL 'boucle sur toutes les cellules CEL de la plage PL 'si la valeur de la cellule CEL est égale à la valeur de la cellule modifié et que leur adresse est différente, If CEL.Value = Target.Value And CEL.Address <> Target.Address Then LD = CEL.Row: Exit For 'définit la ligne de départ LD et sort de la boucle Next CEL 'prochaine cellule de la boucle End If 'fin de la condition 'LF = IIf(AV > Target.Value, Target.Row - 1, Target.Row + 1) 'définit la ligne de fin LF en fonction de l'ancienne valeur (une ligne au-dessus ou au-dessous de la cellule modifiée) If AV > Target.Value Then 'condition : si l'ancienne valeur de la cellule modifiée est inférieure à la nouvelle valeur LF = Target.Row - 1 'définit la ligne de départ LD Else 'sinon For Each CEL In PL 'boucle sur toutes les cellules CEL de la plage PL 'si la valeur de la cellule CEL est égale à la valeur de la cellule modifié et que leur adresse est différente, If CEL.Value = Target.Value And CEL.Address <> Target.Address Then LF = CEL.Row: Exit For 'définit la ligne de départ LD et sort de la boucle Next CEL 'prochaine cellule de la boucle End If 'fin de la condition For LI = LD To LF 'boucle sur toutes les ligne LI de LD à LF Cells(LI, 1).Value = IIf(AV > Target.Value, Cells(LI, 1).Value + 1, Cells(LI, 1).Value - 1) 'incrémente la cellule ligne Li colonne 1 Next LI 'prochaine ligne de la boucle If Not Intersect(Target, PL) Is Nothing Then Tri 'lance la procédure [Tri] Range("A1").Select 'sélectionne la cellule A1 TEST = False 'réinitialise la variable TEST End Sub