Votre question
Résolu

VBA-Comparer une ligne à plusieurs autres sur deux cellules

Tags :
  • Microsoft Excel
Dernière réponse : dans Programmation
27 Mai 2013 14:53:23

Bonjour,
J'ai déjà posté ici il n'y a pas longtemps, j'ai besoin de votre aide et de votre connaissance pour m'aider sur un autre problème.

Je m'explique, je dispose d'un tableau de mesure (une mesure par ligne et des données sur chaque cellule de "A" à "Q") et d'un tableau de capteur(un capteur par ligne et des données de "AL"à "BC"). Pour chaque mesure je souhaite comparer deux valeurs, à deux valeurs de tout les capteurs (pour trouver les capteurs compatibles pour chaque mesure). Les valeurs des mesures ce situe dans les colonnes "F" et "G" (donc"F5" et "G5"pour al première mesure, "F6" et "G6" pour la seconde) à comparer avec les valeurs de tout les capteurs en "AQ" et "AR".

Autre difficulté (pour moi :p ) les valeurs en F sont des valeurs mini, donc quand on les compares avec toutes les valeurs en "AQ" il faut que cela nous sélectionne toute les valeurs égales ou inférieur de capteur, pareille pour "G" comparé à "AR", les valeurs de "G" étant des valeurs max, il faut que les valeur retenu en "AR" soit égales ou supérieurs.

Une fois que nous avons trié les capteur potentiels (il peut en avoir plusieurs de disponible pour une seule mesure) je souhaite les ecrire dnas un troisième tableau entre les deux autres ( de "S5" à "AJ5" pour el premier capteur potentielle à "S5+i" à "AJ5+i" avec i le nombre de capteurs).

Autre problème ici c'est que du fait que chaque mesure a potentiellement plusieurs capteurs, je suis obligé de traiter une mesure par une mesure ou de tout faire en même temps mais d'insérer une ligne en dessous de chaque mesure par capteur supplémentaire, mais cela engendrerais des lignes vides dans mon tableau de capteurs.

En premier temps j'avais pensez que une fois sur ma feuille de calcul Excel, je sélectionne a la souris la ligne de mesure pour laquelle je veux trouver mon(mes) capteurs, que je clic sur mon bouton de macro et que ça me sorte sur mon tableau central le(s) capteur(s) potentiels. j'avais pensez utiliser un filtre avancées, un peu comme ça:

  1. Selection.AdvancedFilter _
  2. Action:=xlFilterCopy, _
  3. CriteriaRange:=Range("F5:G5"), _
  4. CopyToRange:=Range("S5:AJ5"), _
  5. Unique:=False


Mais que le CriteriaRange s'adapte aussi à la sélection en ne prenant en compte que "F" et "G" de la sélection, et que le CopyToRange s'incrémente à chaque nouveau capteur.

Je pense que il y a plus simple mais malgré mes recherches sur Google, je en trouve rien de bien pertinent.

Si vous connaissez une fonction qui peut me permettre cela ou une petite amélioration de mon code sur les filtres je suis preneur =).

Je pense que j'ai écrit un bon pavé, donc si quelque chose ne vous semble pas clair dans la description de mon problème, demandez moi je vous répondrais au plus vite. Je continue de chercher de mon coté.

Merci d'avance pour toute aide qui me sera donnée =)

Autres pages sur : vba comparer ligne plusieurs cellules

28 Mai 2013 13:57:54

Salut,

On attend Tantal ( :hello:  ) ou on commence tout de suite ?

Je n'aime pas utiliser les trucs actifs ou sélectionnés.
Tu l'as déjà vu dans ton premier message, j'en parle à l'ami Tantal (ActiveSheet).

Mais il est des cas, que propose justement Tantal, ou dans le cas que tu décris, où c'est parfaitement justifié.

Donc on sélectionne une ligne et on exécute la macro, qui devra se servir de la ligne en cours pour paramètre.

Regarde comment ça se fait :
  1. Sub ma_fonction()
  2. Dim la_ligne As Range
  3.  
  4. ' // On met ce qui est actif dans une variable, dès le début. '
  5. ' // Comme ça, si la sélection change, on l'aura quand même en mémoire.
  6. Set la_ligne = Selection.EntireRow
  7. If la_ligne.Rows.Count > 1 Then
  8. MsgBox "Veuillez ne sélectionner qu'une seule ligne.", vbCritical
  9. Exit Sub
  10. End If
  11.  
  12. MsgBox "Ligne choisie : " & la_ligne.Rows(1).Row, vbInformation
  13.  
  14. End Sub


Bon, maintenant, on parcourt toutes les lignes utiles de ta feuille, sauf la ligne choisie, et on regarde si certaines d'entre elles ne correspondraient pas.

Pour ce qui est des lignes vides, je suis assez déçu. Le code proposé dans ton topic précédent présente justement une technique pour ne pas avoir ce genre de soucis.

Avec tout ça, tu devrais avoir assez de billes pour commencer.
Ne t'inquiète pas, on ne t'abandonne pas ;) 

A te lire...
m
0
l
28 Mai 2013 15:13:11

Hello,

Bien entendu que Tantal est bienvenue ici si elle le désire :) 

J'ai regardé vite fait ce que tu me propose Zeb, cela me permettrais de rentrer les données de toute les cellules de la ligne sélectionnée dans une variable. Mais comment ne comparer seulement 2 de ces cellules a 2 cellules du tableaux que je vais appeler Data Base (DB). la je pourrais comparer les ligne entière. Ors entre mon tableau de mesure et celui de DB seule certaines cellules sont comparables (dont les deux que je recherche en priorité). Je ne peut pas faire de comparaison ligne à ligne. de plus ce n'est pas une comparaison exact que je veux mais un "<=" ou ">=".

Concrètement mes mesures on des ranges mini et maxi que les capteurs doivent "englober", c'est a dire que la range mini du capteur doit être"<=" à celle de la mesure et la range maxi du capteur doit être ">=" à celle de la mesure.

Je ne sais pas si je suis bien clair dans mes explication :/ .
Sur la façon de résoudre mon problème beaucoup me viennent à l'idée (d'un plan purement strat, sans parler du codage), mais elle apporte toute un problème sur la disposition de mes tableau dans mes feuilles.

Je regarde quand même ce que tu me propose pour demain, il arrive le temps où les heures que je fait ne sont plus payé, je rentre donc chez moi.

En tout cas merci à tous pour votre aide, cela me fait avancé a grand pas vers la simplification de mon problème.
m
0
l
Contenus similaires
28 Mai 2013 15:40:22

Salut :hello: ,

Effectivement, c'est un bon pavé :lol: 

Si je comprend bien :
Tu as, sur la même feuille,

  • Des colonnes A à Q : les mesures
  • Des colonnes S à AJ : ton résultat, cad les lignes de mesure qui "correspondent" aux capteurs
  • Des colonnes AL à BC : les capteurs


    m
    0
    l
    28 Mai 2013 16:29:24

    Autre question, est-ce-que c'est :

    F => AQ et G <= AR
    ou
    F => AQ ou G <= AR
    m
    0
    l
    28 Mai 2013 20:08:57

    Bonsoir,

    Alors oui en effet:

    Des colonnes A à Q : les mesures
    Des colonnes S à AJ : ton résultat, cad les lignes de mesure qui "correspondent" aux capteurs
    Des colonnes AL à BC : les capteurs

    Les résultats sont pour le moment vide bien évidement, c'est ce que je recherche.
    Comme sur ma Feuille3 "TRI" où vous êtes venu à mon aide, les lignes commencent à la ligne 5 (Au dessus c'est de la "mise en page" pour avoir un minimum un coté "application"

    Et c'est les deux condition ensemble, donc un ET: F => AQ et G <= AR

    N'ayant pas ramener de travail à la maison je n'est pas encore pu tester la fonction de Zeb, je le ferais demain matin.
    m
    0
    l
    29 Mai 2013 09:18:59

    Bonjour à tous,

    Après avoir testé ta macro Zeb, il me vient deux questions dont je n'ai pas trouvé réponse sur l'aide excel ou sur internet.

    1. Set la_ligne = Selection.EntireRow

    Cela enregistre dans ma variable seulement les cellules de la ligne que j'ai sélectionnée ou la ligne entière de ma sélection(dépassant donc ma sélection)?

    Et vu que ma sélection est un tableau (une seule ligne mais un tableau quand même non?), la variable la_ligne est elle aussi un tableau du coup? Je pourrais donc l'utiliser comme un tableau et récupérer les valeurs de sa sixième et septième cellule non?
    m
    0
    l
    29 Mai 2013 11:42:19

    J'ai fait des tests avec la macro suivante:

    1. Sub Temp()
    2.  
    3. Dim la_ligne As Range
    4. Dim i As Integer
    5. Dim Derligne As Integer
    6.  
    7. 'Récupération de la ligne de mesure voulut dans une variable
    8. Set la_ligne = Selection.EntireRow
    9. If la_ligne.Rows.Count > 1 Then
    10. MsgBox "Veuillez sélectionner qu'une seule ligne", vbCritical
    11. Exit Sub
    12. End If
    13. MsgBox "Ligne choisie:" & la_ligne.Rows(1).Row, vbInformation
    14.  
    15. 'Nettoyage de la plage de cellules Résultats
    16. Range("S5", "AJ55000").Select
    17. Selection.ClearContents
    18. Selection.Interior.ColorIndex = xlColorIndexNone
    19.  
    20. 'Recherche des capteurs compatible avec la mesure
    21. For i = 5 To Sheets("TEMP").Cells(Rows.Count, 38).End(xlUp).Row
    22. If ((la_ligne.Cells(0, 6).Value >= Range("AQ" & i).Value) And (la_ligne.Cells(0, 7).Value <= Range("A" & i).Value)) Then
    23. Derligne = (Sheets("TEMP").Cells(Rows.Count, 19).End(xlUp).Row + 1)
    24. Sheets("TEMP").Range(Cells(i, 38), Cells(i, 55)).Copy Destination:=Sheets("TEMP").Cells(Derligne, 19)
    25. End If
    26. Next
    27. MsgBox "Recherche Terminée", vbInformation
    28.  
    29. End Sub


    Je n'ai pas de problème, à part le fait que cela me recopie tout les capteurs :lol: , comme si mes conditions ne marchais pas.

    Vous avez des suggestions?
    m
    0
    l
    29 Mai 2013 13:02:12

    Je crois que Excel commence à compter à partir de 1, donc :
    la_ligne.Cells(0, 6). => la_ligne.Cells(1, 6).

    Ensuite, avant que zeb :hello:  te tombe dessus :
    Remplace
    1. 'Nettoyage de la plage de cellules Résultats
    2. Range("S5", "AJ55000").Select
    3. Selection.ClearContents
    4. Selection.Interior.ColorIndex = xlColorIndexNone

    par quelque chose de plus propre (sans .Select et Selection. )

    Comme ça (c'est peut-être pas optimal, pas bon si "trous") :
    1. 'Nettoyage de la plage de cellules Résultats
    2. Range(Cells(5, 19), Cells(5, 36).End(xlDown)).Delete
    3. ' sinon : Range(Cells(5, 19), Cells(55000, 36)
    m
    0
    l
    29 Mai 2013 14:02:25

    Merci Tantal pour tes corections, un problème se pose maintenant, j'ai essayé la macro corrigé sur ma cinquième ligne, il me recopie bien tout mes capteurs (normal la mesure a une petite étendue donc tout les capteurs sont possibles), mais lorsque je la test sur ma ligne 21, qui a une max range plus élevée que certain capteurs, tout ce qui est du tableau Résultat (de S a AJ) et toute ma base de données capteur (AL à BC) sont effacés (même la colonne AK qui est juste une colonne de séparation grisé). Je ne voit pas ce qui peut faire cela.

    Que veux-tu dire par :"Comme ça (c'est peut-être pas optimal, pas bon si "trous")"

    Merci beaucoup
    m
    0
    l
    29 Mai 2013 14:26:28

    LightenTriff a dit :
    Merci Tantal pour tes corections, un problème se pose maintenant, j'ai essayé la macro corrigé sur ma cinquième ligne, il me recopie bien tout mes capteurs (normal la mesure a une petite étendue donc tout les capteurs sont possibles), mais lorsque je la test sur ma ligne 21, qui a une max range plus élevée que certain capteurs, tout ce qui est du tableau Résultat (de S a AJ) et toute ma base de données capteur (AL à BC) sont effacés (même la colonne AK qui est juste une colonne de séparation grisé). Je ne voit pas ce qui peut faire cela.

    Que veux-tu dire par :"Comme ça (c'est peut-être pas optimal, pas bon si "trous")"

    Merci beaucoup


    C'est étrange, je n'ai pas ce comportement, le bout de code est sensé supprimer ce qu'il y a entre S5 et AJ(dernière ligne non vide).
    Erreur de ma part, j'ai oublié le Shift:=xlShiftUp dans
    1. Range(Cells(5, 19), Cells(5, 36).End(xlDown)).Delete Shift:=xlShiftUp



    Ce que je veux dire par là c'est que s'il y a des lignes vides ou des cellules vide dans la colonne AJ, ça vas poser problème, on peux résoudre ce problème en remplaçant par (moins élégant de mon point de vue)
    Range(Cells(5, 19), Cells(55000, 36)).Delete Shift:=xlShiftUp

    Après si .Delete ne te conviens pas pour x raison (mais ça fait deux lignes) :
    Range(Cells(5, 19), Cells(5, 36).End(xlDown)).ClearContents
    Range(Cells(5, 19), Cells(5, 36).End(xlDown)).ColorIndex = xlColorIndexNone

    [/code]
    m
    0
    l
    29 Mai 2013 14:37:12

    Je te remercie Tantal, cela marche très bien pour le nettoyage. Je me souviendrais que si jamais je fais un saut de ligne ou quoi que je dois modifier mon code, merci :) .

    Par contre ça continue de faire comme si mes conditions étais toujours valides dans mon if, cela me recopie quand même les capteurs qui ne sont pas compatibles pour une range max trop petite.
    m
    0
    l
    29 Mai 2013 15:01:50

    Tu peut reposter ton code modifié stp.
    m
    0
    l
    29 Mai 2013 15:06:57

    Voici

    1. Sub Temp()
    2.  
    3. Dim la_ligne As Range
    4. Dim i As Integer
    5. Dim Derligne As Integer
    6.  
    7. 'Récupération de la ligne de mesure voulut dans une variable
    8. Set la_ligne = Selection.EntireRow
    9. If la_ligne.Rows.Count > 1 Then
    10. MsgBox "Veuillez sélectionner qu'une seule ligne", vbCritical
    11. Exit Sub
    12. End If
    13. MsgBox "Ligne choisie:" & la_ligne.Rows(1).Row, vbInformation
    14.  
    15. 'Nettoyage de la plage de cellules Résultats
    16. Range(Cells(5, 19), Cells(5, 36).End(xlDown)).Delete Shift:=xlShiftUp
    17.  
    18.  
    19. 'Recherche des capteurs compatible avec la mesure
    20. For i = 5 To Sheets("TEMP").Cells(Rows.Count, 38).End(xlUp).Row
    21. If ((la_ligne.Cells(1, 6).Value >= Range("AQ" & i).Value) And (la_ligne.Cells(1, 7).Value <= Range("A" & i).Value)) Then
    22. Derligne = (Sheets("TEMP").Cells(Rows.Count, 19).End(xlUp).Row + 1)
    23. Sheets("TEMP").Range(Cells(i, 38), Cells(i, 55)).Copy Destination:=Sheets("TEMP").Cells(Derligne, 19)
    24. End If
    25. Next
    26. MsgBox "Recherche Terminée", vbInformation
    27.  
    28. End Sub


    Edit: petite erreur de ma part j'ai modifier mon code.double erreur le premier code étais "bon" ^^
    m
    0
    l
    29 Mai 2013 15:44:07

    L'erreur viens de If ((la_ligne.Cells(1, 6).Value >= Range("AQ" & i).Value) And (la_ligne.Cells(1, 7).Value <= Range("A" & i).Value)) Then
    devrais être "AR"

    NB : Je préfère la notation Cells(1,1) à Cells("A1")
    m
    0
    l
    29 Mai 2013 15:51:08

    Mais je suis a coté aujourd'hui, je retourne la formule dans tout les sens mais j'ai pas vu que il me manquais le R.

    Je vient de tester comme cela, ce coup ci plus rien ne s'écrit :/ 
    Même avec une mesure dont tout les capteurs sont possible.
    m
    0
    l
    29 Mai 2013 16:11:28

    Trouvé, un problème de notation, les valeurs des mesure qui sont exraitent d'un autre logiciel sont par exemple -60.000, il y a un point, alors que Excel a besoin d'une virgule.

    En utilisant ce code ci en plus:
    1. Range("A5:Q" & Derligne ).Select
    2. Selection.Replace What:=".", Replacement:=".", LookAt:=xlPart, _
    3. SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
    4. ReplaceFormat:=False


    par contre comment passer le format de cellule en nombre?
    m
    0
    l
    29 Mai 2013 16:19:41

    C'est bon en fait avant de trier mes mesure par type (question précédente dans le forum), j'utilise le morceaux de code ci dessus, cela remplace tout les points par des virgules, ensuite cela fonctionne très bien.
    Je vous remercie une fois de plus pour votre aide. =)
    m
    0
    l
    30 Mai 2013 07:34:59

    Ensuite, pour optimiser un peut, je déplacerais la ligne
    1. Derligne = (Sheets("TEMP").Cells(Rows.Count, 19).End(xlUp).Row + 1)
    en dehors de la boule et incrémenterais la variable dans la boucle.
    m
    0
    l
    30 Mai 2013 08:52:05

    Range(...).Select
    Selection.Replace ...

    grrrrr :fou:  :fou:  :fou: 
    m
    0
    l
    30 Mai 2013 09:01:22

    Bonjour,

    Oui Tantal, c'est vrai que Derligne n'a pas besoin d'être dans la boucle.

    Je sais Zeb, c'est pas bien d'utiliser Range(...).Select et Selection.Replace. Mais en cherchant sur le net les seuls morceaux de code me permettant de changer ces points en virgules, tout le monde propose cette macro :/ 
    J'ai pas trouvé sans.
    m
    0
    l
    30 Mai 2013 10:47:21

    Je voudrais copier les données de la_ligne dnas ma page "RESULTATS", J'ai essayer de faire ça:
    1. DerLigneMesure = (Sheets("RESULTATS").Cells(Rows.Count, 1).End(xlUp).Row + 1)
    2. la_ligne.Copy Destination:=Sheets("RESULTATS").Cells(DerLigneMesure, 1)

    En méttant Dim la_ligne As Range au dessus du sub dnas la macro de recherche capteur et dans ma macro Valider.

    Je sais aps si je fait bien pour partager la variable entre toute les macro, il me semblais avoir vu ca dans un cours. Ca serais le .Copy qui ne serais pas utilisable avec une variable?
    m
    0
    l

    Meilleure solution

    30 Mai 2013 11:54:28

    De retour de réunion... je réagis à [ulr=http://www.presence-pc.com/forum/id-2877590/vba-compare...]ce code[/url].
    Pour un grand débutant, c'est pas mal du tout. ;) 

    M'enfin, pourquoi êtes-vous enragés à utiliser des coordonnées ?
    En plus, pour écrire des "AQ" & i !!!
    Imagine que ton programme doive itérer des colonnes, tu ferais un For j = "A" To "AQ" ?
    En plus, il y a une TRES GRAVE ERREUR (mode paranoïaque ON) dans la déclaration de tes numéros de lignes.
    Une feuille, c'est au moins 65536 lignes (version 32bis)?. Tes Integers ne sont donc pas assez grands.
    (Bien que je doute que tu ais autant de données ;)  )

    Regarde, c'est tout bête :
    1. der_ligne = Worksheets("TEMP").Cells(Rows.Count, 19).End(xlUp)
    2.  
    3. For Each une_ligne In Worksheets("TEMP").Range(Worksheets("TEMP").Cells(5, 1), Worksheets("TEMP").Cells(Rows.Count, 44).End(xlUp)).Rows
    4. If la_ligne.Cells(6).Value >= une_ligne.Cells(43).Value And la_ligne.Cells(7).Value <= une_ligne.Cells(44).Value Then
    5. der_ligne.Offset(1)
    6. la_ligne.Range(la_ligne.Cells(38), la_ligne.Cells(55)).Copy Destination:=der_ligne.Cells(19)
    7. End If
    8. Next
    partage
    30 Mai 2013 11:57:50

    Range(...).Select
    Selection.Replace ...

    Ceci se réduit à :

    Range(...).Replace ...

    C'est facile quand même !

    L'intérêt ? Ne pas faire de sélection, qui est une opération TRES gourmande en ressource.
    Une sélection consiste à mettre le focus sur une cellule, une page, un classeur, et à recalculer TOUTE la feuille si nécessaire.
    Mets ça dans une boucle et c'est parti pour avoir besoin de ScreenUpdate !!!!

    Vu le niveau pour s'en passer, avoue que le jeu en vaut la chandelle !
    m
    0
    l
    30 Mai 2013 11:58:53

    Pour ton dernier code, essaie de faire directement avec des objets, pas des coordonnées.
    m
    0
    l
    31 Mai 2013 11:35:42

    Bonjour,

    J'ai modifié selon tes conseilles Zeb, pour le moment tout fonctionne correctement, je peaufine mes conditions pour que toute les mesures soit prise en compte.

    Un grand merci à vous deux, je reviendrais vers vous si jamais un problème se pose sur mon chemin, mais avec ce que vous m'avez donné je devrais me débrouille.

    Un grand merci. =)
    m
    0
    l
    31 Mai 2013 15:12:29

    Tantal et moi, nous nous partagerons les remerciements. :jap: 

    Moderator dixit : C'est à toi de nous départager. Pour la bonne tenue de ce forum, choisis la meilleure des solutions pour passer le statut du topic à "résolu".
    m
    0
    l
    31 Mai 2013 15:28:49

    Voila qui est fait, après pour la meilleure réponse j'ai mit ta dernière Zeb, mais si quelqu'un a besoin de ce genre de macro, lisez le topic en entier, les solutions sont dans chaque post =).

    Encore merci.
    m
    0
    l
    3 Juin 2013 14:45:07

    Lol. C'est en tant que modo que j'insistais sur la bonne tenue du forum !
    Ce pauvre Tantal fait 90% du boulot, moi je me pointe pour faire mon redresseur de tord, et bing, c'est pour bibi la bonne note.
    m
    0
    l