Problème conversion champ en longueur fixe

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Problème conversion champ en longueur fixe

Re: Problème conversion champ en longueur fixe

par sirakawa » 13 mars 2012, 11:54

Oui, on comprend mieux, car Cobol gère des fichiers à longueur d'enregistrement fixe du genre :
nom : longueur 20 caractères...
age : 3 caractères
ce qui fait que pour eux, lire tes productions est un jeu d'enfant.
amuse-toi à regarder à quoi tu échappes:
http://www.csis.ul.ie/cobol/examples/Se ... QWRITE.htm

Re: Problème conversion champ en longueur fixe

par roseline » 13 mars 2012, 10:56

:-) Merci, je testerai tout cela dès que je recevrai le fichier!

Mais ce n'est pas par sadisme que je ne reçois pas les infos de l'interlocuteur, c'est juste qu'il travail en cobol :-(
Donc, j'suis pas très sûr que cela me servirait à grand chose ;-)

A tout bientôt

Re: Problème conversion champ en longueur fixe

par sirakawa » 12 mars 2012, 21:39

Avant toute réponse, il est urgent de voir le fichier modifié retourné.
S'il est, absurdement, sans délimiteur, il est évident que l'interlocuteur possède un moyen de le coder/décoder, et on se demande bien par quel sadisme il pourrait refuser de le communiquer.
Sinon des

Code : Tout sélectionner

substr
bien paramétrés devraient suffire à saucissoner la chose, en n'oubliant pas que cet imbécile de PHP réussit l'exploit de rendre le nombre exact de caractères par la fonction

Code : Tout sélectionner

strlen()
, et de démarrer à 0 son

Code : Tout sélectionner

substr(
), sachant que là 0 est le premier caractère, et que, pendant qu'on y est, au lieu de disposer d'un false et d'un true qui ne risquent pas de se confondre avec d'autres valeurs, il a un false qui vaut 0; donc

Code : Tout sélectionner

strpos
retourne un "vrai" 0 quand la chaîne cherchée se trouve au début de la chaîne explorée, et un 0 booléen quand elle n'est pas trouvée.
(note à l'adresse des experts : je connais !== et ===)
La lecture de Jarry est moins troublante et plus cohérente.
Php n'est pas le seul à être zéroiste; ça montre simplement que tous ces langages ignorent en réalité les besoins de traitement de chaînes de caractères.

Re: Problème conversion champ en longueur fixe

par roseline » 12 mars 2012, 19:39

C'est vrai que je ne trouve pas cela très logique, mais je dois en effet fournir un fichier txt sans aucun espace ou symbole, seul la longueur des champs détermine de quoi il s'agit (d'où l'importance du sprintf!).

Bon, ce qui va être sympa, c'est que je vais devoir faire le "retour".... je vais recevoir mon fichier txt qui aura été "traité" et modifié, et il faudra que je l'injecte dans la table ;-)

J'en profite :-)
Quelle serait la fonction inverse?
Une idée?

Bonne soirée et encore merci pour vos lumières

Re: Problème conversion champ en longueur fixe

par sirakawa » 12 mars 2012, 19:15

Dans mon innocence, je croyais que les fichiers au format C(omma)S(eparated)V(alue) comportaient des lignes dont les diverses données étaient séparées par un symbole, dans la version primitive, la virgule, maintenant virgule, point-virgule, deux points, tabulation, j'en passe et des pires.
Mais peut-être me trompetté-je...

Re: Problème conversion champ en longueur fixe

par roseline » 12 mars 2012, 19:06

Hi hi, cela fait du bien de repartir à zéro!

Voici le code qui fonctionne comme je le souhaite :-)
... et j'ai même réussi à mettre un sprintf supplémentaire.

Pour ceux qui souhaite:
La base de l'export est
880700000008783020.0012341001CH
880700000056547010.005486859791001CH
Le résultat est
8807000000087830000002000U00000012341001CH
8807000000565470000001000U05486859791001CH

<?php
include "config.inc.php";

// la variable qui va contenir les données CSV
$outputCsv = '';

///////////////////////// VALEURS Society ET SiteCode A CHANGER ////////////////////////////////////
$requete = "SELECT CheckID, CheckValor, StatutID, CustomerNumber, Society, SiteCode, SiteCountry FROM base WHERE StatutID = 'U' AND Society = '1' AND SiteCode = '000' AND SiteCountry = 'CH'";
$sql = mysql_query($requete);
if(mysql_num_rows($sql) > 0)
{
$i = 0;

while($Row = mysql_fetch_array($sql))
{
$i++;

$ID = $Row[CheckID];
$val = sprintf('%09u',$Row[CheckValor]*100);
$statut = $Row[StatutID];
$cnumber = sprintf('%010u',$Row[CustomerNumber]);
$soc = $Row[Society];
$code = $Row[SiteCode];
$country = $Row[SiteCountry];

$outputCsv .= "$ID$val$statut$cnumber$soc$code$country\n";

}

}
else
exit('');

/// DONNEES
$Date= date("Y-m-j H:i:s");


/// Ecriture du fichier
header("Content-disposition: attachment; filename=\"ACH0001".date("YmdHis").".txt\"");
header("Content-Type: application/force-download");
header("Content-Transfer-Encoding: application/vnd.ms-excel\n");
header("Pragma: no-cache");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0, public");
header("Expires: 0");

echo $outputCsv;
exit();
?>

Re: Problème conversion champ en longueur fixe

par roseline » 12 mars 2012, 18:14

Oui, je vais reprendre tranquillement le tout depuis le début....
Merci :-)

Re: Problème conversion champ en longueur fixe

par Calimero » 12 mars 2012, 13:28

L'instruction foreach() n'a rien à faire là-dedans, tu te situes déjà dans un while.

N'hésite pas à repartir du code initial si besoin et de comparer les structures. Tu as fait beaucoup de modifications (certaines hasardeuses) qui expliquent certainement ton problème.

Re: Problème conversion champ en longueur fixe

par roseline » 11 mars 2012, 14:29

:-( Ben oui, bien sûr!

Par contre, j'essaye de le mettre à différents endroits, et le fichier ne se génère toujours pas :-(
J'ai essayé après le $i = 0;
Après le $i++;

J'en suis là.....

<?php
$UserID = $_GET['UserID'];
?>
<?php
include "config.inc.php";

// la variable qui va contenir les données CSV
$outputCsv = '';

///////////////////////// VALEURS Society ET SiteCode A CHANGER ////////////////////////////////////
$requete = "SELECT CheckID, CheckValor, StatutID, CustomerNumber, Society, SiteCode, SiteCountry FROM base WHERE StatutID = 'U' AND Society = '1' AND SiteCode = '000' AND SiteCountry = 'CH'";
$sql = mysql_query($requete) or die(mysql_error());
if(mysql_num_rows($sql) > 0)
{
$i = 0;

while($row = mysql_fetch_array($sql))
{

$i++;

// On parcours $Row et on ajout chaque valeur à cette ligne
foreach($row)
$CheckID = $row['CheckID'];
//// travail sur la valeur du chèque
$val = $row['CheckValor'];
$valeurcheque = sprintf('%09u', $val*100);
//// fin travail
$StatutID = $row['StatutID'];
$CustomerNumber = $row['CustomerNumber'];
$Society = $row['Society'];
$SiteCode = $row['SiteCode'];
$SiteCountry = $row['SiteCountry'];

$valeur = ($CheckID, $valeurcheque, $StatutID, $CustomerNumber, $Society, $SiteCode, $SiteCountry);

$outputCsv .= trim($valeur).'';

// Suppression du ; qui traine à la fin
$outputCsv = rtrim($outputCsv, '');

// Saut de ligne
$outputCsv .= "\n";

}

}
else
exit('');

/// DONNEES
$Date= date("Y-m-j H:i:s");


/// Ecriture du fichier
header("Content-disposition: attachment; filename=\"ACH0001".date("YmdHis").".txt\"");
header("Content-Type: application/force-download");
header("Content-Transfer-Encoding: application/vnd.ms-excel\n");
header("Pragma: no-cache");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0, public");
header("Expires: 0");

echo $outputCsv;
exit();
?>

Re: Problème conversion champ en longueur fixe

par Calimero » 11 mars 2012, 00:12

@roseline : tu as entré ton nouveau code entre le while(...) et l'accolade ouvrante {. Ceci expliquant cela.

Re: Problème conversion champ en longueur fixe

par roseline » 10 mars 2012, 17:03

Ok, je comprend bien la raison des deux propositions que vous me donner :-)
Perso, en effet, la solution "simple" me suffit.

Par contre, je n'arrive pas à l'intégrer à mon script :-(
J'ai vu qu'il fallait que je change mysql_fetch_assoc en mysql_fetch_array si je veux travailler sur un champ.
Est-ce bien juste?

Voici mon script corrigé; mais du coup, je n'ai plus de fichier txt qui se génère :-(
Merci encore pour votre aide!

<?php
$UserID = $_GET['UserID'];
?>
<?php
include "config.inc.php";

// la variable qui va contenir les données CSV
$outputCsv = '';

///////////////////////// VALEURS Society ET SiteCode A CHANGER ////////////////////////////////////
$requete = "SELECT CheckID, CheckValor, StatutID, CustomerNumber, Society, SiteCode, SiteCountry FROM base WHERE StatutID = 'U' AND Society = '1' AND SiteCode = '000' AND SiteCountry = 'CH'";
$sql = mysql_query($requete) or die(mysql_error());
if(mysql_num_rows($sql) > 0)
{
$i = 0;

while($row = mysql_fetch_array($sql))
$CheckID = $row['CheckID'];
//// travail sur la valeur du chèque
$val = $row['CheckValor'];
$valeurcheque = sprintf('%09u', $val*100);
//// fin travail
$StatutID = $row['StatutID'];
$CustomerNumber = $row['CustomerNumber'];
$Society = $row['Society'];
$SiteCode = $row['SiteCode'];
$SiteCountry = $row['SiteCountry'];

$valeur = ($CheckID, $valeurcheque, $StatutID, $CustomerNumber, $Society, $SiteCode, $SiteCountry);

{
$i++;

// On parcours $Row et on ajout chaque valeur à cette ligne
foreach($row)
$outputCsv .= trim($valeur).'';

// Suppression du ; qui traine à la fin
$outputCsv = rtrim($outputCsv, '');

// Saut de ligne
$outputCsv .= "\n";

}

}
else
exit('');

/// DONNEES
$Date= date("Y-m-j H:i:s");


/// Ecriture du fichier
header("Content-disposition: attachment; filename=\"ACH0001".date("YmdHis").".txt\"");
header("Content-Type: application/force-download");
header("Content-Transfer-Encoding: application/vnd.ms-excel\n");
header("Pragma: no-cache");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0, public");
header("Expires: 0");

echo $outputCsv;
exit();
?>

Re: Problème conversion champ en longueur fixe

par Calimero » 10 mars 2012, 03:24

C'est pour cette raison qu'il faudrait donner, en toute circonsance, la préférence à une méthode qui résolve le cas général, même si le problème au départ est un cas particulier. Rien ne dit que l'évolution ne créera pas un cas particulier non prévu.
On s'éviterait de devoir après coup ajouter une profusion de lignes de code pour éliminer les cas qu'on n'avait pas prévus...
Oui, ton code est plus générique et bullet-proof que le mien. Le mien a, en revanche, l'avantage de la concision et de la maintenabilité, qui peuvent aussi être des paramètres pertinents (et sur ce dernier point, je n'ai jamais été vraiment content des codes que j'ai pu produire qui utilisaient str_pad(), c'est pourquoi je proposais ici une approche alternative employant sprintf() qui peut parfois jouer le même rôle avantageusement, si on prend toutefois le temps d'en découvrir la syntaxe).

Pour ce qui est de la multiplication, j'avoue volontiers une petite prise de risque que tu as bien relevée, mais éclairée par mon expérience personnelle et une lecture attentive du post initial (100.00 + traitement fichiers texte). Le mieux est parfois l'ennemi du bien, comme on dit :)

Re: Problème conversion champ en longueur fixe

par sirakawa » 09 mars 2012, 22:44

C'est pour cette raison qu'il faudrait donner, en toute circonsance, la préférence à une méthode qui résolve le cas général, même si le problème au départ est un cas particulier. Rien ne dit que l'évolution ne créera pas un cas particulier non prévu.
On s'éviterait de devoir après coup ajouter une profusion de lignes de code pour éliminer les cas qu'on n'avait pas prévus...
Celui, par exemple, qui a écrit la fonction d'inversion d'une matrice 2X2 devrait chercher si par hasard il n'existait pas des matrices aures que 2X2 et une méthode générale d'inversion des matrices carrées.

Re: Problème conversion champ en longueur fixe

par Calimero » 09 mars 2012, 21:42

Et que produit cette méthode dédiée à un cas particulier si, par hasard on tombe sur un nombre à trois décimales?
Dans ce cas la multiplication par 100 ne fonctionnerait plus, en effet, et il faudrait éliminer le point par un autre moyen. Mais j'ai pensé que le cas était improbable vu le 100.00 donné dans le post initial :) (format monétaire)
ou à une seule décimale, parce qu'on a négligé le 0 final de 12.50 qu'on a écrit 12.5?
Mathématiquement parlant, les deux nombres sont identiques (les zéros à droite après la virgule sont non-significatifs), donc la multiplication par 100 donnera rigoureusement le même résultat, ce tu peux d'ailleurs vérifier avec php :
$num=426.3;
echo sprintf('%09u',$num*100); // 000042630

Re: Problème conversion champ en longueur fixe

par sirakawa » 09 mars 2012, 20:25

Et que produit cette méthode dédiée à un cas particulier si, par hasard on tombe sur un nombre à trois décimales? ou à une seule décimale, parce qu'on a négligé le 0 final de 12.50 qu'on a écrit 12.5?