Résolu VBA-Comparer une ligne à plusieurs autres sur deux cellules

  • Auteur de la discussion LightenTriff
  • Date de début

LightenTriff

Habitué
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:

Code:
Selection.AdvancedFilter _
Action:=xlFilterCopy, _
CriteriaRange:=Range("F5:G5"), _
CopyToRange:=Range("S5:AJ5"), _
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 =)
 

zeb

Modérateur
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 :
Code:
Sub ma_fonction()
    Dim la_ligne As Range

    ' // On met ce qui est actif dans une variable, dès le début. '
    ' // Comme ça, si la sélection change, on l'aura quand même en mémoire.
    Set la_ligne = Selection.EntireRow
    If la_ligne.Rows.Count > 1 Then
        MsgBox "Veuillez ne sélectionner qu'une seule ligne.", vbCritical
        Exit Sub
    End If

    MsgBox "Ligne choisie : " & la_ligne.Rows(1).Row, vbInformation

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 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...
 

LightenTriff

Habitué
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.
 

tantal_fr

Grand Maître
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

 

tantal_fr

Grand Maître
Autre question, est-ce-que c'est :

F => AQ et G <= AR
ou
F => AQ ou G <= AR
 

LightenTriff

Habitué
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.
 

LightenTriff

Habitué
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.

Code:
 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?
 

LightenTriff

Habitué
J'ai fait des tests avec la macro suivante:

Code:
Sub Temp()

Dim la_ligne As Range
Dim i        As Integer
Dim Derligne As Integer

'Récupération de la ligne de mesure voulut dans une variable
Set la_ligne = Selection.EntireRow
    If la_ligne.Rows.Count > 1 Then
        MsgBox "Veuillez sélectionner qu'une seule ligne", vbCritical
        Exit Sub
    End If
    MsgBox "Ligne choisie:" & la_ligne.Rows(1).Row, vbInformation
    
'Nettoyage de la plage de cellules Résultats
Range("S5", "AJ55000").Select
Selection.ClearContents
Selection.Interior.ColorIndex = xlColorIndexNone

'Recherche des capteurs compatible avec la mesure
For i = 5 To Sheets("TEMP").Cells(Rows.Count, 38).End(xlUp).Row
    If ((la_ligne.Cells(0, 6).Value >= Range("AQ" & i).Value) And (la_ligne.Cells(0, 7).Value <= Range("A" & i).Value)) Then
        Derligne = (Sheets("TEMP").Cells(Rows.Count, 19).End(xlUp).Row + 1)
        Sheets("TEMP").Range(Cells(i, 38), Cells(i, 55)).Copy Destination:=Sheets("TEMP").Cells(Derligne, 19)
    End If
Next
MsgBox "Recherche Terminée", vbInformation
        
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?
 

tantal_fr

Grand Maître
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
Code:
'Nettoyage de la plage de cellules Résultats
Range("S5", "AJ55000").Select
Selection.ClearContents
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") :
Code:
'Nettoyage de la plage de cellules Résultats
Range(Cells(5, 19), Cells(5, 36).End(xlDown)).Delete
' sinon : Range(Cells(5, 19), Cells(55000, 36)
 

LightenTriff

Habitué
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
 

tantal_fr

Grand Maître


[strike]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). [/strike]
Erreur de ma part, j'ai oublié le Shift:=xlShiftUp dans
Code:
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]
 

LightenTriff

Habitué
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.
 

LightenTriff

Habitué
Voici

Code:
Sub Temp()
 
Dim la_ligne As Range
Dim i        As Integer
Dim Derligne As Integer
 
'Récupération de la ligne de mesure voulut dans une variable
Set la_ligne = Selection.EntireRow
    If la_ligne.Rows.Count > 1 Then
        MsgBox "Veuillez sélectionner qu'une seule ligne", vbCritical
        Exit Sub
    End If
    MsgBox "Ligne choisie:" & la_ligne.Rows(1).Row, vbInformation
 
'Nettoyage de la plage de cellules Résultats
Range(Cells(5, 19), Cells(5, 36).End(xlDown)).Delete Shift:=xlShiftUp

 
'Recherche des capteurs compatible avec la mesure
For i = 5 To Sheets("TEMP").Cells(Rows.Count, 38).End(xlUp).Row
    If ((la_ligne.Cells(1, 6).Value >= Range("AQ" & i).Value) And (la_ligne.Cells(1, 7).Value <= Range("A" & i).Value)) Then
        Derligne = (Sheets("TEMP").Cells(Rows.Count, 19).End(xlUp).Row + 1)
        Sheets("TEMP").Range(Cells(i, 38), Cells(i, 55)).Copy Destination:=Sheets("TEMP").Cells(Derligne, 19)
    End If
Next
MsgBox "Recherche Terminée", vbInformation
 
End Sub

[strike]Edit: petite erreur de ma part j'ai modifier mon code.[/strike]double erreur le premier code étais "bon" ^^
 

tantal_fr

Grand Maître
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")
 

LightenTriff

Habitué
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.
 

LightenTriff

Habitué
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:
Code:
Range("A5:Q" & Derligne ).Select  
    Selection.Replace What:=".", Replacement:=".", LookAt:=xlPart, _  
       SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _  
       ReplaceFormat:=False

par contre comment passer le format de cellule en nombre?
 

LightenTriff

Habitué
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. =)
 

tantal_fr

Grand Maître
Ensuite, pour optimiser un peut, je déplacerais la ligne
Code:
Derligne = (Sheets("TEMP").Cells(Rows.Count, 19).End(xlUp).Row + 1)
en dehors de la boule et incrémenterais la variable dans la boucle.
 

zeb

Modérateur
Range(...).Select
Selection.Replace ...

grrrrr :fou: :fou: :fou:
 
Vous devez vous inscrire ou vous connecter pour répondre ici.
Derniers messages publiés
Statistiques globales
Discussions
730 098
Messages
6 717 065
Membres
1 586 286
Dernier membre
petitangebleu1977
Partager cette page
Haut