je me suis penché sur la façon d’accéder et de rechercher une donnée contenue dans un fichier texte de plusieurs milliers de lignes, sans que ces manipulations ne prennent trop de temps.
le fichier que j'ai choisi pour ma recherche est le fichier regroupant l'ensemble des codes IATA (aéroportuaires) : ce petit code de trois lettre que l'on trouve sur son bagage à la sortie de l'avion.
La première idée (qui n'est pas mauvaise) consistait a mettre ce fichier dans un tableau en mémoire, de façon à ce que la recherche soit instantanée.
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <EditConstants.au3>
global $gui,$Input,$Label_aeroport,$arr, $file=@ScriptDir & "\codesnew.csv"
$gui = GUICreate("Codes Aéroports V 1.1", 730, 128, 232, 194)
$Input = GUICtrlCreateInput("", 16, 24, 30, 21)
GUICtrlCreateLabel("<--- Code Aéroportuaire : Ex: STN", 60, 24, 200, 21)
GUICtrlCreateLabel("Correspond à :", 16, 64, 76, 17)
$Label_aeroport = GUICtrlCreateLabel("", 104, 64, 608, 25)
$Group1 = GUICtrlCreateGroup("", 8, 8, 713, 105)
GUICtrlCreateLabel("Concept && dévellopement : Marc GRAZIANI", 500, 96, 220, 17)
GUICtrlCreateGroup("", -99, -99, 1, 1)
$Button_ok = GUICtrlCreateButton("OK", 648, 16, 65, 25)
$button_array = GUICtrlCreateButton("Liste",648,46,65,25)
$accEnter = GUICtrlCreateDummy()
Global $a_AccelKeys[1][2] = [["{ENTER}", $accEnter]]
GUISetAccelerators($a_AccelKeys)
If not FileExists($file) then
msgbox(64,"Erreur", "Fichier Codes.csv Manquant" & @CRLF & "Je quitte")
Exit
EndIf
Dim $sCSV = FileRead($file)
ProgressOn("Préparation","Chargement, veuillez patienter")
Local $arr = toArrayCsv($sCSV)
GUISetState(@SW_SHOW)
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
Case $Button_ok
_trouve_code()
case $button_array
_ArrayDisplay($arr,"Codes Aéroports","|3",16)
Case $accEnter
If _GuiCtrlGetFocus($gui) = $Input Then
_trouve_code()
Else
GUISetAccelerators("")
ControlSend($gui, "", _GuiCtrlGetFocus($gui), "{ENTER}")
GUISetAccelerators($a_AccelKeys)
EndIf
EndSwitch
WEnd
Func _trouve_code()
$code=GUICtrlRead($Input)
$result=correspond($arr,$code)
GUICtrlsetdata($Label_aeroport,$result)
EndFunc
Func toArrayCsv($s)
Local $line = StringSplit($s,@CRLF,2+1) ; combien de ligne de mon fichier <> tableau
Local $maxCol = 1 ; nombre de colonne de depart
Local $a[UBound($line)][$maxCol] ; je crée un tableau de n ligne et de 1 colonne que je modifierai à ma guise
ProgressSet(0)
For $i = 0 To UBound($line)-1 ; parcours toutes les lignes
Local $tmp = StringSplit($line[$i],";",3) ; combien de colonnes pour la ligne n°i
If(UBound($tmp) > $maxCol ) then $maxCol = UBound($tmp) ; pour connaitre le nombre de colonnes
ReDim $a[UBound($line)][$maxCol] ; je redimensionne mon tableau aux bonnes dimensions
For $j = 0 To UBound($tmp)-1 ; je parcours cellule par cellule "de gauche a droite"
ProgressSet($i*100/UBound($line),"Lecture de la ligne : " & $i)
$a[$i][$j] = $tmp[$j] ; je remplis chaque cellule
Next
Next
ProgressOff()
Return $a
EndFunc
func correspond($array, $code)
$result = _ArrayFindAll($array, $code, 0, 0, 0, 1)
If IsArray($result) Then
For $i = 0 To UBound($array) - 1
$name = $array[$result[$i]][1]& ", " & $array[$result[$i]][2] & ", " & $array[$result[$i]][3] & " (Nom, Ville, Pays)"
return $name
Next
Else
Return "Non trouvé"
EndIf
EndFunc
Func _GuiCtrlGetFocus($hGui = "")
Local $InputID = ControlGetHandle($hGui, "", ControlGetFocus($hGui))
Return _ControlGetGuiID($InputID)
EndFunc ;==>_GuiCtrlGetFocus
Func _ControlGetGuiID($hCtrl)
Local $Result = DllCall("user32.dll", "int", "GetDlgCtrlID", "hwnd", $hCtrl)
If @error = 0 Then Return $Result[0]
Return SetError(1, 0, '')
EndFunc ;==>_ControlGetGuiID
Avantage : l'accès est immédiat
Inconvénient : au lancement, le programme est long a charger.
deuxième idée : faire parcourir le fichier a chaque requête
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <File.au3>
global $gui,$Input,$Label_aeroport,$arr,$file=@ScriptDir & "\codes.csv"
$gui = GUICreate("Codes Aéroports V 1.1", 730, 128, 232, 194)
$Input = GUICtrlCreateInput("", 16, 24, 30, 21)
GUICtrlCreateLabel("<--- Code Aéroportuaire : Ex: STN", 60, 24, 200, 21)
GUICtrlCreateLabel("Correspond à :", 16, 64, 76, 17)
$Label_aeroport = GUICtrlCreateLabel("", 104, 64, 608, 25)
$Group1 = GUICtrlCreateGroup("", 8, 8, 713, 105)
GUICtrlCreateLabel("Concept && dévellopement : Marc GRAZIANI", 500, 96, 220, 17)
GUICtrlCreateGroup("", -99, -99, 1, 1)
$Button_ok = GUICtrlCreateButton("OK", 648, 16, 65, 25)
If not FileExists($file) then
msgbox(64,"Erreur", "Fichier Codes.csv Manquant" & @CRLF & "Je quitte")
Exit
EndIf
HotKeySet("{enter}","_recherche_code")
GUISetState(@SW_SHOW)
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
Case $Button_ok
_recherche_code()
EndSwitch
WEnd
Func _recherche_code()
$flag=0
guictrlsetdata($Label_aeroport,"")
$file_maxline = _FileCountLines($file)
$recherche_code = GUICtrlRead($Input)
$pc_liste = FileOpen($file, 0)
If $pc_liste = -1 Then
MsgBox(0, "Erreur", "Impossible d'ouvrir le fichier !")
Exit
EndIf
ProgressOn("Recherche","Je recherche... Patientez... ")
for $i = 1 to $file_maxline
ProgressSet($i * 100 / $file_maxline)
$line = FileReadLine($pc_liste,$i) ; on parcours chaque ligne du fichier TXT
If StringInStr(stringleft($line,3), $recherche_code) Then
$flag=1
$split = StringSplit($line,";")
GUICtrlsetdata($Label_aeroport,$split[2])
ProgressOff()
ExitLoop
EndIf
if $i=$file_maxline and $flag =0 Then
GUICtrlsetdata($Label_aeroport,"Je suis désolé, je ne trouve pas")
ProgressOff()
ExitLoop
EndIf
Next
FileClose($file)
EndFunc
avantage : le lancement du programme est immédiat
Inconvénient : en cas d'accès répété les temps de recherche sont longs.
troisième idée : transformer le fichier CSV en fichier ini contenant des balises et des labels. (solution retenue)
Les Codes IATA étant générés sur 3 lettres ou chiffres, il est possible de les ordonner alphabetiquemement et numeriquement. chaque balise regroupant les codes de sa lettre ou son chiffre.
#include <GUIConstantsEx.au3>
#include <EditConstants.au3>
global $gui,$Input,$Label_aeroport,$arr,$file=@ScriptDir & "\codes-IATA.ini"
$gui = GUICreate("Codes Aéroports V 1.3", 830, 128, 232, 194)
$Input = GUICtrlCreateInput("", 16, 24, 30, 21)
GUICtrlCreateLabel("<--- Code Aéroportuaire : Ex: STN", 60, 24, 200, 21)
GUICtrlCreateLabel("Correspond à (Nom, Ville, PAYS) : ", 16, 75, 170, 17)
$Label_aeroport = GUICtrlCreateLabel("", 190, 75, 608, 25)
$Group1 = GUICtrlCreateGroup("", 8, 8, 813, 105)
GUICtrlCreateLabel("Concept && dévellopement : Marc GRAZIANI", 600, 96, 220, 17)
GUICtrlCreateGroup("", -99, -99, 1, 1)
$Button_ok = GUICtrlCreateButton("OK", 748, 16, 65, 25)
$button_QUITTER = GUICtrlCreateButton("Quitter",748,46,65,25)
$accEnter = GUICtrlCreateDummy()
Global $a_AccelKeys[1][2] = [["{ENTER}", $accEnter]]
GUISetAccelerators($a_AccelKeys)
If not FileExists($file) then
msgbox(64,"Erreur", "Fichier " & $file & " Manquant" & @CRLF & "Je quitte")
Exit
EndIf
GUISetState(@SW_SHOW)
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE, $button_QUITTER
Exit
Case $Button_ok
_recherche_code()
Case $accEnter
If _GuiCtrlGetFocus($gui) = $Input Then
_recherche_code()
Else
GUISetAccelerators("")
ControlSend($gui, "", _GuiCtrlGetFocus($gui), "{ENTER}")
GUISetAccelerators($a_AccelKeys)
EndIf
EndSwitch
WEnd
Func _recherche_code()
guictrlsetdata($Label_aeroport,"")
$recherche_code = GUICtrlRead($Input)
$lettre_recherche = StringLeft($recherche_code,1)
$result = IniRead($file, stringupper($lettre_recherche), stringleft($recherche_code,3),"")
If $result = "" then
GUICtrlsetdata($Label_aeroport,"Je suis désolé, je ne trouve pas")
Else
GUICtrlsetdata($Label_aeroport,$result)
EndIf
EndFunc
Func _GuiCtrlGetFocus($hGui = "")
Local $InputID = ControlGetHandle($hGui, "", ControlGetFocus($hGui))
Return _ControlGetGuiID($InputID)
EndFunc ;==>_GuiCtrlGetFocus
Func _ControlGetGuiID($hCtrl)
Local $Result = DllCall("user32.dll", "int", "GetDlgCtrlID", "hwnd", $hCtrl)
If @error = 0 Then Return $Result[0]
Return SetError(1, 0, '')
EndFunc ;==>_ControlGetGuiID
Avantage : ouverture et temps d'accès immédiats.
Inconvénients : demande la transformation du fichier CSV en INI
Je laisse cette petite recherche pour ceux que aimeraient faire de même et qui ne savent pas comme s'y prendre.... tout en sachant que certains sont bien meilleur que moi (qu'ils n’hésitent pas à modifier et améliorer le code)








 
 



 
  Il serait trop aisé de ma part de rétorquer que j'ai fourni un lien, et que le code était au bout du clic. J'ai bien compris qu'un exemple entaché de la sueur de mon front était attendu. Alors, bien qu'ayant d'autres chats à fouetter - dont le pauvre
  Il serait trop aisé de ma part de rétorquer que j'ai fourni un lien, et que le code était au bout du clic. J'ai bien compris qu'un exemple entaché de la sueur de mon front était attendu. Alors, bien qu'ayant d'autres chats à fouetter - dont le pauvre  – je vais, de bonne grâce, démontrer que j’ai bien compris que ce forum était un lieu d’échanges et que je n’étais pas là juste pour faire bosser les bienveillants, néanmoins débordés bénévoles compétents. On ne pompe pas les gens qui citent les Shadoks, on les honore.
  – je vais, de bonne grâce, démontrer que j’ai bien compris que ce forum était un lieu d’échanges et que je n’étais pas là juste pour faire bosser les bienveillants, néanmoins débordés bénévoles compétents. On ne pompe pas les gens qui citent les Shadoks, on les honore.  
  Ce serait drôle (comme atterrir à Paris, en Chine) ou pas, mais c’est sur que ce serait bref.
  Ce serait drôle (comme atterrir à Paris, en Chine) ou pas, mais c’est sur que ce serait bref. 
 
 
 
  
  Je ne me suis pas documenté pour connaître les limites juridiques d’utilisation dudit dico. S’il équipe un programme qui sort de chez vous, songez à vous documenter. Il existe des dictionnaires libres de droits sur le net, mais ça vous oblige à l'ajouter en FileInstall alors que presque tout le monde possède Firefox. Pour savoir s’ils sont fiables, croisez-les. Prenez-en une dizaine et composez la substantifique moelle du dictionnaire ! Créez un correcteur de commentaires de code AutoIt pour les abrutis qui mettent des smileys vivants à l’intérieur.
  Je ne me suis pas documenté pour connaître les limites juridiques d’utilisation dudit dico. S’il équipe un programme qui sort de chez vous, songez à vous documenter. Il existe des dictionnaires libres de droits sur le net, mais ça vous oblige à l'ajouter en FileInstall alors que presque tout le monde possède Firefox. Pour savoir s’ils sont fiables, croisez-les. Prenez-en une dizaine et composez la substantifique moelle du dictionnaire ! Créez un correcteur de commentaires de code AutoIt pour les abrutis qui mettent des smileys vivants à l’intérieur.