cedflow
Messages postés28Date d'inscriptionlundi 19 juillet 2004StatutMembreDernière intervention 8 novembre 2004 4 nov. 2004 à 15:54
ben la g pas énormément de temps depuis hier, mais à partir de ce soir je pars sur ton source, donc moi sa m'arrange si tu trouve la solution à notre problème ;-)
JulioDelphi
Messages postés2226Date d'inscriptiondimanche 5 octobre 2003StatutMembreDernière intervention18 novembre 201014 4 nov. 2004 à 15:04
cedflow > donc tu prends pour base mon source ou celui de debiars ? dans mon cas je n'ai pas indéxé, mais dans les deux cas la rechch est rapide.
Dans mon premier source, il fallait faire plus de 39000 fois le tour de la boucle pour trouver, maintenant il en faut moins de 20 :) merci la dichotomie (je n'y avait pas pensé avant, merci debiars)
cedflow
Messages postés28Date d'inscriptionlundi 19 juillet 2004StatutMembreDernière intervention 8 novembre 2004 4 nov. 2004 à 14:39
de mon coté, pour le programe que j'ai a réalisé, je souhaite pas trop prendre le temps d'étudier l'indexation vu mon nivo, je m'y attaquerais quand j'aurais fini le programme et que j'aurais un peu plus de temps pour m'amuser cette fois avec l'indexation.
JulioDelphi
Messages postés2226Date d'inscriptiondimanche 5 octobre 2003StatutMembreDernière intervention18 novembre 201014 4 nov. 2004 à 14:24
cedflow> lol c une bidouille qui marche oui, mais ça ne me plait pas de savoir que c un probleme resolvable et que je le laisse en me disant "je mets des lignes bidons en plus"
Debiars> yes ta source est nikel, c'est juste que j'étais reparti avec le debit de source de cedflow, je vais faire idem en partant de ta source, vois ce ke j'en améliore
"conseil amical" : bah oui je sais :D
Debiars
Messages postés285Date d'inscriptionlundi 16 juin 2003StatutMembreDernière intervention11 février 2018 4 nov. 2004 à 12:08
A JulioDelphi...
pourquoi tu ne vas pas voir mon source :
A propos de communes
plus de problème de dichotomie !
Conseil amical :-D
cedflow
Messages postés28Date d'inscriptionlundi 19 juillet 2004StatutMembreDernière intervention 8 novembre 2004 4 nov. 2004 à 11:05
et pour pas casser la tête y suffirait pas d'ajoutetr un saut de ligne ou un caractère au début et à la fin du fichier
JulioDelphi
Messages postés2226Date d'inscriptiondimanche 5 octobre 2003StatutMembreDernière intervention18 novembre 201014 4 nov. 2004 à 10:43
il reste un enorme problème à regler, je viens de m'en apercevoir : impossible de rechercher le premier et le dernier CP.
je bosse dessus des ke je peux pour corriger ça
++
cedflow
Messages postés28Date d'inscriptionlundi 19 juillet 2004StatutMembreDernière intervention 8 novembre 2004 4 nov. 2004 à 09:26
oki merci beaucoup, c cool
JulioDelphi
Messages postés2226Date d'inscriptiondimanche 5 octobre 2003StatutMembreDernière intervention18 novembre 201014 3 nov. 2004 à 19:27
en relisant mon post je vois ke j'ai mal géré le "france"
il faut remplacer :
Edit6.Text := 'France';
if strtoint(Edit4.Text) > 99100 then
Edit6.Text := sm.after(' ',ListCP.Strings[n-1]);
par
if strtoint(Edit4.Text) > 99100 then
Edit6.Text := sm.after(' ',ListCP.Strings[n-1])
else
Edit6.Text := 'France';
voila.
je vois aussi ke, une fois le CP trouvé, on peut simplement "remonter" juskau premier CP identique, puis garder cet index pour ajouter (en boucle while) tous les CP identiques (jusqu'a ce qu'il soit different)
mais ça va pas faire gagner des secondes a l'execution non plus :)
a tester :D
JulioDelphi
Messages postés2226Date d'inscriptiondimanche 5 octobre 2003StatutMembreDernière intervention18 novembre 201014 3 nov. 2004 à 16:48
ps oublié : la vérification d'un code non trouvé est faite grace au :
if mini = maxi-1 then
begin
MessageDlg('Aucune correspondance trouvée.',mtInformation,[mbOk],0);
Pastrouve := true;
edit4.SetFocus;
break;
end;
ce que je pense qu'on peut améliorer :
i:=ligne;
j := ligne;
while StrToInt(sm.before(' ',ListCP.Strings[i]))=CpATrouver do
begin
dec(i);
end;
while StrToInt(sm.before(' ',ListCP.Strings[j]))=CpATrouver do
begin
inc(j);
end;
for n:=i+1 to j-1 do
ComboBox3.Items.Add(sm.after(' ',ListCP.Strings[n]));
on peut directment ajouter ComboBox3.Items.Add(sm.after(' ',ListCP.Strings[i])); et ComboBox3.Items.Add(sm.after(' ',ListCP.Strings[j])); sasn faire de boucle avec FOR avec le N, a condition de mettre la ComboBox3.sorted à true;
voila :)
JulioDelphi
Messages postés2226Date d'inscriptiondimanche 5 octobre 2003StatutMembreDernière intervention18 novembre 201014 3 nov. 2004 à 16:45
ok, voila ma retouche pour la procedure du edit4exit :
procedure TForm1.Edit4Exit(Sender: TObject);
var
n, j, i, maxi, mini, ici, CPaTrouver, CpTrouve, Ligne :Integer;
CodePostal :string;
Commune :string;
isOk, Pastrouve: boolean;
begin
if length(Edit4.Text)<>5 then exit;
ComboBox3.Clear;
isOk := false;
CPaTrouver := StrToINt(edit4.Text);
maxi := ListCP.Count;
mini := 0;
repeat
if mini = maxi-1 then
begin
MessageDlg('Aucune correspondance trouvée.',mtInformation,[mbOk],0);
Pastrouve := true;
edit4.SetFocus;
break;
end;
ici := (mini + maxi) div 2;
CpTrouve := StrToInt(sm.before(' ',ListCP.Strings[ici])); // récupération du code postal
if CpTrouve < CpaTrouver then mini := ici else if CpTrouve > Cpatrouver then maxi := ici
else
begin
Ligne := ici;
isOk := true;
end;
until isOk;
i:=ligne;
j := ligne;
while StrToInt(sm.before(' ',ListCP.Strings[i]))=CpATrouver do
begin
dec(i);
end;
while StrToInt(sm.before(' ',ListCP.Strings[j]))=CpATrouver do
begin
inc(j);
end;
for n:=i+1 to j-1 do
ComboBox3.Items.Add(sm.after(' ',ListCP.Strings[n]));
Edit6.Text := 'France';
if strtoint(Edit4.Text) > 99100 then
Edit6.Text := sm.after(' ',ListCP.Strings[n-1]);
ComboBox3.ItemIndex := 0;
end;
j'utilise ici la dichotomie, c a dire ke je coupe la poire en deux a chake fois.
en chch un code postal, je pioche le CP du mileu de liste, puis je compare avc < ou >. Apres la premiere pioche, il ne me reste plus ke la moitié (maxi) du fichier a parcourir, etc etc etc, ke l'on rechch "01000" ou "99516", ça mets (théoriquement) le meme temps. (je ne sais pas comment vous calculer le nb de scondes d'execution d'une proc.)
je viens de faire ça avant d('aller au taf pour aider notre ami cedflow, je pense que ce bout de source est encore réduisable et optimisable : je vous le laisse de bon coeur :)
JulioDelphi
Messages postés2226Date d'inscriptiondimanche 5 octobre 2003StatutMembreDernière intervention18 novembre 201014 3 nov. 2004 à 16:00
pour al limite de depassement, cune boucle sans fin ki gene c ça ?
logique puisque tu utilises une boucle WHILE qui attends forcement qqchose de "bon", regarde ds mon source (je vois que tu t'en ai servi, ça fait plaisir) j'utilise des boucles FOR, comme ça a un moment, ça s'arrete, apres je verif si qqchose a été trouvé, sinon je sors un dialog "aucune commune trouvée"
je vais voir ça de plus pres bientot
cedflow
Messages postés28Date d'inscriptionlundi 19 juillet 2004StatutMembreDernière intervention 8 novembre 2004 3 nov. 2004 à 15:51
si vous saviez comment rendre mon source plus simple et plus propre sa m'interresse aussi
cedflow
Messages postés28Date d'inscriptionlundi 19 juillet 2004StatutMembreDernière intervention 8 novembre 2004 3 nov. 2004 à 15:39
ben pour régler mon bug de dépassement de TListString, je capte pas ou est l'erreur
merci
JulioDelphi
Messages postés2226Date d'inscriptiondimanche 5 octobre 2003StatutMembreDernière intervention18 novembre 201014 3 nov. 2004 à 15:36
tu as besoin de quoi de plus ?
les bureaux distributeurs en premier ? si oui : trie les :)
sinon quelles améliorations !?
cedflow
Messages postés28Date d'inscriptionlundi 19 juillet 2004StatutMembreDernière intervention 8 novembre 2004 3 nov. 2004 à 15:05
g vraiment besoin d'aide pour améliorer mon source, Merci
Debiars
Messages postés285Date d'inscriptionlundi 16 juin 2003StatutMembreDernière intervention11 février 2018 31 oct. 2004 à 17:54
Pour ajouter mon grain de sel à tous ces commentaires
(lecture passionante...), j'ai déposé ma solution.
Voir "A propos des noms de communes"
JulioDelphi
Messages postés2226Date d'inscriptiondimanche 5 octobre 2003StatutMembreDernière intervention18 novembre 201014 30 oct. 2004 à 16:50
oui bien sur je comprends l'utilité du B.D mais pour le prog est-ce si important ? juste ça :)
ça va etre monstrueux le boulot pour mettre dans l'ordre lol, apres le bureau distributeur, je veux un classement par nombre d'habitants :D
Emandhal
Messages postés194Date d'inscriptiondimanche 2 mars 2003StatutMembreDernière intervention10 octobre 20063 30 oct. 2004 à 16:38
japee je sais que des fois il y a des ", c'est les cas où il y a des espaces ou des caractères spéciaux. Si pour relire le fichier test tu utilises les CSi y'aura pas de problème, la TStringList s'adaptera parfaitement su que dans le fichier text la méthode utilisée est les CSi :)
JulioDelphi
Messages postés2226Date d'inscriptiondimanche 5 octobre 2003StatutMembreDernière intervention18 novembre 201014 30 oct. 2004 à 16:36
bon ke je me souviennes :
procedure TForm1.e_cpBtnClick(Sender: TObject);
var
i: integer;
begin
if length(e_cp.text)<>5 then exit;
ComboBox1.clear;
for i:=0 to TCp.Count-1 do
begin
if sm.before(' ',TCp.Strings[i])=e_cp.text then ComboBox1.items.add(sm.after(' ',TCp.Strings[i]));
if ComboBox1.items.count=0 then showmessage('Aucune correspondance trouvée') else ComboBox1.itemindex:=0;
end;
end;
voila la procedure manquante je crois ... de tte façon je REup cette nuit qd meme le bon
Joleroy
Messages postés106Date d'inscriptionmardi 16 décembre 2003StatutMembreDernière intervention24 octobre 2005 30 oct. 2004 à 16:06
Et pourqoi ne pas mettre la liste dans une table plutot qu 'un fichier texte. ca serait pas plus rapide?
JulioDelphi
Messages postés2226Date d'inscriptiondimanche 5 octobre 2003StatutMembreDernière intervention18 novembre 201014 30 oct. 2004 à 15:25
OMG ! j'ai up le mauvais :| naaaaaaaan désolé !
bah je l'upload cette nuit ...
:'(
japee
Messages postés1727Date d'inscriptionvendredi 27 décembre 2002StatutModérateurDernière intervention 6 novembre 20218 30 oct. 2004 à 14:54
Ben j'avais écrit (vous m'avez devancé...) :
.....................................
Emandhal
Je n'ai pas le temps d'éplucher ton code, il m'a lair intéressant. Mais dans le fichier obtenu, certaines communes sont entourées de " et pas d'autres...
Et de toute manière, celà ne résout pas le problème. Il faut déterminer quel est le bureau distributeur.
Dans le fichier d'origine, dans le cas où plusieurs communes ont le même code postal, elles sont classées dans l'ordre alphabétique.
Dans ces conditions, il faut déterminer quel est le bureau distributeur, qui n'est forcément placé en premier.
Il est faux d'affirmer que le code postal 95000 correspond à BOISEMONT ou que 81500 correspond à AMBRES, même si le contraire est vrai.
Donc, mon commentaire plus haut reste valable... :(
....................................................................
Tu comprends l'utilité de connaître le bureau distributeur, JulioDelphi ?
Le bureau distributeur distribue le courrier aux petites communes alentour, quoi...
cedflow
Messages postés28Date d'inscriptionlundi 19 juillet 2004StatutMembreDernière intervention 8 novembre 2004 30 oct. 2004 à 14:51
JulioDelphi, g vu ton source, mais quand j'ouvre le fichier il est incomplet.
type
TForm1 = class(TForm)
e_cp: TEditBtn;
ComboBox1: TComboBox;
Label1: TLabel;
procedure e_cpKeyPress(Sender: TObject; var Key: Char);
procedure FormCreate(Sender: TObject);
procedure e_cpBtnClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
TCp: TStringList;
implementation
{$R *.dfm}
procedure TForm1.e_cpKeyPress(Sender: TObject; var Key: Char);
begin
if not (Key in ['0'..'9', Chr(VK_BACK), Chr(VK_DELETE)]) then key :=#0;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
TCp := TstringList.Create;
if fileexists('CpList.txt') then TCp.LoadFromFile('CpList.txt') else
begin
MessageDlg('Fichier "CpList.txt" non trouvé.',mtError,[mbOk],0);
application.Terminate;
end;
end;
procedure TForm1.e_cpBtnClick(Sender: TObject);
var
i: integer;
begin
for i:=0 to TCp.Count-1 do
begin
end;
end;
end.
***************************************
donc forcément y manque le principal lol
JulioDelphi
Messages postés2226Date d'inscriptiondimanche 5 octobre 2003StatutMembreDernière intervention18 novembre 201014 30 oct. 2004 à 14:44
yes mais ton idée est superbe :)
mais le bureau distributeur c un putain de boulot a modifier ...
est-ce si important !??
Emandhal
Messages postés194Date d'inscriptiondimanche 2 mars 2003StatutMembreDernière intervention10 octobre 20063 30 oct. 2004 à 14:41
nop ca traduit le fichier tel quel s'il y a des corrections à faire faut les faire avant. comme le bureau distributeur en premier...
Je précise que j'ai simplement exposé une idée de format. J'ai aps exposé l'idée complete :)
JulioDelphi
Messages postés2226Date d'inscriptiondimanche 5 octobre 2003StatutMembreDernière intervention18 novembre 201014 30 oct. 2004 à 14:34
oui mais est ce que l'ordre des communes est bon ? car il faut mettre le bureau distributeur en premier !!!
Emandhal
Messages postés194Date d'inscriptiondimanche 2 mars 2003StatutMembreDernière intervention10 octobre 20063 30 oct. 2004 à 14:10
Voilà la procedure :D
Procedure TransformerFichierCPenFormatCSI(Const aSource, aDest: String);
Var
FichierSource: TextFile;
StringList: TStringList;
Ligne, LastCP, CodePostal: String;
Procedure AddToFile(Str: String);
Var
FText: TextFile;
Begin
If Length(Str)<7 Then Exit;
AssignFile(FText, aDest);
Try
Append(FText);
WriteLn(FText, Str);
Finally
CloseFile(FText);
end;
end;
Begin
LastCP := '';
AssignFile(FichierSource, aDest); // Assigne le fichier
Try
Rewrite(FichierSource); // Ouvre le fichier
Finally
CloseFile(FichierSource); // Ferme le fichier
end; // Fichier Destination créé
AssignFile(FichierSource, aSource);
Reset(FichierSource);
Try
StringList := TStringList.Create;
Try
While not Eof(FichierSource) do
begin
Readln(FichierSource, Ligne);
CodePostal := Copy(Ligne, 1, 5);
If not SameText(LastCP, CodePostal) Then
begin
AddToFile(LastCP+' '+StringList.CommaText);
LastCP := CodePostal;
StringList.Clear;
end;
StringList.Add(Copy(Ligne, 7, MaxInt));
end;
AddToFile(LastCP+' '+StringList.CommaText); // Ecriture du dernier code postal
Finally
StringList.Free;
end;
Finally
CloseFile(FichierSource);
end;
End;
et là le fichier passe de 752ko à 559ko.
JulioDelphi
Messages postés2226Date d'inscriptiondimanche 5 octobre 2003StatutMembreDernière intervention18 novembre 201014 30 oct. 2004 à 14:03
non, ta procedure ne connais pas les Bureaux Distributeurs !
donc qqn va qd meme devoir se tapper de regarder pour n code postaix, kelle est la ville ki detient le B.D :/ c ça qui est long, mais le formatage du nouveau fichier txt oui c rapide.
Emandhal
Messages postés194Date d'inscriptiondimanche 2 mars 2003StatutMembreDernière intervention10 octobre 20063 30 oct. 2004 à 13:28
Je l'ai dit en 10min la procedure qui va s'en charger est faite. :)
JulioDelphi
Messages postés2226Date d'inscriptiondimanche 5 octobre 2003StatutMembreDernière intervention18 novembre 201014 30 oct. 2004 à 12:43
ouè mais ki va se tapper le boulot de modif le fichier ? lol
Emandhal
Messages postés194Date d'inscriptiondimanche 2 mars 2003StatutMembreDernière intervention10 octobre 20063 30 oct. 2004 à 12:38
A voir la tête du fichier txt je pense qu'il y a moyen de pouvoir améliorer la rapidité de celui ci... Je m'explique :
Admettons ça :
95000 CERGY
95000 BOISEMONT
95000 JOUY LA FONTAINE
95000 JOUY LE MOUTIER
95000 MENANDON
95000 NEUVILLE SUR OISE
95000 VAUREAL
95000 VINCOURT
Mon avis est de le passer comme ceci :
95000 CERGY,BOISEMONT,"JOUY LA FONTAINE","JOUY LE MOUTIER",MENANDON,"NEUVILLE SUR OISE",VAUREAL,VINCOURT
Et après de faire :
Codepostal := Copy(Ligne, 1, 5);
Communes := Copy(Ligne, 7, MaxInt);
et pour récupérer les communes dans un TStringList (pouvant se mettre dans un ComboBox ou un ListBox par exemple) en utilisant le CSI (CommaSeparatedInfos) du TStringList.
Je pense que ça réduirai sensiblement le nombre de lignes du fichier text et donc améliorer la vitesse de lecture mais aussi la taille du fichier txt.
La transformation est pas si difficile une petite fonction permetterai de le faire simplement et automatiquement (en utilisant le CSI pour être sûr de la compatibilité).
Je ne fais qu'exposer une idée comme ça. S'il y en a qui connaissent pas les CSI, je les invite à regarder l'aide de Delphi sur les fonctions 'Delimiter' et 'QuoteChar' du TStringList.
Je ne sais pas si c'est une super idée mais moi c'est la méthode que j'aurai utilisé en premier.
JulioDelphi
Messages postés2226Date d'inscriptiondimanche 5 octobre 2003StatutMembreDernière intervention18 novembre 201014 30 oct. 2004 à 09:22
ce site donne tous les CP, les communes soulignées sont les bureaux distributeurs ...
JulioDelphi
Messages postés2226Date d'inscriptiondimanche 5 octobre 2003StatutMembreDernière intervention18 novembre 201014 30 oct. 2004 à 09:10
lol oui ok, à 1:40:17 je me suis arrété, il était largement l'heure du dodo :)
je suis 100% OK et désireux de faire la rechch du bureau distributeur(B.D), sauf que je n'en connais qu'un seul (59190 : hazebrouck). Aucun code ne va me donner la liste des B.D
Alors, on utilise un typé ou un CSV ? comment va ton reclasser les communes ou ajouter un "B" ou "C" entre le CP et la commune (pour "B"ureau ou "C"ommune)
allez on se motive :)
cs_Delphiprog
Messages postés4297Date d'inscriptionsamedi 19 janvier 2002StatutMembreDernière intervention 9 janvier 201333 30 oct. 2004 à 02:22
1/ Si je ne me trompe pas, il y a environ 40000 communes en France. Si l'on table sur une longueur moyenne de ligne de 100 caractères, cela fait un fichier de taille potentielle de 4 Mo.
2/Vous semblez suggérer l'utilisation d'une liste de chaines. Or, avec la présence de bureaux distributeurs, nous nous trouvons en présence de 3 données par ligne. Si le codage n'est pas insurmontable pour un certain nombre d'entre vous, CedFlow déclare débuter en Delphi. Ce n'est peut-être donc pas aussi évident pour lui.
3/ Que l'on lise le fichier ou qu'on le charge dans un TStringList, le gain est à relativiser. D'un côté on ne lit que ce qui est nécessaire jusqu'à trouver la bonne ligne, de l'autre TStringList.LoadFromFile lit l'intégralité du fichier.
4/ Le chargement de l'intégralité du fichier dans un TStringList ne pemettra pas d'utiliser la méthode IndexOf, pourtant si efficace, pour retrouver une commune quelconque puisqu'il faudra alors fournir l'intégralité de l'information (code postal+bureau distributeur+commune).
En écartant l'idée d'une base de données, il ne reste plus que deux autres choix possibles :
- un fichier typé
- un fichier CSV
Le premier offre l'avantage d'un accès indexé donc rapide, sans charger l'intégralité du fichier en mémoire.
Le second offre la souplesse pour la longueur des "colonnes" de données. Mais cette souplesse a un prix : la lenteur de lecture du fichier.
C'est donc le moment de faire un choix avant de continuer à coder et s'apercevoir qu'on se retrouve dans une impasse.
JulioDelphi : j'ai regardé ton ébauche de code, mais tu t'es arrêté quand ça commençait à devenir intéressant, à savoir la recherche d'un code postal puis celui du bureau distributeur et celui de la commune. Dommage...
japee
Messages postés1727Date d'inscriptionvendredi 27 décembre 2002StatutModérateurDernière intervention 6 novembre 20218 30 oct. 2004 à 01:43
Où as tu trouvé le fichier 'CpList.txt' ?
Est-il complet et fiable ?
S'il l'est, il serait intéressant à mon avis de le modifier quelque peu.
Il se présente comme ceci (exemple, mais il y en a d'autres...) :
95000 BOISEMONT
95000 CERGY // <- Le bureau distributeur
95000 JOUY LA FONTAINE
95000 JOUY LE MOUTIER
95000 MENANDON
95000 NEUVILLE SUR OISE
95000 VAUREAL
95000 VINCOURT
Il faudrait placer le bureau distributeur devant les communes qui dépendent de lui, comme ceci :
95000 CERGY
95000 BOISEMONT
95000 JOUY LA FONTAINE
95000 JOUY LE MOUTIER
95000 MENANDON
95000 NEUVILLE SUR OISE
95000 VAUREAL
95000 VINCOURT
Ce qui permettrait, en saisissant 95000, d'obtenir CERGY, ce qui est quand même plus judicieux, à priori, que BOISEMONT...
Evidemment, il faut disposer d'une documentation concernant les codes postaux pour effectuer ce travail...
Quoi qu'il en soit, idée de programme très, très intéressante !
Bon courage pour la suite.
JulioDelphi
Messages postés2226Date d'inscriptiondimanche 5 octobre 2003StatutMembreDernière intervention18 novembre 201014 30 oct. 2004 à 01:40
euh... c'est ecrit "voila mon source a moi" donc il te suffit de le telecharger ...
et oui effectivement j'ai mis le txt ds un TStringList.
donc va sur l'url pour prendre mon source ! c tout bete :|
ps : je vois que tu as pris l'executable mais le lien juste a coté c'est "la source" ... suffisais de lire mais on va dire qu'il est tard ;)
cedflow
Messages postés28Date d'inscriptionlundi 19 juillet 2004StatutMembreDernière intervention 8 novembre 2004 30 oct. 2004 à 01:35
Delphiprog t commandes ayant à peu près la même fonctions que mes boucles, cela n'a pas amélioré de façon notable la vitesse d'exécution, par contre g pus rendre plus simple mon code, donc c cool.
en fait la perte de temps est due à la recherche dans le txt et non aux filtres appliqués sur la String (m'enfin si on peut gagner la aussi ;-) )
cedflow
Messages postés28Date d'inscriptionlundi 19 juillet 2004StatutMembreDernière intervention 8 novembre 2004 30 oct. 2004 à 01:21
JulioDelphi tu pourrais pas me passer le source, ca m'éviterais de me faire chier à coder même si g déjà ma petite idée sur le codage (c tjrs du temps de gagné)
sinon, je ne c pas ce que tu as utilisé, mais je penses quand stockant le txt dans un StringList au démarrage du prog, on peut obtenir une bonne vitesse de fonctionnement car on accède directement au lignes.
JulioDelphi
Messages postés2226Date d'inscriptiondimanche 5 octobre 2003StatutMembreDernière intervention18 novembre 201014 30 oct. 2004 à 00:14
5 nov. 2004 à 23:52
4 nov. 2004 à 16:38
ça te va ?
4 nov. 2004 à 15:54
4 nov. 2004 à 15:04
Dans mon premier source, il fallait faire plus de 39000 fois le tour de la boucle pour trouver, maintenant il en faut moins de 20 :) merci la dichotomie (je n'y avait pas pensé avant, merci debiars)
4 nov. 2004 à 14:39
4 nov. 2004 à 14:24
Debiars> yes ta source est nikel, c'est juste que j'étais reparti avec le debit de source de cedflow, je vais faire idem en partant de ta source, vois ce ke j'en améliore
"conseil amical" : bah oui je sais :D
4 nov. 2004 à 12:08
pourquoi tu ne vas pas voir mon source :
A propos de communes
plus de problème de dichotomie !
Conseil amical :-D
4 nov. 2004 à 11:05
4 nov. 2004 à 10:43
je bosse dessus des ke je peux pour corriger ça
++
4 nov. 2004 à 09:26
3 nov. 2004 à 19:27
il faut remplacer :
Edit6.Text := 'France';
if strtoint(Edit4.Text) > 99100 then
Edit6.Text := sm.after(' ',ListCP.Strings[n-1]);
par
if strtoint(Edit4.Text) > 99100 then
Edit6.Text := sm.after(' ',ListCP.Strings[n-1])
else
Edit6.Text := 'France';
voila.
je vois aussi ke, une fois le CP trouvé, on peut simplement "remonter" juskau premier CP identique, puis garder cet index pour ajouter (en boucle while) tous les CP identiques (jusqu'a ce qu'il soit different)
mais ça va pas faire gagner des secondes a l'execution non plus :)
a tester :D
3 nov. 2004 à 16:48
ce que je pense qu'on peut améliorer :
on peut directment ajouter ComboBox3.Items.Add(sm.after(' ',ListCP.Strings[i])); et ComboBox3.Items.Add(sm.after(' ',ListCP.Strings[j])); sasn faire de boucle avec FOR avec le N, a condition de mettre la ComboBox3.sorted à true;
voila :)
3 nov. 2004 à 16:45
j'utilise StrMan.pas (comme toujours), trouvable ici : http://diabloporc.free.fr/delphi/strman/
j'utilise ici la dichotomie, c a dire ke je coupe la poire en deux a chake fois.
en chch un code postal, je pioche le CP du mileu de liste, puis je compare avc < ou >. Apres la premiere pioche, il ne me reste plus ke la moitié (maxi) du fichier a parcourir, etc etc etc, ke l'on rechch "01000" ou "99516", ça mets (théoriquement) le meme temps. (je ne sais pas comment vous calculer le nb de scondes d'execution d'une proc.)
je viens de faire ça avant d('aller au taf pour aider notre ami cedflow, je pense que ce bout de source est encore réduisable et optimisable : je vous le laisse de bon coeur :)
3 nov. 2004 à 16:00
logique puisque tu utilises une boucle WHILE qui attends forcement qqchose de "bon", regarde ds mon source (je vois que tu t'en ai servi, ça fait plaisir) j'utilise des boucles FOR, comme ça a un moment, ça s'arrete, apres je verif si qqchose a été trouvé, sinon je sors un dialog "aucune commune trouvée"
je vais voir ça de plus pres bientot
3 nov. 2004 à 15:51
3 nov. 2004 à 15:39
merci
3 nov. 2004 à 15:36
les bureaux distributeurs en premier ? si oui : trie les :)
sinon quelles améliorations !?
3 nov. 2004 à 15:05
31 oct. 2004 à 17:54
(lecture passionante...), j'ai déposé ma solution.
Voir "A propos des noms de communes"
30 oct. 2004 à 16:50
ça va etre monstrueux le boulot pour mettre dans l'ordre lol, apres le bureau distributeur, je veux un classement par nombre d'habitants :D
30 oct. 2004 à 16:38
30 oct. 2004 à 16:36
procedure TForm1.e_cpBtnClick(Sender: TObject);
var
i: integer;
begin
if length(e_cp.text)<>5 then exit;
ComboBox1.clear;
for i:=0 to TCp.Count-1 do
begin
if sm.before(' ',TCp.Strings[i])=e_cp.text then ComboBox1.items.add(sm.after(' ',TCp.Strings[i]));
if ComboBox1.items.count=0 then showmessage('Aucune correspondance trouvée') else ComboBox1.itemindex:=0;
end;
end;
voila la procedure manquante je crois ... de tte façon je REup cette nuit qd meme le bon
30 oct. 2004 à 16:06
30 oct. 2004 à 15:25
bah je l'upload cette nuit ...
:'(
en attendant, prends EditBtn.pas et StrMan.zip du dossier http://diabloporc.free.fr/delphi/
30 oct. 2004 à 14:54
.....................................
Emandhal
Je n'ai pas le temps d'éplucher ton code, il m'a lair intéressant. Mais dans le fichier obtenu, certaines communes sont entourées de " et pas d'autres...
Et de toute manière, celà ne résout pas le problème. Il faut déterminer quel est le bureau distributeur.
Dans le fichier d'origine, dans le cas où plusieurs communes ont le même code postal, elles sont classées dans l'ordre alphabétique.
Dans ces conditions, il faut déterminer quel est le bureau distributeur, qui n'est forcément placé en premier.
Il est faux d'affirmer que le code postal 95000 correspond à BOISEMONT ou que 81500 correspond à AMBRES, même si le contraire est vrai.
Donc, mon commentaire plus haut reste valable... :(
....................................................................
Tu comprends l'utilité de connaître le bureau distributeur, JulioDelphi ?
Le bureau distributeur distribue le courrier aux petites communes alentour, quoi...
30 oct. 2004 à 14:51
************************************
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, EditBtn;
type
TForm1 = class(TForm)
e_cp: TEditBtn;
ComboBox1: TComboBox;
Label1: TLabel;
procedure e_cpKeyPress(Sender: TObject; var Key: Char);
procedure FormCreate(Sender: TObject);
procedure e_cpBtnClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
TCp: TStringList;
implementation
{$R *.dfm}
procedure TForm1.e_cpKeyPress(Sender: TObject; var Key: Char);
begin
if not (Key in ['0'..'9', Chr(VK_BACK), Chr(VK_DELETE)]) then key :=#0;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
TCp := TstringList.Create;
if fileexists('CpList.txt') then TCp.LoadFromFile('CpList.txt') else
begin
MessageDlg('Fichier "CpList.txt" non trouvé.',mtError,[mbOk],0);
application.Terminate;
end;
end;
procedure TForm1.e_cpBtnClick(Sender: TObject);
var
i: integer;
begin
for i:=0 to TCp.Count-1 do
begin
end;
end;
end.
***************************************
donc forcément y manque le principal lol
30 oct. 2004 à 14:44
mais le bureau distributeur c un putain de boulot a modifier ...
est-ce si important !??
30 oct. 2004 à 14:41
Je précise que j'ai simplement exposé une idée de format. J'ai aps exposé l'idée complete :)
30 oct. 2004 à 14:34
30 oct. 2004 à 14:10
Procedure TransformerFichierCPenFormatCSI(Const aSource, aDest: String);
Var
FichierSource: TextFile;
StringList: TStringList;
Ligne, LastCP, CodePostal: String;
Procedure AddToFile(Str: String);
Var
FText: TextFile;
Begin
If Length(Str)<7 Then Exit;
AssignFile(FText, aDest);
Try
Append(FText);
WriteLn(FText, Str);
Finally
CloseFile(FText);
end;
end;
Begin
LastCP := '';
AssignFile(FichierSource, aDest); // Assigne le fichier
Try
Rewrite(FichierSource); // Ouvre le fichier
Finally
CloseFile(FichierSource); // Ferme le fichier
end; // Fichier Destination créé
AssignFile(FichierSource, aSource);
Reset(FichierSource);
Try
StringList := TStringList.Create;
Try
While not Eof(FichierSource) do
begin
Readln(FichierSource, Ligne);
CodePostal := Copy(Ligne, 1, 5);
If not SameText(LastCP, CodePostal) Then
begin
AddToFile(LastCP+' '+StringList.CommaText);
LastCP := CodePostal;
StringList.Clear;
end;
StringList.Add(Copy(Ligne, 7, MaxInt));
end;
AddToFile(LastCP+' '+StringList.CommaText); // Ecriture du dernier code postal
Finally
StringList.Free;
end;
Finally
CloseFile(FichierSource);
end;
End;
et là le fichier passe de 752ko à 559ko.
30 oct. 2004 à 14:03
donc qqn va qd meme devoir se tapper de regarder pour n code postaix, kelle est la ville ki detient le B.D :/ c ça qui est long, mais le formatage du nouveau fichier txt oui c rapide.
30 oct. 2004 à 13:28
30 oct. 2004 à 12:43
30 oct. 2004 à 12:38
Admettons ça :
95000 CERGY
95000 BOISEMONT
95000 JOUY LA FONTAINE
95000 JOUY LE MOUTIER
95000 MENANDON
95000 NEUVILLE SUR OISE
95000 VAUREAL
95000 VINCOURT
Mon avis est de le passer comme ceci :
95000 CERGY,BOISEMONT,"JOUY LA FONTAINE","JOUY LE MOUTIER",MENANDON,"NEUVILLE SUR OISE",VAUREAL,VINCOURT
Et après de faire :
Codepostal := Copy(Ligne, 1, 5);
Communes := Copy(Ligne, 7, MaxInt);
et pour récupérer les communes dans un TStringList (pouvant se mettre dans un ComboBox ou un ListBox par exemple) en utilisant le CSI (CommaSeparatedInfos) du TStringList.
Je pense que ça réduirai sensiblement le nombre de lignes du fichier text et donc améliorer la vitesse de lecture mais aussi la taille du fichier txt.
La transformation est pas si difficile une petite fonction permetterai de le faire simplement et automatiquement (en utilisant le CSI pour être sûr de la compatibilité).
Je ne fais qu'exposer une idée comme ça. S'il y en a qui connaissent pas les CSI, je les invite à regarder l'aide de Delphi sur les fonctions 'Delimiter' et 'QuoteChar' du TStringList.
Je ne sais pas si c'est une super idée mais moi c'est la méthode que j'aurai utilisé en premier.
30 oct. 2004 à 09:22
http://www.36000communes.com/departements.html
bon tri ...
30 oct. 2004 à 09:10
je suis 100% OK et désireux de faire la rechch du bureau distributeur(B.D), sauf que je n'en connais qu'un seul (59190 : hazebrouck). Aucun code ne va me donner la liste des B.D
Alors, on utilise un typé ou un CSV ? comment va ton reclasser les communes ou ajouter un "B" ou "C" entre le CP et la commune (pour "B"ureau ou "C"ommune)
allez on se motive :)
30 oct. 2004 à 02:22
2/Vous semblez suggérer l'utilisation d'une liste de chaines. Or, avec la présence de bureaux distributeurs, nous nous trouvons en présence de 3 données par ligne. Si le codage n'est pas insurmontable pour un certain nombre d'entre vous, CedFlow déclare débuter en Delphi. Ce n'est peut-être donc pas aussi évident pour lui.
3/ Que l'on lise le fichier ou qu'on le charge dans un TStringList, le gain est à relativiser. D'un côté on ne lit que ce qui est nécessaire jusqu'à trouver la bonne ligne, de l'autre TStringList.LoadFromFile lit l'intégralité du fichier.
4/ Le chargement de l'intégralité du fichier dans un TStringList ne pemettra pas d'utiliser la méthode IndexOf, pourtant si efficace, pour retrouver une commune quelconque puisqu'il faudra alors fournir l'intégralité de l'information (code postal+bureau distributeur+commune).
En écartant l'idée d'une base de données, il ne reste plus que deux autres choix possibles :
- un fichier typé
- un fichier CSV
Le premier offre l'avantage d'un accès indexé donc rapide, sans charger l'intégralité du fichier en mémoire.
Le second offre la souplesse pour la longueur des "colonnes" de données. Mais cette souplesse a un prix : la lenteur de lecture du fichier.
C'est donc le moment de faire un choix avant de continuer à coder et s'apercevoir qu'on se retrouve dans une impasse.
JulioDelphi : j'ai regardé ton ébauche de code, mais tu t'es arrêté quand ça commençait à devenir intéressant, à savoir la recherche d'un code postal puis celui du bureau distributeur et celui de la commune. Dommage...
30 oct. 2004 à 01:43
Est-il complet et fiable ?
S'il l'est, il serait intéressant à mon avis de le modifier quelque peu.
Il se présente comme ceci (exemple, mais il y en a d'autres...) :
95000 BOISEMONT
95000 CERGY // <- Le bureau distributeur
95000 JOUY LA FONTAINE
95000 JOUY LE MOUTIER
95000 MENANDON
95000 NEUVILLE SUR OISE
95000 VAUREAL
95000 VINCOURT
Il faudrait placer le bureau distributeur devant les communes qui dépendent de lui, comme ceci :
95000 CERGY
95000 BOISEMONT
95000 JOUY LA FONTAINE
95000 JOUY LE MOUTIER
95000 MENANDON
95000 NEUVILLE SUR OISE
95000 VAUREAL
95000 VINCOURT
Ce qui permettrait, en saisissant 95000, d'obtenir CERGY, ce qui est quand même plus judicieux, à priori, que BOISEMONT...
Evidemment, il faut disposer d'une documentation concernant les codes postaux pour effectuer ce travail...
Quoi qu'il en soit, idée de programme très, très intéressante !
Bon courage pour la suite.
30 oct. 2004 à 01:40
et oui effectivement j'ai mis le txt ds un TStringList.
donc va sur l'url pour prendre mon source ! c tout bete :|
ps : je vois que tu as pris l'executable mais le lien juste a coté c'est "la source" ... suffisais de lire mais on va dire qu'il est tard ;)
30 oct. 2004 à 01:35
en fait la perte de temps est due à la recherche dans le txt et non aux filtres appliqués sur la String (m'enfin si on peut gagner la aussi ;-) )
30 oct. 2004 à 01:21
sinon, je ne c pas ce que tu as utilisé, mais je penses quand stockant le txt dans un StringList au démarrage du prog, on peut obtenir une bonne vitesse de fonctionnement car on accède directement au lignes.
30 oct. 2004 à 00:14
voila mon source a moi !
http://diabloporc.free.fr/creations.php#cp
Merci a toi pour la liste :D
29 oct. 2004 à 23:14
Codepostal := Copy(Ligne, 1, 5);
Commune := Copy(Ligne, 7, Length(Ligne));