Page 2 sur 2

Re: extraire données d'une liste depuis une ou plusieurs autres

Posté : sam. 09 févr. 2019 22:25
par mikell
Si tu veux utiliser plusieurs fichiers d'exclusion, utilise la fonctionnalité la plus intéressante de "Scripting.Dictionary" : l'élimination des doublons. L'idée :
- tu lis chaque fichier .txt d'exclusion dans une array avec FileReadToArray
- tu crées un dico "exclusions", et tu le remplis en parcourant successivement ces arrays (boucles For). Les doublons seront automatiquement éliminés
- ensuite comme dans mon code précédent, tu nettoies le dico "liste" en parcourant le dico "exclusions"
Ouala Image

Re: extraire données d'une liste depuis une ou plusieurs autres

Posté : lun. 11 févr. 2019 09:31
par fredmame
Hello,


Voici ci dessous le code que j'ai réussi à avancer :

en me basant bien sur sur ton code, j'ai ajouté quelques options.
Pour l'instant : 1 fichier à filtrer et 1 filtre : ca marche.

pour 1 fichier à filtrer mais plusieurs filtres je n'arrive pas:
la fonction fileopendialog me sort une chaine ainsi : patch\nomfichier.txt|autre_fichier.txt

j'ai alors fait un tableau qui récupere les données, supprime la 1ere ligne (celle qui compte les lignes) avec arraydelete
ensuite je compte combien il reste de lignes
ainsi la 1ere ligne est le path
les suivantes sont les noms des fichiers

l'idée est ensuite d'arriver à creer un tableau qui puisse justement concatener les valeurs de ces fichiers.

J'ai bien trouvé un code mais je n'arrive pas à passer les chemins variables en lecture :
Dim $avFiles[5] = [$test] ne marche pas avec $test = $chemin & $chemin2
j'ai essayé plein de combinaisons et je n'arrive pas

Ca coince là, car si j'arrive à passer du "fileopen" =>tableau qui liste les noms de fichier filtres=>concatene les données

je peux réinjecter ca dans ton code final de filtrage.


d'ailleurs ce qui est bizarre, c'est pourquoi fileopen ne donne pas des path completes séparées ?
bizarre de devoir passer par un stringsplit puis tableau pour filtrer les chemins et les reconstruire...


:
#include <FileConstants.au3>
#include <MsgBoxConstants.au3>
#include <Array.au3>
#include <File.au3>


;mon essai avec cette variable mais dans l'exemple qui marche y'a pas Ca
;https://www.autoitscript.com/forum/topic/37866-read-multiple-files-into-1-array/



$chemin = "C:\Users\Admin\OneDrive\tri par autoit\filtre1.txt"
$chemin2 = "C:\Users\Admin\OneDrive\tri par autoit\filtre2.txt"
$test = $chemin & $chemin2 ; marche pas



;Dim $avFiles[5] = [$chemin , $chemin2] ; ca fonctionne

Dim $avFiles[5] = [$test] ; marche pas
Dim $sString = ""
For $n = 0 To UBound($avFiles) - 1
    $sString &= FileRead($avFiles[$n], FileGetSize($avFiles[$n]))
    If StringRight($sString, 2) <> @CRLF Then $sString &= @CRLF
Next
$avLines = StringSplit($sString, @CRLF, 1)

_ArrayDisplay($avLines, "Displaying " & $avLines[0] & " lines from " & UBound($avFiles) & " files.")






#include <FileConstants.au3>
#include <MsgBoxConstants.au3>
#include <Array.au3>
#include <File.au3>

Func_depart()

Func Func_depart()

 ; Crée une constante locale avec le message à afficher dans FileOpenDialogAFILTRER.
    Local Const $sMessage1 = "A FILTRER : choisir le fichier"

    ; Ouvre une boîte de dialogue  pour sélectionner une liste de fichier(s) qui seront le ou les filtres
    Local $sFileOpenDialogAFILTRER = FileOpenDialog($sMessage1, @WorkingDir & "\", "txt ou ini (*.ini;*.txt)", $FD_FILEMUSTEXIST)
    If @error Then
        ; Affiche le message d'erreur.
        MsgBox($MB_SYSTEMMODAL, "", "Aucun fichier sélectionné.")
   EndIf




    ; Crée une constante locale avec le message à afficher dans FileOpenDialogFILTRES.
    Local Const $sMessage2 = "FILTRES : Appuyez sur Ctrl ou Shift pour choisir plusieurs fichiers"

    ; Ouvre une boîte de dialogue  pour sélectionner une liste de fichier(s) qui seront le ou les filtres
    Local $sFileOpenDialogFILTRES = FileOpenDialog($sMessage2, @WorkingDir & "\", "txt ou ini (*.ini;*.txt)", $FD_FILEMUSTEXIST + $FD_MULTISELECT)
    If @error Then
        ; Affiche le message d'erreur.
        MsgBox($MB_SYSTEMMODAL, "", "Aucun fichier sélectionné.")

    Else
      ; Change le répertoire de travail (@WorkingDir) vers l'emplacement du répertoire de script comme FileOpenDialog l'a défini au dernier dossier consulté.
        FileChangeDir(@ScriptDir)

    EndIf


 func_suite($sFileOpenDialogFILTRES,$sFileOpenDialogAFILTRER)

;fin de la selection des différents fichiers

EndFunc


;ca va mettre dans un tableau toute la selection
;mais le tableau affiche dans la 1ere ligne (numerotée zero) le nombre total d'éléments
;il faut alors juste recuperer les données path (chemin) et ensuite chaque nom de fichier

Func func_suite($sFileOpenDialogFILTRES,$sFileOpenDialogAFILTRER)

;Diviser la chaîne de path en utilisant le délimiteur "|" et la valeur de flag par défaut.
Local $aPath = StringSplit($sFileOpenDialogFILTRES, "|")

_ArrayDisplay($aPath,"Tableau non traité") ;affichage tableau non traité avec le listing des noms des fichiers de filtres
_ArrayDelete($aPath, 0) ;supprimer la 1ere ligne numérotée zero
_ArrayDisplay($aPath, "ligne 0 du tableau supprimée pour enlever le compteur") ; affichage du tableau avec la ligne zero en moins (celle qui affiche le nombre de lignes mais ne sert a rien)




;essai divers marche pour plusieurs fichiers selectionnés

;MsgBox(0, "test affichage","le contenu est " & _ArrayToString($aPath," ainsi que " , 0, 4)) ; affiche le contenu du tableau de la ligne 0 à 4

;$sString_Indirect = ""
;For $i = 2 To 4 ; affiche le contenu de la ligne 2 à 4
  ;  $sString_Indirect &= '"' & $aPath[$i] & '" ' ; ca affiche entre des " chaque contenu de ligne
;Next

;MsgBox(0, "test affichage par boucle de ligne 2 à 4", $sString_Indirect)

;fin essais divers



; calcul du nombre de lignes dans le tableau

Local $iRows = UBound($aPath, $UBOUND_ROWS) ;
MsgBox($MB_SYSTEMMODAL, "coucou", "le tableau contient exactement " & _
            $iRows & " ligne(s) ")

   MsgBox($MB_SYSTEMMODAL, "Path épurée", _ArrayToString($aPath,"",0,0) ) ; affiche juste le conteu de la ligne 0 à 0 on peut supprimer le ,0 à la fin

   $Pathok =  _ArrayToString($aPath,"",0,0)

If $iRows = 1 Then
   MsgBox ($MB_SYSTEMMODAL,"unique", "il y a un seul fichier donc  " &  @CRLF & $Pathok  & @CRLF & " sera le chemin avec le nom")

Else



   $sLesfichiers = ""
 For $i = 1 To $iRows - 1
    $sLesfichiers &= '"' & $aPath[$i] & '",' ; ca va creer une chaine de cette forme "nomdufichier","nom_autre",


Next
   $sLesfichiersmod = StringTrimRight ($sLesfichiers, 1) ; ca recrée la chaine avec les noms mais sans la derniere virgule (stringsplitright enleve 1 caractere )
MsgBox(0, "creation de la ligne des noms", $sLesfichiers)
MsgBox(0, "creation de la ligne des noms modifiés", $sLesfichiersmod)

   MsgBox ($MB_SYSTEMMODAL,"multiple", "il y a plusieurs fichiers donc le chemin sera :" & @CRLF & $Pathok & @CRLF & "et les fichiers seront" & @CRLF & $sLesfichiersmod )

EndIf



;ici le traitement des données



;pour 1 seul fichier filtre
if $iRows = 1 Then
    $sFileOpenDialog2 =  '"' & $Pathok  & '"'
   MsgBox ($MB_SYSTEMMODAL," pour voir" , $sFileOpenDialog2 )

Else

;pour plusieurs fichiers filtres
   ;il faut faire une boucle pour creer  une chaine path noms mais comment mettre dans le array plusieurs fichiers ???
   ;voir fonction arrayadd





EndIf


$aList = FileReadToArray ( $sFileOpenDialogAFILTRER) ; liste
 _ArrayDisplay($aList,"contenu working à filtrer")


; pour voir ce qui est en données
MsgBox ($MB_SYSTEMMODAL," pour voir si c'est bien entre guillemets" , $sFileOpenDialog2 )


If $iRows= 1 Then

$aExcl = FileReadToArray(  $Pathok) ; exclusions attention le chemin lorsqu'il est dans une variable ne doit pas avoir de guillemets
 _ArrayDisplay($aExcl,"A supprimer")

Else

; ici il faut utiliser une boucle qui prend la liste des fichiers txt et les mets en 1 seul tableau
   Dim $avFiles[5] = ;ICI IL FAUDRAIT ARRIVER A METTRE LA LISTE DES FICHIERS FILTRES
Dim $sString = ""
For $n = 0 To UBound($avFiles) - 1
    $sString &= FileRead($avFiles[$n], FileGetSize($avFiles[$n]))
    If StringRight($sString, 2) <> @CRLF Then $sString &= @CRLF
Next
$avLines = StringSplit($sString, @CRLF, 1)

_ArrayDisplay($avLines, "Displaying " & $avLines[0] & " lines from " & UBound($avFiles) & " files.")

EndIf






; construction du dictionnaire
$sdList = ObjCreate("Scripting.Dictionary")
For $i In $aList
    $sdList.Item($i)
Next

; suppression dans le dico des éléments présents dans les exclusions
For $i In $aExcl
    If $sdList.Exists($i) Then $sdList.Remove($i)
Next

; lecture du dico nettoyé dans une array
$asdList = $sdList.Keys()
_ArrayDisplay("hide",$asdList)


;sauvegarde du resultat
$sFile = FileSaveDialog("Enregistrer sous...", @ScriptDir, "Text Files (*.txt) |  ini Files (*.ini) | All Files (*.*)", 18, "")
If @error Then Exit

$sString = _ArrayToString($asdList , @crlf, Default, Default, @CRLF)

FileWrite($sFile, $sString)





 EndFunc
















 

Re: extraire données d'une liste depuis une ou plusieurs autres

Posté : lun. 11 févr. 2019 11:25
par mikell
Ce code est une variante du précédent
J'ai séparé les rubriques, commenté, laissé des _ArrayDisplay et des parties "visualisation" pour la compréhension
C'est vite fait, ça peut dans doute être optimisé

#include <File.au3>
#Include <Array.au3>


$sMessage1 = "A FILTRER : choisir le fichier"
$sFichierListe = FileOpenDialog($sMessage1, @WorkingDir & "\", "txt ou ini (*.ini;*.txt)", $FD_FILEMUSTEXIST)
    If @error Then
        MsgBox($MB_SYSTEMMODAL, "", "Aucun fichier sélectionné.")
   EndIf
Msgbox(0,"fichier liste", $sFichierListe)
FileChangeDir(@ScriptDir)

$sMessage2 = "FILTRES : Appuyez sur Ctrl ou Shift pour choisir plusieurs fichiers"
$sFileOpenDialogFILTRES = FileOpenDialog($sMessage2, @WorkingDir & "\", "txt ou ini (*.ini;*.txt)", $FD_FILEMUSTEXIST + $FD_MULTISELECT)
    If @error Then
        MsgBox($MB_SYSTEMMODAL, "", "Aucun fichier sélectionné.")
   EndIf
FileChangeDir(@ScriptDir)

;---------------------------------------------

; création de la liste des fichiers filtre
$aTmp = StringSplit($sFileOpenDialogFILTRES, "|")
;_ArrayDisplay($aTmp, "tmp filtre")
Local $aFiltres[$aTmp[0]-1]
For $i = 2 to $aTmp[0]
   $aFiltres[$i-2] = $aTmp[1] & "\" & $aTmp[$i]
Next
_ArrayDisplay($aFiltres, "fichiers filtre")

;-----------------------------------

; construction du dictionnaire liste
$sdList = ObjCreate("Scripting.Dictionary")

; lecture du fichier liste
$aList = FileReadToArray($sFichierListe) ; liste
 _ArrayDisplay($aList, "liste initiale")
; et ajout dans le dico liste
For $i In $aList  
    $sdList.Item($i)
Next

; visualisation du dico liste
$asdList = $sdList.Keys()
_ArrayDisplay($asdList, "dico liste")

;----------------------------------------

; construction du dictionnaire exclusions
$sdExcl = ObjCreate("Scripting.Dictionary")

For $i = 0 to UBound($aFiltres) -1
           ; lecture de chaque fichier filtre
    $aExc = FileReadToArray($aFiltres[$i])
    ; _ArrayDisplay($aExc)
            ; et ajout dans le dico exclusions
    For $k In $aExc
        $sdExcl.Item($k)
    Next
Next

; visualisation du dico exclusions final
$asdExcl = $sdExcl.Keys()
_ArrayDisplay($asdExcl, "dico exclusions")

;----------------------------------------------------

; suppression dans le dico liste des éléments du dico exclusions
For $i In $sdExcl
    $sdList.Remove($i)
Next

; lecture du dico nettoyé dans une array
$asdList = $sdList.Keys()
_ArrayDisplay($asdList, "résultat final")

 

Re: extraire données d'une liste depuis une ou plusieurs autres

Posté : lun. 11 févr. 2019 19:00
par Tlem
Bonsoir.
Pour la circonstance, je vais proposer une solution différente qui me semble (ce n'est qu'un avis) un peu plus simple.
  1. On lit le fichier à traiter dans un tableau.
  2. Avec le/les fichiers de filtrage, on crée une chaine ou chaque élément est séparé par un séparateur unique dans le but d'avoir des noms uniques pour la recherche avec StringInStr.
  3. On lit le tableau du fichier à traiter de la fin vers le début afin de pouvoir supprimer au fur et à mesure les éléments contenus dans le filtre.

Voici un code grossier qui d'après mes tests semble fonctionner.

Code : Tout sélectionner

#include <File.au3>
#Include <Array.au3>

Local $sFodFILE, $aFodFILE, $sFodFILTRES, $aFodFILTRES, $sFilter

; Sélection du fichier à filtrer.
$sFodFILE = FileOpenDialog("Sélectionnez le fichier à filtrer", @WorkingDir & "\", "txt (*.txt)", $FD_FILEMUSTEXIST + $FD_MULTISELECT)
If @error Then
	MsgBox($MB_SYSTEMMODAL, "", "Aucun fichier sélectionné.")
	Exit
EndIf
; Transformation du résultat en tableau.
$aFodFILE = FileReadToArray($sFodFILE)


; Sélection du/des fichiers de filtrage.
$sFodFILTRES = FileOpenDialog("Sélectionnez un ou plusieurs fichiers de filtrage", @WorkingDir & "\", "txt (*.txt)", $FD_FILEMUSTEXIST + $FD_MULTISELECT)
If @error Then
	MsgBox($MB_SYSTEMMODAL, "", "Aucun fichier sélectionné.")
	Exit
EndIf
; Transformation du résultat en tableau.
$aFodFILTRES = StringSplit($sFodFILTRES, "|")


; Cette partie de code va transformer la liste des filtres afin d'obtenir une chaine du genre : |a.zip|b.zip|c.zip|e.zip|
; Cette chaine nous servira pour la comparaison. Le fait qu'il puisse y avoir des doublons dans les noms n'a pas d'importance
; car la recherche va se faire avec StringInStr(), d'ou l'obligation d'utiliser des séparateurs afin d'avoir des noms unique.
If $aFodFILTRES[0] = 1 Then
	; Lecture et transformation du fichier sélectionné dans $sFilter
	$sFilter = StringReplace('|' & Fileread($aFodFILTRES[1]) & @CRLF, @CRLF, '|')
Else
	; Lecture, fusion et transformation des fichiers du tableau.
	For $i = 2 to UBound($aFodFILTRES) - 1
		$sFilter &= StringReplace('|' & Fileread($aFodFILTRES[1] & "\" & $aFodFILTRES[$i]) & @CRLF, @CRLF, '|') ; Lecture du fichier sélectionné dans $sFilter
	Next
		$sFilter = StringReplace($sFilter, '||', '|') ; Cette ligne est juste pour le fun et éviter les doublons ||
EndIf


; Lecture du tableau depuis la fin jusqu'au début en supprimant les éléments contenus dans le filtre.
For $i = UBound($aFodFILE) - 1 To 0 step -1
	If StringInStr($sFilter, $aFodFILE[$i]) Then _ArrayDelete($aFodFILE, $i)
Next

_ArrayDisplay($aFodFILE)

Re: extraire données d'une liste depuis une ou plusieurs autres

Posté : lun. 11 févr. 2019 19:32
par fredmame
bonsoir et merci pour tout ce que tu as fait
j'ai passé tellement d'heures là dessus.
mais ca permet d'apprendre, de piocher des idées, d'essayer de comprendre...
je viens de finir ma journée de boulot, je vais regarder, comprendre et tester .
Encore merci pour cette aide si précieuse...

Re: [résolu] extraire données d'une liste depuis une ou plusieurs autres

Posté : mer. 13 févr. 2019 21:51
par fredmame
je me suis permis de supprimer le " + $FD_MULTISELECT" ligne 7 car c'est un fichier unique

et ajouter le code pour enregistrer le fichier final.
Si j'ai le courage, je pourrais me lancer dans l'aventure d'un GUI mais bon, c'est encore une aventure...


le code est une turie, c'est exactement ce que je cherchais à faire.

y a t'il une subtilité/regle lors de l'écriture $a et $s dans le code : j'entends sur l'usage de la lettre a ou s ?

Re: [résolu] extraire données d'une liste depuis une ou plusieurs autres

Posté : mer. 13 févr. 2019 22:13
par Tlem
Bonsoir.
Oui il y a bien une subtilité qui est juste une "convention".

Cette "convention" préconise qu'une variable soit prefixés par "s" soit la première lettre du mot String qui signifie chaîne en anglais et par "a" pour indiquer qu'il s'agit d'un tableau (Array en anglais).

Il me semble que ce sujet a déjà été abordé et qu'il faisait référence à un ou plusieurs liens concernant les conventions de nommage des variables en informatique.

Edit : J'ai retrouvé ceci : https://fr.wikipedia.org/wiki/Notation_hongroise
Cela vous donnera une très bonne base. ^^