Recherche de résultas mutiples
Résoluccm81 Messages postés 11033 Statut Membre -
J'essaie de trouver une formule qui me permettrait d'identifier les différents résultats d'une recherche et selon ces résultats, rapporter une valeur(Texte) prédéterminée.
Par exemple: (Formule en col I dans mon échantillon ici-bas)
Si pour un même numéro de transit (col A) les valeurs en J pour les lignes qui suivent (lignes ayant en A la même valeur qu'en A2) sont "MLO" et "BOTH", la valeur rapportée en I devrait être "LOADED BOTH".
Mais il y a plus d'une possibilité:
- Les valeurs en J pourraient toutes être "MLO", alors la valeur rapportée en I devrait être "LOADED MLO"
- Les valeurs en J pourraient toutes être "WEL", alors la valeur rapportée en I devrait être "LOADED WEL"
- Les valeurs en J pourraient toutes être "BOTH", alors la valeur rapportée en I devrait être "LOADED BOTH"
- Et si il n'y a aucune autres lignes ayant en A la même valeur que A2, la valeur rapportée devrait être "BALLAST"
Voir lien: https://www.cjoint.com/c/EByocjJJJ4Z
Si je me suis mal expliquer, n'hésitez pas à me poser des questions.
Merci!
--
eLise
- Recherche de résultas mutiples
- Searcher moteur de recherche - Guide
- Recherche automatique des chaînes ne fonctionne pas - Guide
- Recherche photo - Guide
- Historique de recherche - Guide
- Resultas foot - Télécharger - Vie quotidienne
21 réponses
- 1
- 2
Le souci porte sur l’identification d’un identifiant de transit en colonne A et des statuts en colonne J, du texte à reporter en colonne I selon des règles.
Plusieurs règles s’appliquent: si aucune autre ligne ne partage le même transit, on obtient BALLAST; si toutes les valeurs en J valent MLO, WEL ou BOTH, on obtient LOADED MLO, LOADED WEL ou LOADED BOTH.
D'autres discussions ont proposé d'étendre le mécanisme via une fonction VBA qui lit le bloc de transits, compte les occurrences MLO, WEL et BOTH, puis déduit le libellé final.
En pratique, des ajustements ont été évoqués pour corriger des espaces ou des minuscules dans la colonne Section, et pour normaliser en majuscules afin d’assurer une correspondance fiable.
Il y a une situation que la fonction ne gère pas. Il s'agit des cas où il n'y a qu'une seule ligne pour un numéro de transit. Dans ces cas, il faudrait que la fonction retourne "BALLAST".
nbli = li2 - li1
If nbli = 0 Then f = "BALLAST": Exit Function
Set plageSec = ActiveSheet.Range(Cells(li1 + 1, coSec), Cells(li2, coSec))
Mais il doit rester des cas non traités
J'ai tenté de l'ajouter mais je ne m'y connais vraiment pas assez pour le faire.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre questionMerci beaucoup :-)
En modifiant ma formule de calcul du nombre total de BALLAST et LOADED par section (MLO & WEL) de cette façon:
NB.SI($I$2:$I$7392;"BALLAST MLO")+NB.SI($I$2:$I$7392;"BALLAST BOTH")+NB.SI.ENS($I$2:$I$7392;"LOADED WEL";$J$2:$J$7392;"BOTH")
j'allais chercher les transits BALLAST MLO manquants.
Bien sûr j'ai appliqué la même logique pour la section WEL.
Encore une fois, un gros merci! :-)
Finalement la fonction a besoin d'un petit ajustement.
Lorsqu'on retrouve "BOTH" en «J» pour la première ligne d'un numéro de transit (en «A»), la fonction doit repérer dans «J» les valeurs. Il y a pour certains numéros de transit plus d'une valeur («MLO», «WEL» & «BOTH»). Dans ces cas où il y a 2 ou 3 valeurs pour un même numéro de transit, la fonction devrait retourner «LOADED BOTH».
J'ai aucune idée comment ajuster la fonction pour qu'elle me donne ce résultat. Peux-tu m'aider?
Je crois que mon lien fonctionne encore: https://www.cjoint.com/?3Bypup2nzyX
Merci
https://www.cjoint.com/?3BBpvBPkIMC
Je pense que tu vas encore avoir des soucis avec cette fonction, on y verrait plus clair si tu détaillais de façon précise et complète en français tous les différents cas
Si Transit = 1 seule ligne alors f=BALLAST + Section
Si Tansit = "BOTH" alors ....
Cdlmnt
Si Transit TOUTES les lignes suivantes = "BOTH" alors f= "LOADED BOTH"
Si Transit des lignes suivantes = "MLO" alors f= "LOADED MLO"
Si Transit des lignes suivantes = "WEL" alors f= "LOADED WEL"
Si Transit des lignes suivantes = "MLO" et "WEL" alors f= "LOADED BOTH"
Pour t'aider à mieux comprendre je vais te mettre en contexte:
La première ligne d'un transit représente le trajet d'un navire. Son trajet peut être formé de 2 sections (MLO et WEL), ou d'une seule.
La cargaison du navire fait parfois le même trajet que le navire mais parfois non. Celle-ci peut transiter une seule section: MLO par exemple.
Ou une portion de la cargaison peut transiter une seule section (MLO) et une autre portion transitera l'autre section (WEL), ou encore les 2 sections. Tout ça pour un même navire.
Ce que j'essaie de déterminer pour chaque transit c'est si le navire était chargé (LOADED) pour MLO seulement, ou pour WEL seulement, ou pour les 2 sections, ou Vide (BALLAST).
La valeur de «J» pour la première ligne d'un transit est seulement utilisée comme référence quand le transit n'a qu'une seule ligne. Ceci signifie qu'il n'y avait pas de cargaison à bord. Alors si BOTH f="BALLAST BOTH"; si MLO f="BALLAST MLO", si WEL f="BALLAST WEL"
Autrement, ce sont les valeurs de "J" des lignes suivantes (lignes des cargaisons) qui déterminent les sections pour lesquelles le navire était chargé. Soit juste MLO, juste WEL ou les 2 (BOTH).
Est-ce que ça t'aide?
1. Si Transit = 1 seule ligne alors f=BALLAST + Section
donne
If nbli = 0 Then f = "BALLAST " & Section: Exit Function
2. Si Transit TOUTES les lignes suivantes = "BOTH" alors f= "LOADED BOTH"
Si Transit des lignes suivantes = "MLO" alors f= "LOADED MLO"
Si Transit des lignes suivantes = "WEL" alors f= "LOADED WEL"
donne
If nbli = b Then f = "LOADED BOTH": Exit Function
If nbli = m Then f = "LOADED MLO": Exit Function
If nbli = w Then f = "LOADED WEL": Exit Function
3. Si Transit des lignes suivantes = "MLO" et "WEL" alors f= "LOADED BOTH"
donne
f nbli = m + w Then f = "LOADED BOTH": Exit Function
Toute la prodédure
Const coSection = "J" Public Function f(cel As Range) As String Dim li1 As Long, li2 As Long, li As Long, Transit As Long, coTransit As Long, nbli As Long Dim plageSection As Range, Section As String, m As Long, b As Long, w As Long, nbSectionTransit As Long li1 = cel.Row Transit = cel.Value coTransit = cel.Column Section = ActiveSheet.Cells(li1, coSection) If cel.Offset(-1, 0) = Transit Then f = "": Exit Function li2 = li1 While ActiveSheet.Cells(li2, coTransit).Value = Transit li2 = li2 + 1 Wend li2 = li2 - 1 nbli = li2 - li1 If nbli = 0 Then f = "BALLAST " & Section: Exit Function Set plageSection = ActiveSheet.Range(Cells(li1 + 1, coSection), Cells(li2, coSection)) nbSectionTransit = Application.WorksheetFunction.CountIf(plageSection, Section) If nbSectionTransit = 0 Then f = "BALLAST": Exit Function b = Application.WorksheetFunction.CountIf(plageSection, "BOTH") m = Application.WorksheetFunction.CountIf(plageSection, "MLO") w = Application.WorksheetFunction.CountIf(plageSection, "WEL") If nbli = b Then f = "LOADED BOTH": Exit Function If nbli = m Then f = "LOADED MLO": Exit Function If nbli = w Then f = "LOADED WEL": Exit Function If nbli = m + w Then f = "LOADED BOTH": Exit Function End Function
Cdlmnt
donne
f nbli = b + m Then f = "LOADED BOTH": Exit Function
2.Si Transit des lignes suivantes = "BOTH" et "WEL" alors f= "LOADED BOTH"
donne
f nbli = b + w Then f = "LOADED BOTH": Exit Function
3.Si Transit des lignes suivantes = "BOTH" et "WEL" et "MLO" alors f= "LOADED BOTH"
donne
f nbli = b + w + m Then f = "LOADED BOTH": Exit Function
Je ne sais pas si l'ordre des sections dans chacune des possibilités est importante par exemple si MLO vient avant WEL dans l'ordre des lignes, ou BOTH vient avant WELL, etc...
post #11
Si Transit = 1 seule ligne alors f=BALLAST + Section
Si Transit TOUTES les lignes suivantes = "BOTH" alors f= "LOADED BOTH"
Si Transit des lignes suivantes = "MLO" alors f= "LOADED MLO"
Si Transit des lignes suivantes = "WEL" alors f= "LOADED WEL"
Et dans tous les autres cas post #17
"LOADED BOTH" ??
Si oui
Const coSection = "J" Public Function f(cel As Range) As String Dim li1 As Long, li2 As Long, li As Long, Transit As Long, coTransit As Long, nbli As Long Dim plageSection As Range, Section As String, m As Long, b As Long, w As Long, nbSectionTransit As Long li1 = cel.Row Transit = cel.Value coTransit = cel.Column Section = ActiveSheet.Cells(li1, coSection) If cel.Offset(-1, 0) = Transit Then f = "": Exit Function li2 = li1 While ActiveSheet.Cells(li2, coTransit).Value = Transit li2 = li2 + 1 Wend li2 = li2 - 1 nbli = li2 - li1 If nbli = 0 Then f = "BALLAST " & Section: Exit Function Set plageSection = ActiveSheet.Range(Cells(li1 + 1, coSection), Cells(li2, coSection)) nbSectionTransit = Application.WorksheetFunction.CountIf(plageSection, Section) b = Application.WorksheetFunction.CountIf(plageSection, "BOTH") m = Application.WorksheetFunction.CountIf(plageSection, "MLO") w = Application.WorksheetFunction.CountIf(plageSection, "WEL") If nbli = b Then f = "LOADED BOTH": Exit Function If nbli = m Then f = "LOADED MLO": Exit Function If nbli = w Then f = "LOADED WEL": Exit Function f = "LOADED BOTH": Exit Function End Function
Bonne soirée
Mai j'ai ensuite remplacé les "BOTH" des ligne de cargaison avec "MLO". Maintenant toutes les lignes de cargaison ont "MLO" et seule la première ligne du transit a "BOTH". J'ai recopié la fonction dans les cellules à nouveau et elle retourne encore "LOADED BOTH"
Est-ce que la fonction prend en considération la valeur de «J» de la première ligne lorsqu'il y a des lignes de cargaison? Si c'est le cas, ça expliquerait pourquoi elle retourne "LOADED BOTH" à la place de "LOADED MLO".
Il faudrait que la fonction ignore la première ligne lorsqu'il y a des lignes de cargaison dans un même transit.
Mais il faudrait qu'elle la prenne en considération lorsqu'il n'y a pas d'autres lignes que la première pour quelle soit en mesure de retourner "BALLAST" + Section.
Avec cette version, tu n'auras plus besoin de le faire
https://www.cjoint.com/?3BCr7WOxNgm
Y a t'il d'autres cas que ceux de mon fichier ?
Si oui, complètes-le avec les résultats attendus (et expliqués)
Cdlmnt
La modification que tu as apportée semble fonctionner. Il existe 3 autres possibilités de combinaison (que j'ai ajouté au fichier échantillon: 68249, 68300, 68000) mais la fonction telle qu'elle est semble bien les gérer.
https://www.cjoint.com/?ECcp0Xk97V5
Je vais tester encore un peu à partir d'un nouveau fichier avant de conclure.
Merci encore :-)
La dernière ligne traite les cas non envisagés plus haut dans le code, dont ces trois là font partie
If nbli = w Then f = "LOADED WEL": Exit Function
f = "LOADED BOTH": Exit Function
End Function
Cdlmnt
Je suis toujours à tester la fonction que tu as créée et j'ai constaté que si j'ai 2 classeurs ouverts en même temps, et que ces 2 classeurs ont cette fonction, un affecte l'autre. Comment puis-je faire pour que la fonction s'applique seulement à la feuille sur la quelle je travaille?
si j'ai 2 classeurs ouverts en même temps, et que ces 2 classeurs ont cette fonction, un affecte l'autre
Peut être essayer en ouvrant tes deux classeurs dans deux sessions différentes d'excel
2. Peux tu me donner un ordre de grandeur du nombre de lignes des tes classeurs
Au tout début j'avais ajouté la fonction au classeur Y.
En suite j'ai décidé de monter un fichier Maître (X) sur lequel j'allais ajouter la fonction mais aussi d'autres formules servant à fournir d'autres informations. Toutes ces informations sont compilées pour publier un rapport annuel. Je voulais créer un fichier Maître pour le prochain rapport annuel, question d'accélérer la publication du rapport en éliminant une multitude de vérifications manuelles.
Donc, ce qui se produit: si j'ai mon classeur X ouvert, et qu'ensuite j'ouvre mon classeur Y, devant mes propres yeux je vois les résultats de la colonne de la fonction dans le classeur X changés!
Chacun des fichiers de données sur lesquels je travails ont 7393 lignes. Chacun des 2 classeurs ont un nombre différent de feuilles.
Et la solution ne peut pas être d'ouvrir seulement un classeur. Il faut que je sois capable d'avoir les 2 ou même plus de classeurs d'ouvert en même temps.
Est-ce possible de transformer cette en fonction en macro reliée au classeur spécifiquement?
Ouvrir le premier classeur
Depuis le bureau, lancer excel et ouvrir le deuxième classeur
Dans le menu Fenetre tu ne dois voir qu'un seul classeur
2. Est-ce possible de transformer cette en fonction en macro reliée au classeur spécifiquement?
Oui, c'est pour ça que je t'ai demandé le nombre de lignes
3. Au passage j'ai besoin d'une précision
dans la colonne I (le résultat)
il y a par exemple 4 transit n° 67890, plage A2:A5,
le resultat
I2=LOADED MLO
I3, I4, I5 = vide
comme calculé par la fonction f de la macro
c'est bien ce que tu veux ? (1 seul résultat par transit sur la première ligne)
Tu dis
2. Pour ce qui est du nombre de ligne du fichier, celui-ci changera à chaque année, alors idéalement faudrait que la macro soit en mesure d'identifier la dernière ligne de données.
3. Tout à fait. Seule la première ligne d'un transit doit afficher le résultat de l'analyse de la fonction.
https://www.cjoint.com/?3CfuBF8MwsE
RQ. La colonne J ne comportant plus que des valeurs sur les premières lignes des transit, le fichier devrait être plus léger. Tu me dis ce que ça donne au niveau du temps d'exécution
Cdlmnt
1. Sur mon fichier ?
2. Lorsque tu es sur la ligne surlignée en jaune, mets la souris sur les variables coTra et li21
tu dois avoir coTra = A et li1 = 2
3. La variable transit est déclarée comme entier long (c'était bien des nombres en colonne A dans ton fichier), si chez toi c'est une chaine de caractères (du texte) , normal que ça plante. Si c'est ça, déclares là comme string (Tansit as string)
4. La colonne Transit est bien la colonne A ?
5. Chez moi, je n'ai pas cette erreur, je t'envoie la dernière version complétée, tu commences par essayer celle là et tu dis
https://www.cjoint.com/?3CgojnuSpHg
2. Lorsque tu es sur la ligne surlignée en jaune, mets la souris sur les variables coTra et li21 :: Voulais-tu dire coTra et li1 ? Si oui, j'ai coTra = "A" et li1 = 2
3. La variable transit est déclarée comme entier long (c'était bien des nombres en colonne A dans ton fichier), si chez toi c'est une chaine de caractères (du texte) , normal que ça plante. C'était format «Standard», pas «Text». Je l'ai maintenant changé au format «Nombre».
4. La colonne Transit est bien la colonne A ? Oui
On a des problème de téléchargement en ce moment alors j'attends d'avoir ton nouveau fichier.
Mais en attendant, la seule chose qui est différente dans mon fichier c'est que la colonne où se passe la macro est "AT". Le fichier échantillon devait être allégé alors beaucoup de colonnes et lignes ont été éliminées. Est-ce que ceci peut être la cause du problème? Est-ce que l'emplacement des résultats de la macro est considéré outre dans:
Const coTra = "A"
Const coSec = "J"
Const coVal = "I"
Const lideb = 2
Const coTra = "A"
Const coSec = "I"
Const coVal = "AT"
Const lideb = 3
Mais ça tu pouvais pas savoir. Et étant pas très connaissante en VBA, j'avais compris l'impact avant maintenant.
La macro s'exécute. Je dois maintenant voir si tous les résultats sont exacts.
Je te reviens.
Merci
Et qu'est ce que ça donne lors de l'exécution ?
RQ. Ce n'est pas en changeant le format de la colonne transit que tu vas changer la nature des objets qu'elle contient
La question : est ce que ce sont des nombres ou du texte
pour savoir, tu mets en format standard si ça se cale à droite ce sont des nombres, si ça se cale à gauche c'est du texte
La macro peut très bien fonctionner avec n'importe lequel des deux types, il suffit de le lui dire dans les déclarations
Dim Transit as long pour un entier, Dim Transit as string pour du texte
RQ. tu as aussi Dim Transit (sans préciser le type, donc type Variant pour excel, mais c'est moins propre)
2. Lorsque tu es sur la ligne surlignée en jaune, mets la souris sur les variables coTra et li21 :: Voulais-tu dire coTra et li1 ?
Si oui, j'ai coTra = "A" et li1 = 2
ça c'est correct, si du moins en colonne A tu as les transit et que la première ligne des données est 2
5. la colonne où se passe la macro est "AT".
que veux tu dire par là ?
que le résultat de la macro est en colonne AT ?
Le fichier échantillon devait être allégé alors beaucoup de colonnes et lignes ont été éliminées. Est-ce que ceci peut être la cause du problème?
Oui voir ci-dessous
Est-ce que l'emplacement des résultats de la macro est considéré outre dans
What ?
les colonnes de travail de la macro sont définies dans les constantes en début de code, ça permet justement d'éviter de toucher au code de la procédure en cas de changement de configuration dans la feuille
Const coTra = "A" ' colonne Transità toi de modifier les valeurs des constantes selon ta configuration
Const coSec = "J" ' colonne Section
Const coVal = "I" ' colonne Valeur rapportée
Const lideb = 2 ' première ligne des données
2. En analysant ta macro, j'ai compris que je devais changer «Const lideb = 2» à «Const lideb = 3» car le premier transit est sur la ligne 3 dans mon fichier.
Ceci étant dit, et-ce que ce changement engendre d'autres changements dans la macro?
5. Dans mon fichier la colonne des résultats est AT. Alors j'ai changé «Const coVal = "I"» à «Const coVal = "AT"». Et la macro s'est exécutée au bon endroit.
Mais les résultats ne sont pas exacts. Les seuls résultats apparaissant sont :
"BALLAST BOTH"
"BALLAST MLO"
"BALLAST WEL"
"LOADED BOTH"
De plus, le tout dernier transit en ligne 7393 n'a pas de résultat, comme si la macro s'était arrêtée avant 7392.
Ceci étant dit, et-ce que ce changement engendre d'autres changements dans la macro?
en principe non
6.1. Mais les résultats ne sont pas exacts. Les seuls résultats apparaissant sont :
"BALLAST BOTH"
"BALLAST MLO"
"BALLAST WEL"
"LOADED BOTH"
Là je ne vois pas, sur mon exemple j'ai tout ce qu'il faut
6. 2. De plus, le tout dernier transit en ligne 7393 n'a pas de résultat, comme si la macro s'était arrêtée avant 7392.
<= au lieu de < ici
While li2 <= lifin
Peux tu m'envoyer un bout de ton fichier au format excel 2003 avec tous les cas possibles
Tu fais un double-clic sur mon peudo et tu as "Lui envoyer un message"
Voici mon fichier dans son entièreté.
Dans la colonne AT tu trouveras les résultats que j'ai obtenus avec la macro. Mais ce fichier ne comporte pas la macro. Je voulais simplement te fournir le fichier avec toutes mes données.
Complètement en bas du fichier, colonne AR, il y a un tableau. Dans la première partie du tableau tu trouveras les totaux du fichier pour MLO, WEL et COMBINE. COMBINE étant tous, donc tous les LOADED (MOL + WEL + BOTH) et tous les BALLAST (MLO + WEL + BOTH). J'ai enlevé les formules mais se sont les totaux que j'ai obtenu selon la macro. Pour obtenir le total des transits LOADED MLO il faut additionner tous les LOADED MLO + LOADED BOTH;
pour WEL = LOADED WEL + LOADED BOTH;
pour COMBINE = LOADED MLO + LOADED WEL + LOADED BOTH. Même principe pour les BALLAST.
La deuxième partie contient les vrais résultats. C'est ce que le fichier (la macro) devrait me permettre de calculer. Ce sont les totaux véritables que nous avons obtenus avec notre vieille méthode.
Et la troisième partie montre la différence entre les deux.
https://www.cjoint.com/c/ECgvm65009l
C'est maintenant le week-end, alors à bon week-end et à lundi !
Merci encore :-)
- 1
- 2
Je ne sais pas pour quoi mais je n'arrive pas à faire fonctionner ta macro. J'ai enregistré le fichier avec extension .xlsm. Quand j'essaie de l'exécuter, je reçois un message me demandant un nom de macro.