Besoin d'aide pour un algo
Résolu
0z0z
Messages postés
108
Date d'inscription
Statut
Membre
Dernière intervention
-
0z0z Messages postés 108 Date d'inscription Statut Membre Dernière intervention -
0z0z Messages postés 108 Date d'inscription Statut Membre Dernière intervention -
Bonjour à tous,
J'ai un site en PHP dans le quel j'ai un tableau dont les données proviennent d'un fichier CSV.
Dans ce tableau j'affiche une liste d'article qui doit être fabriqué. Et il est très probable qu'un même article doivent être fabriqué plusieurs fois.
$lesColonnes[26] représente la quantité du produit.
$lesColonnes[22] représente la référence du produit.
Ce que je voudrais c'est rassembler les produits qui ont la même référence et faire un +1 pour la quantité.
J'avais penser faire un truc du genre :
Ligne 2 et 13 c'est ce que j'ai rajouté mais qui ne fonctionne pas biensur. Donc si vous avez une petite idée je suis preneuse. Merci.
J'ai un site en PHP dans le quel j'ai un tableau dont les données proviennent d'un fichier CSV.
Dans ce tableau j'affiche une liste d'article qui doit être fabriqué. Et il est très probable qu'un même article doivent être fabriqué plusieurs fois.
$lesColonnes[26] représente la quantité du produit.
$lesColonnes[22] représente la référence du produit.
Ce que je voudrais c'est rassembler les produits qui ont la même référence et faire un +1 pour la quantité.
J'avais penser faire un truc du genre :
echo "<table border='1'>\n"; $nb = 0; while(!feof($fp)) { $nb++; echo "<tr>"; $j = sizeof($ligne); // On récupère une ligne $Ligne = fgets($fp,1024); $lesColonnes = explode(";", $Ligne); $lesColonnes = str_replace('"','',$lesColonnes); $date = date("d/m/Y"); if ($lesColonnes[17] >= $date){ if ($lesColonnes[22].[$nb] = $lesColonnes[22].[$nb-1]) { // On affiche la ligne echo "<td>$lesColonnes[23]</td>"; echo "<td>$lesColonnes[22]</td>"; echo "<td>$lesColonnes[24]</td>"; echo "<td>$lesColonnes[25]</td>"; echo "<td>$lesColonnes[26]</td>"; echo "<td>$lesColonnes[17]</td>"; echo "</tr>"; } } } echo "</table>\n";
Ligne 2 et 13 c'est ce que j'ai rajouté mais qui ne fonctionne pas biensur. Donc si vous avez une petite idée je suis preneuse. Merci.
A voir également:
- Besoin d'aide pour un algo
- Algo prono - Télécharger - Sport
- ALGO ET PASCAL - Forum Pascal
- Algo du cheval - Forum Programmation
- Demande d'algo Mastermind - Forum Programmation
- Algo arbre/graph ✓ - Forum Programmation
37 réponses
Bonjour,
Si j'ai bien compris, tu peux faire une boucle pour préparer un tableau compacter qui aura le format que tu souhaite :
Dis moi si ce n'est pas ça que tu cherches, mais c'est ce que j'ai compris.
Si j'ai bien compris, tu peux faire une boucle pour préparer un tableau compacter qui aura le format que tu souhaite :
$lesColonnes_compact = array(); foreach($lesColonnes as $t) { if(isset($lesColonnes_compact[$t[22]]) $lesColonnes_compact[$t[22]][26]++; else $lesColonnes_compact[$t[22]]=$t; }
Dis moi si ce n'est pas ça que tu cherches, mais c'est ce que j'ai compris.
Bon en gros avec ce code :
J'obtiens un tabelau du genre :
nom_prod ; ref_prod ; quantité ; date
ex1 ; 001 ; 1 ; 18/02/10
ex1 ; 001 ; 1 ; 18/02/10
ex1 ; 001 ; 2 ; 25/02/10
ex2 ; 002 ; 1 ; 18/02/10
En gros je veux que mes deux première ligne deviennent :
ex1 ; 001 ; 2 ; 18/02/10
car elles on la même référence ainsi que la même date.
J'espère que mon explication est assez claire :/
$file = "...\nomFichier.csv"; $contenu = fopen ($file, "r") or die("Cannot open $file"); if (!$fp = fopen($file,"r")) { echo "Echec de l'ouverture du fichier"; exit; } else { echo "<table border='1'>\n"; while(!feof($fp)) { echo "<tr>"; $j = sizeof($ligne); // On récupère une ligne $Ligne = fgets($fp,1024); $lesColonnes = explode(";", $Ligne); $lesColonnes = str_replace('"','',$lesColonnes); $date = date("d/m/Y"); if ($lesColonnes[17] >= $date { // On affiche la ligne echo "<td>$lesColonnes[23]</td>"; echo "<td>$lesColonnes[22]</td>"; echo "<td>$lesColonnes[24]</td>"; echo "<td>$lesColonnes[25]</td>"; echo "<td>$lesColonnes[26]</td>"; echo "<td>$lesColonnes[17]</td>"; echo "</tr>"; } } echo "</table>\n"; fclose($fp); }
J'obtiens un tabelau du genre :
nom_prod ; ref_prod ; quantité ; date
ex1 ; 001 ; 1 ; 18/02/10
ex1 ; 001 ; 1 ; 18/02/10
ex1 ; 001 ; 2 ; 25/02/10
ex2 ; 002 ; 1 ; 18/02/10
En gros je veux que mes deux première ligne deviennent :
ex1 ; 001 ; 2 ; 18/02/10
car elles on la même référence ainsi que la même date.
J'espère que mon explication est assez claire :/
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Ca ne fonctionne pas ce que je t'ai donné ? j'ai l'impression que ca correspond bien à ce que tu veux faire, il faut juste que tu ajoutes le bout de code avant la création de ton table, et que tu utilises la variable $lesColonnes_compact pour la création de ton table.
echo "<table border='1'>\n"; while(!feof($fp)) { $lesColonnes_compact = array(); echo "<tr>"; $j = sizeof($ligne); // On récupère une ligne $Ligne = fgets($fp,1024); $lesColonnes = explode(";", $Ligne); $lesColonnes = str_replace('"','',$lesColonnes); $date = date("d/m/Y"); if ($lesColonnes[17] >= $date){ foreach($lesColonnes as $l) { if(isset($lesColonnes_compact[$l[22]]) $lesColonnes_compact[$l[22]][26]++; else $lesColonnes_compact[$l[22]]=$l; } // On affiche la ligne echo "<td>$lesColonnes_compact[23]</td>"; echo "<td>$lesColonnes_compact[22]</td>"; echo "<td>$lesColonnes_compact[24]</td>"; echo "<td>$lesColonnes_compact[25]</td>"; echo "<td>$lesColonnes_compact[26]</td>"; echo "<td>$lesColonnes_compact[17]</td>"; echo "</tr>"; } } echo "</table>\n";
Est-ce bien ce que tu me propose ?
Si c'est le cas voici le message d'erreur :
<br />
<b>Parse error</b>: syntax error, unexpected T_VARIABLE in <b>maPage.php</b> on line <b>28</b><br />
l.28 = $lesColonnes_compact[$l[22]][26]++;
Déjà je suis pas sur que cela fonctionne dans tous les cas :
$lesColonnes[17] >= $date
Comparer deux chaines de caractère c'est pas l'idéal, puis en plus tu réutilise la fonction date à chaque fois, ce qui est une perte de temps (négligeable j'avoue). Tu pourrais le faire qu'une fois au début, bref
Pour faire ce que tu veux, avant d'afficher les données extraites du fichier CSV, tu dois les enregistrer et les pré-traiter. donc :
Voilà qui est fait, a part petite négligence, ca devrait fonctionner. Par contre, pour la comparaison de date à corriger, je te suggère de repasser ca en timestamp pour comparer, ou même mieux, de stocker les timestamp directement dans le fichier CSV.
Edit : Il y avait une petite négligence -_-'
$lesColonnes[17] >= $date
Comparer deux chaines de caractère c'est pas l'idéal, puis en plus tu réutilise la fonction date à chaque fois, ce qui est une perte de temps (négligeable j'avoue). Tu pourrais le faire qu'une fois au début, bref
Pour faire ce que tu veux, avant d'afficher les données extraites du fichier CSV, tu dois les enregistrer et les pré-traiter. donc :
$file = "...\nomFichier.csv"; $contenu = fopen ($file, "r") or die("Cannot open $file"); if (!$fp = fopen($file,"r")) { echo "Echec de l'ouverture du fichier"; exit; } else { $conteneur = Array(); $date = date("d/m/Y"); while(!feof($fp)) { $ligne = fgets($fp,1024); $colonne = explode(";", $ligne); $colonne = str_replace('"','',$colonne); if ($colonne[17] >= $date { // à corriger je suppose $conteneur[] = Array( $colonne[23], // 0 $colonne[22], // 1 référence $colonne[24], // 2 $colonne[25], // 3 $colonne[26], // 4 quantité $colonne[17] // 5 ); // là j'ai toutes les données dans un tableau } } fclose($fp); $passe = Array(); // tableau pour mettre les références déjà passées echo "<table border='1'>\n"; foreach ($conteneur as $colonne1) { $actuel = $colonne1[1]; if (!in_array($actuel, $passe)) { $quantite = 0; foreach ($conteneur as $colonne2) { if ($colonne2[1] == $actuel) $quantite += $colonne2[4]; } echo "<tr>"; for ($i = 0; $i<6; $i++) { echo "<td>$colonne1[$i]</td>"; } echo "</tr>"; $passe[] = $actuel; } } echo "</table>\n"; }
Voilà qui est fait, a part petite négligence, ca devrait fonctionner. Par contre, pour la comparaison de date à corriger, je te suggère de repasser ca en timestamp pour comparer, ou même mieux, de stocker les timestamp directement dans le fichier CSV.
Edit : Il y avait une petite négligence -_-'
Non, en fait j'avais pas vu comment tu remplissais ton tableau, ma solution s'applique si tu as un tableau avec toute les lignes que tu veux afficher :
Ca devrait être mieux ^^
// Recupération des colonnes dans un tableau while(!feof($fp)) { $lesColonnes_compact = array(); echo "<tr>"; $j = sizeof($ligne); // On récupère une ligne $Ligne = fgets($fp,1024); $lesColonnes = str_replace('"','',$Ligne); $lesColonnes[] = explode(";", $lesColonnes); } // Compactage des colonnes foreach($lesColonnes as $t) { if(isset($lesColonnes_compact[$t[22]]) $lesColonnes_compact[$t[22]][26]++; else $lesColonnes_compact[$t[22]]=$t; } // Affichage du tableau echo "<table border='1'>\n"; foreach($lesColonnes_compact as $c) { $date = date("d/m/Y"); if ($c[17] >= $date) { // On affiche la ligne echo "<td>$c[23]</td>"; echo "<td>$c[22]</td>"; echo "<td>$c[24]</td>"; echo "<td>$c[25]</td>"; echo "<td>$c[26]</td>"; echo "<td>$c[17]</td>"; echo "</tr>"; } } echo "</table>\n";
Ca devrait être mieux ^^
Moi j'aimerais bien savoir, c'est quoi ce truc de fou ?
foreach($lesColonnes as $t) {
if(isset($lesColonnes_compact[$t[22]])
$lesColonnes_compact[$t[22]][26]++;
else
$lesColonnes_compact[$t[22]]=$t;
}
ZOOM : [$t[22]]
(Par rapport à mon code, j'aurais pu économiser de la mémoire en vérifiant directement lors de la récupération de données depuis le fichier si j'avais déjà vu la référence, avec un autre système)
(Enfin je dis ca, ca sert à rien, mais puisque on est dans l'algorithmique, ...)
foreach($lesColonnes as $t) {
if(isset($lesColonnes_compact[$t[22]])
$lesColonnes_compact[$t[22]][26]++;
else
$lesColonnes_compact[$t[22]]=$t;
}
ZOOM : [$t[22]]
(Par rapport à mon code, j'aurais pu économiser de la mémoire en vérifiant directement lors de la récupération de données depuis le fichier si j'avais déjà vu la référence, avec un autre système)
(Enfin je dis ca, ca sert à rien, mais puisque on est dans l'algorithmique, ...)
J'ai testé les deux solutions très rapidement mais apparement il y a un problème à chaque fois.
Defouille : il me met encore la même erreur pour $lesColonnes_compact[$l[22]][26]++;
Blocks : le problème survient à la sortie du while
Je dois quitter le bureau pour aujourd'hui mais je regarderai ca de plus près demain. Je vous remercie tout les deux.
Defouille : il me met encore la même erreur pour $lesColonnes_compact[$l[22]][26]++;
Blocks : le problème survient à la sortie du while
Je dois quitter le bureau pour aujourd'hui mais je regarderai ca de plus près demain. Je vous remercie tout les deux.
Ok Defouille je vois ce que tu as voulu faire. Joli d'ailleurs le tableau associatif
Juste ca :
foreach($lesColonnes_compact as $c)
Faudrait l'adapter à un tableau associatif, de même que le reste
Et Ozoz, dans ton message, tu as écrit ca :
$lesColonnes_compact[$l[22]][26]++
ZOOM X2 : $l[22]][26]
ZOOM X4 : $l
C'est pas un "l" dans le code de Defouille -_-...
Pour Ozoz, j'ai édité mon code après, peut-être l'as tu utilisé quand il était faux :/.
Juste ca :
foreach($lesColonnes_compact as $c)
Faudrait l'adapter à un tableau associatif, de même que le reste
Et Ozoz, dans ton message, tu as écrit ca :
$lesColonnes_compact[$l[22]][26]++
ZOOM X2 : $l[22]][26]
ZOOM X4 : $l
C'est pas un "l" dans le code de Defouille -_-...
Pour Ozoz, j'ai édité mon code après, peut-être l'as tu utilisé quand il était faux :/.
Bonjour Blocks et Defouille.
Ce matin j'ai rééssayer les codes que vous m'avez fournit hier mais j'ai toujours les mêmes erreurs.
Blocks :
C'est pas un "l" dans le code de Defouille -_-...
J'avais des "l" partout au lieu des "t" donc ca n'était pas un soucis mais j'ai quand même essayé avec "t" et j'ai la même erreur.
Pour la solution que tu as édité l'erreur est toujours au même au endroit. C'est-à-dire à la fermeture du while " }; ".
Ce matin j'ai rééssayer les codes que vous m'avez fournit hier mais j'ai toujours les mêmes erreurs.
Blocks :
C'est pas un "l" dans le code de Defouille -_-...
J'avais des "l" partout au lieu des "t" donc ca n'était pas un soucis mais j'ai quand même essayé avec "t" et j'ai la même erreur.
Pour la solution que tu as édité l'erreur est toujours au même au endroit. C'est-à-dire à la fermeture du while " }; ".
Bon et bien j'ai trouvé une solution. Je vous l'expose :
Blocks je suis quand même intéressée par ta solution donc si tu vois d'où vient le problème j'aimerai bien savoir aussi :)
$file = "...\nomFichier.csv"; $contenu = fopen ($file, "r") or die("Cannot open $file"); if (!$fp = fopen($file,"r")) { echo "Echec de l'ouverture du fichier"; } else { $conteneur = Array(); $date = '17/02/10'; $resultats = array(); while(!feof($fp)) { // On récupère une ligne $colonnes = fgetcsv($fp, 1024, ';'); if ($colonnes[17] >= $date){ // on indexe les résultats sur la reference if (isset($resultats[$colonnes[22]])) { //si le produit est déjà référencé on ajoute la quantité à la quantité existante $resultats[$colonnes[22]]['quantite'] += $colonnes[26]; } else { //sinon on crée la ligne pour le produit $resultats[$colonnes[22]] = array('rayon-ref' => $colonnes[23], 'codif-acheteur' => $colonnes[22], 'codif-fournisseur' => $colonnes[24], 'libelle' => $colonnes[25], 'quantite' => $colonnes[26], 'date' => $colonnes[17]); } } } //on affiche les résultats echo '<table border=1>'; foreach ($resultats as $ligne) { echo '<tr>' .'<td>'.$ligne['rayon-ref'].'</td>' .'<td>'.$ligne['codif-acheteur'].'</td>' .'<td>'.$ligne['codif-fournisseur'].'</td>' .'<td>'.$ligne['libelle'].'</td>' .'<td>'.$ligne['quantite'].'</td>' .'<td>'.$ligne['date'].'</td>' .'</tr>'; } echo '</table>'; }
Blocks je suis quand même intéressée par ta solution donc si tu vois d'où vient le problème j'aimerai bien savoir aussi :)
Ah je viens de refaire des tests et enfaite il s'avère que ma solution n'est pas tout à fait optimiser.
Quand un même produit est a fabriquer pour deux dates différentes il me les rassemble. Or moi je veux bien distinguer les dates de fabrication :/
Quand un même produit est a fabriquer pour deux dates différentes il me les rassemble. Or moi je veux bien distinguer les dates de fabrication :/
Bah enfaite celui que j'ai a un tout petit problème.
Donc si ta solution pouvais m'éviter ce problème ou bien si tu vois d'où vient mon problème ca serait parfait :)
Donc si ta solution pouvais m'éviter ce problème ou bien si tu vois d'où vient mon problème ca serait parfait :)
Quand un même produit est a fabriquer pour deux dates différentes il me les rassemble. Or moi je veux bien distinguer les dates de fabrication :/
Ha d'accord ... Je viens de comprendre
Tu as ca :
RFGJ 28/03/10 1
RFGJ 22/04/10 2
RFGJ 22/04/10 1
RFGJ 22/04/10 1
RFHD 12/03/10 1
Et tu veux que ca devienne :
RFGJ 28/03/10 1
RFGJ 22/04/10 4
RFHD 12/03/10 1
?
Donc séparer par la référence, ET les dates ?
PS : Je voudrais aussi juste savoir si le système de comparaison des dates fonctionnes
car en gros tu dis :
si : "12/05/10" < "21/07/09" et donc c'est un peu n'importe quoi (sur un mois tu dois pas voir le problème, mais sur plusieurs mois tu auras des bugs je suppose)
Ha d'accord ... Je viens de comprendre
Tu as ca :
RFGJ 28/03/10 1
RFGJ 22/04/10 2
RFGJ 22/04/10 1
RFGJ 22/04/10 1
RFHD 12/03/10 1
Et tu veux que ca devienne :
RFGJ 28/03/10 1
RFGJ 22/04/10 4
RFHD 12/03/10 1
?
Donc séparer par la référence, ET les dates ?
PS : Je voudrais aussi juste savoir si le système de comparaison des dates fonctionnes
car en gros tu dis :
si : "12/05/10" < "21/07/09" et donc c'est un peu n'importe quoi (sur un mois tu dois pas voir le problème, mais sur plusieurs mois tu auras des bugs je suppose)
Pour être exacte j'ai ca :
Référence Quantité Expé au + tard
L0023 18 11/03/10
L0015 22 11/03/10
L0007 8 11/03/10
Et je voudrais avoir ca :
Référence Quantité Expé au + tard
L0023 9 11/03/10
L0007 8 11/03/10
L0015 5 11/03/10
L0023 9 18/03/10
L0015 17 18/03/10
Enfaite si la référence est la même, il me les rassemble à la date au plus tôt. Et moi je ne veux pas qu'il me les rassemble mais qui me les laisse bien distinct.
Vois tu ce que je veux dire ?
Pour la comparaison des dates pour l'instant tout ce fait sur un seul mois. Je n'ai pas eu l'occasion de faire le test pour quand il y a plusieurs mois. Que proposerais tu pour arranger cela ?
Référence Quantité Expé au + tard
L0023 18 11/03/10
L0015 22 11/03/10
L0007 8 11/03/10
Et je voudrais avoir ca :
Référence Quantité Expé au + tard
L0023 9 11/03/10
L0007 8 11/03/10
L0015 5 11/03/10
L0023 9 18/03/10
L0015 17 18/03/10
Enfaite si la référence est la même, il me les rassemble à la date au plus tôt. Et moi je ne veux pas qu'il me les rassemble mais qui me les laisse bien distinct.
Vois tu ce que je veux dire ?
Pour la comparaison des dates pour l'instant tout ce fait sur un seul mois. Je n'ai pas eu l'occasion de faire le test pour quand il y a plusieurs mois. Que proposerais tu pour arranger cela ?
Un instant je vais essayer de l'améliorer et de trouver la faille (je peux pas vraiment l'essayer puisque j'ai pas de fichier CSV sous la main :p)
EDIT : Message 11 :
Faudrait l'adapter à un tableau associatif, de même que le reste
Je corrige, Defouille, ta syntaxe est bonne, je regarderais la prochaine fois (quoi que tu n'as même pas protesté U.u)
EDIT : Message 11 :
Faudrait l'adapter à un tableau associatif, de même que le reste
Je corrige, Defouille, ta syntaxe est bonne, je regarderais la prochaine fois (quoi que tu n'as même pas protesté U.u)