IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

WinDev Discussion :

Générer txt avec Motif


Sujet :

WinDev

  1. #1
    Membre confirmé Avatar de _shuriken_
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2006
    Messages : 543
    Points : 454
    Points
    454
    Par défaut Générer txt avec Motif
    Bonsoir tout le monde,

    J'ai un fichier Texte avec cette structure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    09:47:00 -> TRANSACTION START
    09:47:00 TRACK 2 DATA: 6765460270532722
    09:47:03 CARD(6765460270532722) TAKEN
    09:47:07 <- TRANSACTION END
    09:47:15 -> TRANSACTION START
    09:47:15 TRACK 2 DATA: 6765460270532722
    09:47:21 PIN ENTERED
    09:47:21 TRANSACTION REQUEST AAAAA   
    09:47:23 TRANSACTION REPLY NEXT 041 FUNCTION 5
    09:47:28 TRANSACTION REQUEST AAAB A A
    09:47:31 TRANSACTION REPLY NEXT 405 FUNCTION A105
    09:47:36 CASH REQUEST: 03000000
    09:47:36 CASH 1:1,3;
    09:47:39 CARD(6765460270532722) TAKEN
    09:47:42 CASH PRESENTED
      
    ========================================
       RETRAIT
      DATE      HEURE       OP.      GAB
    01/09/15  09:26:42    006006006   70010001
    N?CARTE          6765460270532722
    N?COMPTE         700001204037
    MONTANT TRX. :   XOF 30000
    N?TRX:           774916
    CODE REPONSE     000
    ========================================
    09:47:44 CASH TAKEN
    09:47:51 <- TRANSACTION END
    Le fichier contient des milliers de données qui sont sous ce format (Début d'enregistrement TRANSACTION START, fin d'enregistrement TRANSACTION END) . Je veux pouvoir parcourir chaque ligne, dès que je retrouve le motif CASH TAKEN je dois écrire les les lignes en rouges.

    J'ai commencé ce bout de code, mais je ne suis pas vraiment sûr de la logique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    idFichier est un entier
    ResFermeFichier est un entier
    sligne est une chaîne
    NomCheminFichier est une chaîne
    sval est une chaîne
    ResEcrit est un booléen = Vrai
    nBreligne est un entier = 0
     
    NomCheminFichier = "G:\Transaction.txt"
    //Transaction est une chaine
    idFichier=fOuvre(SAI_FIC,foLectureEcriture) 
    Trace(idFichier)
    SI idFichier = -1 ALORS 
    	Erreur(ErreurInfo(errMessage))
    SINON	
    	//flitligne(idFichier) 
    	sligne=fLitLigne(idFichier) 
     
    	TANTQUE sligne<>EOT 
    		nBreligne = nBreligne + 1
    		sval = sligne [[20 A 10]]
    		SI sval = "CASH TAKEN" ALORS
    			nBreligne = nBreligne-8
    			sligne=fLitLigne(nBreligne)
    			ResEcrit = fEcritLigne(idFichier,sligne)
    		FIN
     
    	FIN
     
    	SI ResEcrit = Faux ALORS Erreur(ErreurInfo(errMessage))
    	// Fermeture du fichier
    	ResFermeFichier = fFerme(idFichier)
    	SI ResFermeFichier = -1 ALORS
    		// Affichage du message d'erreur si la fermeture n'a pas été effectuée
    		Erreur(ErreurInfo(errMessage))
    	FIN 
    FIN
    Merci du coup de main.

    Cordialement,
    _shuriken_
    "When you can measure what you are speaking about, and express it in numbers, you know something about it; but when you cannot measure it, when you cannot express it in numbers, your knowledge is of a meager and unsatisfactory kind; it may be the beginning of knowledge, but you have scarcely in your thoughts advanced to the state of Science, whatever the matter may be."

    Lord Kelvin - 1883.

  2. #2
    Membre émérite
    Homme Profil pro
    Inscrit en
    Octobre 2007
    Messages
    1 075
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2007
    Messages : 1 075
    Points : 2 441
    Points
    2 441
    Par défaut
    Bonjour,

    Je vois un problème avec votre manière de faire : vous ne pouvez pas aisément revenir en arrière avec fLitLigne.
    Il faudrait mémoriser le début de chaque ligne dans un tableau glissant pour revenir en début de ligne-8 après chaque détection de "CASH TAKEN".
    Ce serait déjà mieux si vous pouviez effectuer un traitement "en avant" en travaillant avec la détection de "RETRAIT" (ligne 18 du fichier)

    En plus de cela, fLitLigne sera assez "lent", enfin comparativement à la lecture globale du fichier.

    Sauf le cas où vous craignez de saturer votre mémoire, vous pourriez donc charger le fichier d'un bloc et parcourir la chaîne résultante.
    Ce sera beaucoup plus rapide que les accès disque successifs de fLitLigne.

    A partir de votre code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
    PositionCash est un entier
    TransacDébut, TransacFin sont des entiers
    PosCR est un entier
    sTraqueCash est une chaine =  "CASH TAKEN"
    NomCheminFichier = "G:\Transaction.txt"
     
    sTransaction est une chaine = fChargeTexte(NomCheminFichier)
    Trace(Taille(sTransaction))
     
    Si sTransaction = "" ALORS
            Erreur(ErreurInfo(errMessage))
    SINON	
           PositionCash = PositionOccurence(sTransaction, sTraqueCash, RangPremier) 
           TANTQUE PositionCash <> 0
                  //Recherche des CR qui précèdent, pour "remonter" de 8 lignes
                  TransacFin = Position(sTransaction, CR, PositionCash -1, DepuisFin)
                  PosCR = TransacFin
                  POUR  i = 1 A 8 
                         PosCR = Position(sTransaction, CR, PosCr - 1, DepuisFin)
                  FIN 
                  TransacDébut = PosCR + 1
                  //
                  //Mettre en rouge de TransacDébut à TransacFin
                  //
                 PositionCash = PositionOccurence(sTransaction, sTraqueCash, RangSuivant) 
           FIN 
    fSauveTexte(NomCheminFichier, sTransaction)
    Dans l'hypothèse où on peut tester "RETRAIT", c'est encore plus simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    nOffsetRetrait est un entier = nnn
    //n étant le nombre minimum de caractères entre le R de RETRAIT et le C de Cash TAKEN
    //Si ce nombre est connu et constant, on pourrait même se passer de la recherche de TransacFin
    sTraqueRetrait  est une chaine = "RETRAIT"
    TransacDébut = PositionOccurence(sTransaction, sTraqueRetrait, RangPremier) 
    TANTQUE TransacDébut <> 0
          TransacDébut = Position(sTransaction, CR, TransacDébut, DepuisFin) + 1  //s'il faut tenir compte des espaces qui précèdent "RETRAIT" en ligne 18 du fichier exemple
          TransacFin = Position(sTransaction, sTraqueCash, TransacDébut + nOffsetRetrait)
          TransacFin = Position(sTransaction, CR, TransacFin -1, DepuisFin)
          //on va au CR qui précède "CASH TAKEN", soit la fin de la ligne précédente
          //ou TransacFin = TransacDébut + longueur connue de la chaine à mettre en rouge
          //
          //Mettre en rouge de TransacDébut à TransacFin
         //
         TransacDébut = PositionOccurence(sTransaction, sTraqueRetrait, RangPremier) 
    FIN
    Non testé, mais cela doit être (presque) bon.

    Bon travail

    Hemgé

  3. #3
    Expert éminent
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    3 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 3 954
    Points : 9 284
    Points
    9 284
    Par défaut
    hello,
    je suis entièrement d'accord avec ce que dit Hemgé :

    En plus de cela, fLitLigne sera assez "lent", enfin comparativement à la lecture globale du fichier.
    Sauf le cas où vous craignez de saturer votre mémoire
    En Windev, moins il y a de boucles, plus c'est performant.

    A titre indicatif (car la méthode à Hemgé est largement suffisante dans le cas présent) voici un traitement en utilisant les expressions régulières de Vbscript ( j'en vois déjà qui disent : tiens voilà J.P qui essaie de nous refourguer ses expressions régulières ) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    Machaine est une chaîne
    x est un entier
    regEx est un objet Automation "VBScript.RegExp"
    oMatch est un objet Automation dynamique //Match
    oMatches est un objet Automation dynamique //MatchCollection
    Machaine = fChargeTexte("F:\temp\CashTest.txt")
    regEx>>Global = Vrai
    regEx>>MultiLine = False
    // Le motif correspond à ce qui est encadré par une série de 40=
    regEx>>Pattern = "={40}((.|\n)+?)={40}"
    oMatches = regEx>>Execute(Machaine)
    // on balaie toutes les occurrences trouvées
    POUR x = 0 _A_ oMatches>>Count - 1
    oMatch = oMatches>>Item(x)
    Trace("Retrait ",x," : " + RC,oMatch>>Submatches(0))
    FIN
    Cela donne une base de départ pour un cas plus complexe à traiter.

    Ami calmant, J.P
    Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

  4. #4
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2004
    Messages
    2 329
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 329
    Points : 3 841
    Points
    3 841
    Par défaut
    Bonjour,

    Pour ma part, je suis partisan du fLitLigne(), tout simplement pour cette histoire de taille de fichier.
    J'ai eu un cas où les fichiers faisaient plusieurs 100 Mo, avec une machine survitaminée (8coeurs, 16Go) et ça ramait comme pas possible, sans parler des plantages qui arrivaient de temps à autre.

    Je suis donc passé à du fLitLigne(), ce qui m'a réglé mon problème.
    L'avantage que j'y vois est que l'on a pas à s'occuper de la taille du fichier à traiter.

    Pour en revenir au sujet, je vois un motif CASH PRESENTED avant les lignes rouges.
    Ne pourrais-tu pas déclencher le traitement des lignes rouges à partir de ce motif, et de l'arrêter au motif CASH TAKEN ?

  5. #5
    Membre émérite
    Homme Profil pro
    Inscrit en
    Octobre 2007
    Messages
    1 075
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2007
    Messages : 1 075
    Points : 2 441
    Points
    2 441
    Par défaut
    Ce n'est pas que " J.P ... essaie de nous refourguer ses expressions régulières", c'est qu'il nous revient avec son objet Automation !
    Ceci étant, j'aime aussi utiliser les expressions régulières et reconnais les limitations de Windev dans ce domaine.
    Je n'ai pas encore fait le saut vers cet objet que je devrais apprendre, sans doute.

    J'ignore pourquoi, mais j'ai considéré que les lignes 17 et 26 (répétition de =) avaient été ajoutées à notre intention ...
    Evidemment, si elles font partie du fichier, il faut s'en servir.

    Si on en reste au fLitLigne, alors Windev possède la fonction fLitLigneExpressionRégulière().

  6. #6
    Membre confirmé Avatar de _shuriken_
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2006
    Messages : 543
    Points : 454
    Points
    454
    Par défaut
    Salut Hemgé,

    Avec RETRAIT, j'ai ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    //nPositionCash est un entier
    TransacDébut, TransacFin sont des entiers
    //nPosCR est un entier
    sTraqueCash est une chaîne =  "CASH TAKEN"
    NomCheminFichier est une chaîne = "G:\Transaction.txt"
     
    sTransaction est une chaîne = fChargeTexte(NomCheminFichier)
    //Trace(Taille(sTransaction))
     
    nOffsetRetrait est un entier = 282
    //n étant le nombre minimum de caractères entre le R de RETRAIT et le C de Cash TAKEN
    //Si ce nombre est connu et constant, on pourrait même se passer de la recherche de TransacFin
    sTraqueRetrait  est une chaîne = "RETRAIT"
    TransacDébut = PositionOccurrence(sTransaction, sTraqueRetrait, rangPremier) 
    TANTQUE TransacDébut <> 0
    	TransacDébut = Position(sTransaction, CR, TransacDébut, DepuisFin) + 1  //s'il faut tenir compte des espaces qui précèdent "RETRAIT" en ligne 18 du fichier exemple
    	TransacFin = Position(sTransaction, sTraqueCash, TransacDébut + nOffsetRetrait)
    	TransacFin = Position(sTransaction, CR, TransacFin -1, DepuisFin)
    	//on va au CR qui précède "CASH TAKEN", soit la fin de la ligne précédente
    	//ou TransacFin = TransacDébut + longueur connue de la chaine à mettre en rouge
    	//
    	//Mettre en rouge de TransacDébut à TransacFin
    	//
    	TransacDébut = PositionOccurrence(sTransaction, sTraqueRetrait, rangPremier)
     
    FIN
    fSauveTexte(NomCheminFichier, sTransaction)
     
    Info("Fichier géneré")
    Le n de nOffsetRetrait est connu et constant, j'ai compté le nombre exact de caractères est bien 282. Le programme ne retourne pas les bonnes valeurs.

    J'ai aussi testé avec le CASH TAKEN idem :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    PositionCash est un entier
    TransacDébut, TransacFin sont des entiers
    PosCR est un entier
    sTraqueCash est une chaîne =  "CASH TAKEN"
    NomCheminFichier est une chaîne = "G:\Transaction.txt"
     
    sTransaction est une chaîne = fChargeTexte(NomCheminFichier)
    //Trace(Taille(sTransaction))
     
    SI sTransaction = "" ALORS
    	Erreur(ErreurInfo(errMessage))
    SINON	
    	PositionCash = PositionOccurrence(sTransaction, sTraqueCash, rangPremier) 
    	TANTQUE PositionCash <> 0
    		//Recherche des CR qui précèdent, pour "remonter" de 8 lignes
    		TransacFin = Position(sTransaction, CR, PositionCash -1, DepuisFin)
    		PosCR = TransacFin
    		POUR  i = 1 A 8 
    			PosCR = Position(sTransaction, CR, PosCR - 1, DepuisFin)
    		FIN 
    		TransacDébut = PosCR + 1
    		//
    		//Mettre en rouge de TransacDébut à TransacFin
    		//
    		PositionCash = PositionOccurrence(sTransaction, sTraqueCash, rangSuivant) 
    FIN 
    	fSauveTexte(NomCheminFichier, sTransaction)
    FIN
    Merci d'avance,
    _shuriken_
    "When you can measure what you are speaking about, and express it in numbers, you know something about it; but when you cannot measure it, when you cannot express it in numbers, your knowledge is of a meager and unsatisfactory kind; it may be the beginning of knowledge, but you have scarcely in your thoughts advanced to the state of Science, whatever the matter may be."

    Lord Kelvin - 1883.

  7. #7
    Membre émérite
    Homme Profil pro
    Inscrit en
    Octobre 2007
    Messages
    1 075
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2007
    Messages : 1 075
    Points : 2 441
    Points
    2 441
    Par défaut
    Citation Envoyé par _shuriken_ Voir le message
    Le programme ne retourne pas les bonnes valeurs.
    Mais encore ? Il ampute de combien de caractères ? Que sélectionne-t-il ?
    Ma boule de cristal n'est pas assez performante pour voir si loin...

    Citation Envoyé par _shuriken_ Voir le message
    Le n de nOffsetRetrait est connu et constant, j'ai compté le nombre exact de caractères est bien 282.
    282 caractères y compris les caractères invisibles notamment les retours de ligne (CR ou plus probablement CR + LF en fin de chaque ligne, soit 8 x 1 ou 8 x 2) ?
    A comparer avec le nombre de caractères amputés.
    Pour avoir une idée plus fiable, plutôt que de compter, il vous suffit de demander les positions de RETRAIT et de CASH. Leur différence vous fournira une nombre précis et exact qui vous permettra d 'extrapoler.

    Citation Envoyé par _shuriken_ Voir le message
    J'ai aussi testé avec le CASH TAKEN idem
    Il y a me semble-t-il une erreur dans la boucle de recherche de CR. Au lieu de 8 cela doit être 9, ou 7 si les lignes de séparation 17 & 26 ne font pas partie du fichier et ne sont que des ajouts pour nous faciliter le repérage des informations.
    Mais cela, vous devriez le corriger aisément, soit en regardant quelle valeur le code vous retourne, soit en variant la valeur de i.

    Par ailleurs, est-ce que les lignes de "=" (17 & 26) font réellement partie du fichier ?
    Si c'est le cas, cela vaudrait la peine de travailler sur cette base. Le code serait plus clair pour l'avenir.

  8. #8
    Expert éminent
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    3 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 3 954
    Points : 9 284
    Points
    9 284
    Par défaut
    hello,
    avec ce motif et mon objet automation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    // Le motif correspond à ce qui commence par RETRAIT
    // et dont la dernière ligne contient CODE
     regEx>>Pattern = "(RETRAIT(.|\n)+?CODE.+\n)"
    j'arrive à capturer l'ensemble des lignes comprises entre les ===== .
    J'ai essayé avec un fichier de 2000 retraits ( 1,8 Mo ) . Je récupère bien tous les retraits dans un temps plus que raisonnable ( 72 ms en enlevant l'affichage par trace).

    Ami calmant, J.P
    Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

  9. #9
    Membre émérite
    Homme Profil pro
    Inscrit en
    Octobre 2007
    Messages
    1 075
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2007
    Messages : 1 075
    Points : 2 441
    Points
    2 441
    Par défaut
    Citation Envoyé par jurassic pork Voir le message
    hello,
    avec ce motif et mon objet automation :mouarf: :
    On en remet donc une couche ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    bRouge est un booléen
    nCompteur est un entier 
     
    sTransaction est une chaîne = fChargeTexte(NomCheminFichier)
     
    POUR TOUTE CHAÎNE sArg DE sTransaction SÉPARÉE PAR RC 
    	SI PAS bRouge _ET_ VérifieExpressionRégulière(sArg, "[=]{40}") ALORS 	 
    		bRouge = Vrai
    		nCompteur ++
    	SINON 
    		SI bRouge _ET_ VérifieExpressionRégulière(sArg, "[=]{40}") ALORS bRouge =Faux 
    	FIN	
    FIN
    Info("Compteur = " + nCompteur)

    Mais, comme déjà écrit dans une autre discussion antérieure, je reste d'avis que ceux qui ne comprennent pas les expressions régulières ne doivent pas adopter les solutions que nous exposons ici, car ils ne seront pas à même de gérer d'éventuels problèmes ou l'évolution de leur soft.

Discussions similaires

  1. Modifier un fichier txt avec FSO?
    Par flo456 dans le forum ASP
    Réponses: 6
    Dernier message: 25/10/2005, 22h16
  2. probleme d'import de fichier txt avec des tab
    Par lecureuil dans le forum Access
    Réponses: 4
    Dernier message: 23/08/2005, 19h22
  3. lire et changer le contenu d'texte.txt avec javascript?!
    Par Squalli dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 11/08/2005, 18h20
  4. Creer un fichier txt avec la date du jour
    Par quarkz dans le forum Débuter
    Réponses: 8
    Dernier message: 28/07/2005, 17h29
  5. Pb import fichier txt avec lignes de longueurs diverses
    Par zebulon90 dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 09/12/2004, 08h32

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo