Compter des lignes par paquet (split?)

cs_darkbol Messages postés 61 Date d'inscription lundi 7 juin 2004 Statut Membre Dernière intervention 6 décembre 2004 - 5 juil. 2004 à 10:24
cs_darkbol Messages postés 61 Date d'inscription lundi 7 juin 2004 Statut Membre Dernière intervention 6 décembre 2004 - 12 août 2004 à 09:58
Salut

Je bloque vraiment sur ma conversion de fichier.

Je m'explique :

Je voudrais remplacer "l'entête" de chaque paquet de valeurs par le nb de lignes dudit paquet.

ex :

->0004
507210.7 6245180.0
507207.6 6247034.5
511326.2 6247043.5
511331.1 6245188.5
507210.7 6245180.0

transformation...

5
507210.7 6245180.0
507207.6 6247034.5
511326.2 6247043.5
511331.1 6245188.5
507210.7 6245180.0

alors j'ai testé ca :

Do While Not EOF(1)
       
Line Input #1, Tempo

Dim nbrlig As Long
Dim tem As String
Dim i As Long
If Asc(Left$(Tempo, 1)) 45 Or Asc(Left$(Tempo, 1)) 9 Then
Print #2, Tempo
End If

nbrlig = 0
Do While Not EOF(2)
Line Input #2, Tempo
tem = Split(Tempo, Chr$(45))
For i = 0 To 5000
If Asc(Left$(tem(i), 1)) = Chr$(9) Then
nbrlig = nbrlig + 1

Else
Tempo = Replace(Tempo, , nbrlig & String(5, Chr$(9)), 1, 1)
End If

Print #3, Tempo
Loop
Loop


je dirai que c le fruit de ma réflexion la plus poussée mais ca marche pas trop car mon tem(i) ne prend pas les blocs en question (debug print maffiche qu'une ligne pê du au print line)... enfin plus c complexe plus je me perds....

Comment faire pour avoir la separation des blocs plus propre afin d'en remplacer "l'entête"? Ou alors quelle autre méthode y a til ?

merci pour le coup de main pasque je peine vraiment....

A +

"j'aime bien compter ... :-|

22 réponses

cs_liquide Messages postés 1016 Date d'inscription samedi 22 mars 2003 Statut Membre Dernière intervention 24 juin 2008
5 juil. 2004 à 13:39
bien effectivement tu peux utiliser le "split"

j'ai fait un essai sur un fichier, j'ai un textbox en multiligne :

Dim Chaine As String
    Dim Splitage() As String
    
    Open App.Path & "\config.txt" For Input As #2
        Chaine = StrConv(InputB(LOF(2), 2), vbUnicode)
    Close #2

    Splitage() = Split(Chaine, vbCrLf)
    Text1.Text = UBound(Splitage()) + 1 & vbCrLf & Chaine


bonne prog
liquide
0
cs_darkbol Messages postés 61 Date d'inscription lundi 7 juin 2004 Statut Membre Dernière intervention 6 décembre 2004
6 juil. 2004 à 09:42
On m'a très justement fait remarquer ma mauvaise déclaration de mon tem()...

Par contre je ne comprends ce que affiche la texte box; la concaténation du max de blocs séparés par un retour chariot (+1?), d'un autre ret char et de chaine.

Je ne suis pas non plus sur d'avoir compris ce que contient Chaine. Pour moi (et mon humble nivo), c un string à partir du contenu de #2 au préalable converti en binaire pou avoir un bloc...

Do While Not EOF(1)
       
' Récupère la ligne de texte du 1er fichier
Line Input #1, Tempo

Dim nbrlig As Long
Dim tem() As String
Dim i As Long
If Asc(Left$(Tempo, 1)) 45 Or Asc(Left$(Tempo, 1)) 9 Then
Print #2, Tempo
End If
Loop
Close #2

Open "H:\Surfin project of the fire\Charisma2Surfer\test01.bln" For Input As #2
Line Input #2, Tempo

Do While Not EOF(2)
nbrlig = 0
tem = Split(Tempo, Chr$(62))
For i = 0 To UBound(tem())
If Asc(Left$(tem(i), 1)) = 9 Then
nbrlig = nbrlig + 1

Else
Tempo = Replace(Tempo, , nbrlig & String(5, Chr$(9)), 1, 1)
nbrlig = 0
End If
Next
Print #3, Tempo
Loop


dans mon cas les blocs que je désire séparer sont plusieurs lignes (conme sur l'ex cité plus haut) avec "l'entête". Et je commence à douter : j'ai essayé de spliter entre les chr$(45) mais Ubound me donne 1(??) et mon if ne prend pas non plus.

Dans ce cas, left et tem() seraient ils incompatibles?

merci

"j'aime bien convertir... :-|
0
cs_liquide Messages postés 1016 Date d'inscription samedi 22 mars 2003 Statut Membre Dernière intervention 24 juin 2008
6 juil. 2004 à 11:05
salut,

- Chaine contient le fichier entier a ouvrir
- La tetxbox contient : 1) le nombre de lignes 2) le string "Chaine", pour exemple, il n'est la que pour afficher ce que donne ton fichier apres "conversion" si tu le sauvegardes. ce n'est qu'un test visuel.

par contre je pensais que ton entete du nombre de ligne n'existait pas et qui fallait la créer.
d'ou mon :Text1.Text = UBound(Splitage()) + 1 & vbCrLf & Chaine

si tu veux spliter, essais le vbcrlf ou le chr$(13)

le ubound est la taille maxi du split, j'ai incrémenter de 1 car je ne savais pas que l'entete existait deja et dans l'exemple je la crée. le ubound prend la taille maxi du tableau c'est a dire que ton tableau commence a 0 et va jusqu'au maxi, mais en fait la "taille 0" compte pour 1 valeur mais elle n'est jamais interpreter dans un "comptage"

nous comptons une valeur 1 pour ---> 1
or split compte une valeur 0 pour ----> 1
on a donc toujours une difference de 1 avec le split

en prenant le fait que ton entete existe avec ton exemple:
tu as en realité 6 lignes. Quand tu vas spliter, le ubound va te donner une valeur de 5(c'est la valeur que tu souhaites obtenir). Je prend toujours un textbox pour visualiser le résultat.

Dim Chaine As String
Dim Splitage() As String
Dim ChaineInter as String
Dim i as Integer

Open "H:\Surfin project of the fire\Charisma2Surfer\test01.bln" For Input As #2
Chaine = StrConv(InputB(LOF(2), 2), vbUnicode)
Close #2

Splitage() = Split(Chaine, vbCrLf)
ChaineInter = UBound(Splitage())
For i = 1 to UBound(Splitage())
ChaineInter = ChaineInter & VbCrLf & Splitage(i)
Next i

Text1.Text = ChaineInter


bonne prog
liquide
0
cs_darkbol Messages postés 61 Date d'inscription lundi 7 juin 2004 Statut Membre Dernière intervention 6 décembre 2004
6 juil. 2004 à 13:50
Eh bien fait c à demi vrai, il y a déjà un entête mais ce n'est pas le bon et je voudrais le remplacer par un autre : le nombre de lignes. C pr ca qu'à la base je splite avec chr(45), vaut il mieux splitter par ligne?

Ma maniere de le voir cété de splitter par bloc pr compter y le nombre de lignes et en remplacer l'entete... comme on peut le voir sur mon petit code bien naif...

A quel point est il faux d'ailleurs? Car qd je le lance, il plante tout simplement, j'aurais encore préféré un message d'erreur...

Merci de m'aider à y voir clair ds mon code car je crois que je m'emmêle bcq les pinceaux...

Do While Not EOF(2)
nbrlig = 0
tem = Split(Tempo, Chr$(13))
For i = 0 To UBound(tem())
    If Asc(Left$(tem(i), 1)) = 9 Then
    nbrlig = nbrlig + 1
        If Asc(Left$(tem(i), 1)) = 45 Then
        Tempo = Replace(tem(i), nbrlig & String(5, "") & Chr$(13), 1, 1)
        nbrlig = 0
        End If
    End If
Next i
loop

Print #3, Tempo


"j'aime bien ... :-|
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_liquide Messages postés 1016 Date d'inscription samedi 22 mars 2003 Statut Membre Dernière intervention 24 juin 2008
6 juil. 2004 à 14:37
tu as plusieurs entetes dans ton fichier ou une seule ?
est ce qu'il y a plusieurs blocs ou 1 seul ?
Dans le cas ou tu as plusieurs blocs, le code de séparation est le chr$(45) ?
le chr$(45) équivaut au "-" c'est bien le cas dans ton fichier ?

l'exemple que je te donne est pour un seul bloc, puisque dans l'intitulé du message il n'y en avait qu'un à detailler et a compter.

pour ton code, tu parcours ton fichier, alors tu n'as pas besoin de le spliter forcement(do while not ...). si tu split, split sans parcourir ton fichier, il faut spliter tout ton fichier en un seul bloc.
regarde si tem est bien déclarer en : dim tem() as string
dans ton code tu cherches le "-" chr$(45) (à moins que ce soit le ->) et la "tabulation"chr$(9), mais je n'en vois pas dans l'exemple

essais de donner plus d'info et aussi, travaille plutot avec l'ouverture du fichier comme je te l'ai donné "chaine", je ne pense pas que le parcours comme tu le fais soit necessaire dans l'etat actuel.

bonne prog
liquide
0
cs_darkbol Messages postés 61 Date d'inscription lundi 7 juin 2004 Statut Membre Dernière intervention 6 décembre 2004
6 juil. 2004 à 16:30
Ok merci

Pour occuper, je résume par une vue d'ensemble de ce que je veux faire... une vue un peu grossie de l'exemple pour savoir de quoi je parle:

Mon premier fichier de type ASCII (.dat) se présente come suit :

!Coordinate System:
!Projection System ID : 0 Initialized Quick: 0
!Secondary Horizontal: Units: m Per/Meter: 1
!Geodetic Datum: EUROP50 Ellipsoid: INTNL
! Projection Method: Transverse Mercator
! Central Meridian: 3
! Base Parallel:0
! ScaleFactor:0.9996
! FALSEEasting:500000 m
! FALSENorthing:0m
! UserHorizontal:Units: mPer/Secondary:1
(T1,F20.5,T25,F16.5)
->0004
507210.7 6245180.0
507207.6 6247034.5
511326.2 6247043.5
->0005
496916.0 6253882.5
496912.4 6248884.5
->0006
520730.5 6218637.0

->0007
515289.4 6289726.0
520385.8 6289747.5
520397.6 6287324.5

etc jusqu'à ->0148 et le nombre de couples de valeurs varie entre 5 et 30.

Ma conversion veut résulter en ca :

3
507210.700000000 6245180.00000000
507207.600000000 6247034.50000000 511326.200000000 6247043.50000000
2
496916.000000000 6253882.50000000
496912.400000000 6248884.50000000

1
520730.500000000 6218637.00000000

3
515289.400000000 6289726.00000000
520385.800000000 6289747.50000000
520397.600000000 6287324.50000000

Voilà.

La ou j'y arrive :
ok pour le tri des valeur (petit if asc(left$())
ok pour le format des décimales (double replace)

Problème :
remplacer chaque "entête" de groupe par le nbre de lignes correspondant.

Allez je repars creuser un peu plus...

Merci!

"j'aime bien être suivi... :-|
0
cs_liquide Messages postés 1016 Date d'inscription samedi 22 mars 2003 Statut Membre Dernière intervention 24 juin 2008
6 juil. 2004 à 17:15
re salut
essais ca :

Dim Chaine As String
Dim Splitage() As String
Dim Splitage1() As String
Dim ChaineInter As String
Dim i As Integer
Dim j As Integer

Open "H:\Surfin project of the fire\Charisma2Surfer\test01.bln" For Input As #2
Chaine = StrConv(InputB(LOF(2), 2), vbUnicode)
Close #2

Splitage() = Split(Chaine, "->")

For i = 1 To UBound(Splitage()) '0 ou 1 suivant la recup du text avant le 1er comptage
    Splitage1() = Split(Splitage(i), vbCrLf) 'split les blocs
        ChaineInter = ChaineInter & (UBound(Splitage1()) - 1) & vbCrLf
       
        For j = 1 To UBound(Splitage1())
            ChaineInter = ChaineInter & Splitage1(j) & vbCrLf
        Next j
        
Next i

Text1.Text = ChaineInter


bien sur j'utilise toujours une textbox en multiline pour visualiser ce que ca va rendre

bonne prog
liquide
0
cs_darkbol Messages postés 61 Date d'inscription lundi 7 juin 2004 Statut Membre Dernière intervention 6 décembre 2004
7 juil. 2004 à 10:24
snif....

Merci beaucoup...

Je reviens de loin là...

c motivant d'avancer surtt pr un newbie..

8-)

A bientot j'espère...

"j'aime bien quand ca marche... :-|
0
cs_darkbol Messages postés 61 Date d'inscription lundi 7 juin 2004 Statut Membre Dernière intervention 6 décembre 2004
8 juil. 2004 à 11:19
heu salut,

Juste une ptite dernière chose...

Je ne maitrise pas encore parfaitement ce que tu mas donné (je comprends pas comment il fait pour remplacer directement les entetes...) parce que le chaineinter reprend tout le contenu dans ma compréhension (car splitage1())...

Mais au final, 2 éléments font que le fichier importé dans l'application ne correspond pas à l'original...

1/ chaque entête doit être précédé de 11 espaces..(j'arrive pas à les insérer..)

2/ et entre chaque bloc, il y a un saut de ligne (jarrive pas à le supprimer)

pour le string(11, chr$32)) J'ai essayé un replace du chr$(13) à partir d'un left après input line #nouveau fichier temp... c un peu barbare et en plus ca marche pas...

le saut de ligne est en fait une ligne constituée que d'un retour chariot... alors petit if left = chr$(13) then else print #fichier mais là échec encore...

Merci de m'aider à remédier à cela (décidément ya peu de choses que j'arrive à faire...)

snif

"j'aime bien quand c jamais fini... :-(
0
cs_liquide Messages postés 1016 Date d'inscription samedi 22 mars 2003 Statut Membre Dernière intervention 24 juin 2008
8 juil. 2004 à 11:54
salut pour les espaces, j'utilise la facon "barbare"
pour les saut de ligne, il les ajoute a pour tout, si tu ne les veut pas a la fin de chaque bloc il faut une condition de bloc quand il trouve le dernier bloc

essais ca :

Dim Chaine As String
Dim Splitage() As String
Dim Splitage1() As String
Dim ChaineInter As String
Dim i As Integer
Dim j As Integer

Open App.Path & "\config.txt" For Input As #2
Chaine = StrConv(InputB(LOF(2), 2), vbUnicode)
Close #2

Splitage() = Split(Chaine, "->")

For i = 1 To UBound(Splitage()) '0 ou 1 suivant la recup du text avant le 1er comptage
Splitage1() = Split(Splitage(i), vbCrLf) 'split les blocs
ChaineInter = ChaineInter & "           " & (UBound(Splitage1()) - 1) & vbCrLf

For j = 1 To UBound(Splitage1())
If j = UBound(Splitage1()) Then
    ChaineInter = ChaineInter & Splitage1(j)
Else
    ChaineInter = ChaineInter & Splitage1(j) & vbCrLf
End If
Next j

Next i

Text1.Text = ChaineInter

liquide
0
cs_darkbol Messages postés 61 Date d'inscription lundi 7 juin 2004 Statut Membre Dernière intervention 6 décembre 2004
8 juil. 2004 à 12:46
Yo

Merci !!

C nickel... j'avais mis string(11,"")&chaineinter c pr ca que ca marchait pas...

Et pour pr le if jaurais jamais trouvé...

Ben... 1h30 et toi tu ne le plies en 2 min...

Merci d'être arrivé au bout de mes peines!

A bientôt j'espère Liquide!

"j'aime bien ceux qui maitrisent... :-)))
0
cs_liquide Messages postés 1016 Date d'inscription samedi 22 mars 2003 Statut Membre Dernière intervention 24 juin 2008
8 juil. 2004 à 17:41
Au plaisir d'une nouvelle aide si besoin est.

Pour le "ceux qui maitrisent", je suis sincerement loin de la maitrise comme Ebart, renfield, rene38, Dark et j'en oubli bcp.

bonne prog
liquide
0
cs_darkbol Messages postés 61 Date d'inscription lundi 7 juin 2004 Statut Membre Dernière intervention 6 décembre 2004
26 juil. 2004 à 09:22
Salut Liquid,

Salut Nofutur,

Je reviens avec un petite question... Je reviens avec la conversion d'un autre fichier mais là j'arrive pas résoudre le problème :

Je rappelle la conversion qui écrivait un fichier ASCII par blocs (avec comme entete le nbre de ligne du bloc).

Mon problème présent est que j'aimerais séparer mes blocs et faire le comptage en fonction du dernier caractère de la ligne, je m'explique, de ca :

691860.10 6514398.00 SFSB-89-40
690860.10 6414398.00 SFSB-89-40
695567.10 6361817.00 SFSB-89-41 695566.90 6361841.60 SFSB-89-41
695566.60 6361866.20 SFSB-89-41

je veux ca :

2
691860.10 6514398.00 SFSB-89-40
690860.10 6414398.00 SFSB-89-40
3
695567.10 6361817.00 SFSB-89-41 695566.90 6361841.60 SFSB-89-41
695566.60 6361866.20 SFSB-89-41

La séparation par blocs s'effectue donc par le changement du 40 en 41 (puis 42...) et je n'y arrive pas...

Voilà merci pour le coup de main!

++

"j'aime bien les conversions... :-|
0
cs_liquide Messages postés 1016 Date d'inscription samedi 22 mars 2003 Statut Membre Dernière intervention 24 juin 2008
26 juil. 2004 à 12:34
Salut, Sont ils tous dans l'ordre ?

c'est a dire, 'est ce qu'il n'y a pas de mélange entre les valeur, un 41 vient se glisser en plein milieu des 40?

tu peux donc tout spliter puis tu reprends tout :

dim Compte as integer
dim Val,Val2 as integer
dim ListCompte() as integer
redim List(0)
Compte = 0
For i = lbound(splitage()) to ubound(splitage())
Val = right(splitage(i), 2)
if Val <> Val1 then
ListCompte(ubound(ListCompte()-1) = compte
redim preserve ListCompte(ubound(ListCompte())
compte = 1
Val2 = Val
else 
Compte = compte +1
end if
Next i

'Y'a plus qu'a recupérer le listCompte et le reinjecté dans le fichier


Le code n'est pas testé l'idée doit être là

Bonne prog
liquide
0
cs_darkbol Messages postés 61 Date d'inscription lundi 7 juin 2004 Statut Membre Dernière intervention 6 décembre 2004
26 juil. 2004 à 13:37
euh merci encore... c pas encore de mon niveau...

Mais du coup je comprends pas un truc, que "splite" splitage() ?

parce que je comprends pas comment l'insérer... voici mon code :

Dim Tempo As String
Dim SurferApp As Object
Static nb As Long

Set SurferApp = GetObject(, "Surfer.application")

Open SurferApp.Path & "\import Data\CharismaGeoframe Non Converted Data" & File2(23).FileName For Input As #1 'opens the file to import im reading mode
Open SurferApp.Path & "\import Data\CharismaGeoframe Non Converted Data\tempG.bln" For Output As #2

Do While Not EOF(1)
       
Line Input #1, Tempo
If Asc(Left$(Tempo, 1)) = 83 Then  'if the first character is "S"
Tempo = Mid$(Tempo, 47, 9) & "," & Mid$(Tempo, 55, 10) & Chr$(9) & Mid$(Tempo, 1, 10)
Print #2, Tempo
End If
Loop

Close #1
Close #2

Open SurferApp.Path & "\import Data\CharismaGeoframe Non Converted Data\tempG.bln" For Input As #2
Open SurferApp.Path & "\import Data\CharismaGeoframe Converted Data" & File3(33).FileName For Output As #3

Dim tempo2 As String
Dim temp() As String
Dim splitlig() As String

Do While Not EOF(2)
Line Input #2, tempo2
temp = Split(tempo2, Chr$(9))
tempo2 = Replace(Replace(Replace(tempo2, Chr$(9), String(3, Chr$(32))), temp(1), temp(1) & "0" & String(2, Chr$(32))), temp(2), temp(2) & "0" & String(4, Chr$(32))) 'adds the needed decimal zeros
Print #3, tempo2
Loop

Close #2
Close #3


Est ce que je splite par ligne? Sinon pas d'intrus pour le 41 au milieu de 40...

Merci !

"j'aime bien les nuages... :-|
0
cs_liquide Messages postés 1016 Date d'inscription samedi 22 mars 2003 Statut Membre Dernière intervention 24 juin 2008
26 juil. 2004 à 13:47
tu récupères tes valeurs dans quoi ?, quelle variable ?
et tu les affiche dans quoi ?
car entre les temp, tempo, tempo2 tempo3, je ne sais pas ou sont tes valeurs.

liquide
0
cs_darkbol Messages postés 61 Date d'inscription lundi 7 juin 2004 Statut Membre Dernière intervention 6 décembre 2004
26 juil. 2004 à 14:03
Dsl si c pas très clair

Voilà la procédure:

1/ ouverture-lecture du fichier pris dans une listbox (file2(23))
2/ ouverture-écriture du fichier tempG
3/ stockage des lignes commencant par S et mise au format
4/ Print tempG, Tempo
5/ ouverture-lecture tempG
6/ ouverture-écriture fichier "final" file3(33)
7/ splitage entre chaque "tabulation" dans temp
8/ mise au format des valeurs dans tempo2
9/ Print file3(33)

Voilà, c clair comment c le bazar et ya meme des variables que je me servais plus (nb et splitlig)...

Donc pour résumer :

Tempo : contient les valeurs que l'on veut garder du fichier original.
Tempo2 : contient ces mêmes valeurs mais dans un bon format...
mais le fichier final résulte en un pavé où rien n'est séparé en blocs.

++

"j'aime bien les nuages... :-(
0
cs_liquide Messages postés 1016 Date d'inscription samedi 22 mars 2003 Statut Membre Dernière intervention 24 juin 2008
26 juil. 2004 à 19:41
je suppose donc que c'est le Tempo2 qui doit etre travaillé:

A mettre en entete:
dim Compte as integer
dim Val,Val2 as integer
dim ListCompte() as integer
redim ListCompte(0)

a mettre apres le print tempo2

Val = right(Tempo2,2)
if Val <> Val2 and Val2 <> "" then
ListCompte(ubound(ListCompte()-1) = compte
redim preserve ListCompte(ubound(ListCompte())
compte = 1
Val2 = Val
else
Compte = compte +1
end if

bonne prog
liquide
0
cs_darkbol Messages postés 61 Date d'inscription lundi 7 juin 2004 Statut Membre Dernière intervention 6 décembre 2004
27 juil. 2004 à 09:37
salut

jai mis ca apres le print mais est ce ke tu pourrais m'expliquer ce ke ca fait car je pense pas avoir tt compris...

- il ma indiqué un ptit mismatch dc jai mis str(val2) <> ""
- que represente val2? est ce automatiquement le val de la ligne qui sui le premier val?
- et il me dit que le tableau ListCompte() est subscript out of range, je l'ai deja eu plusieurs mais à koi se refere cette erreur?
- comment afficher le compteur en entete apres ? print listcompte, tempo2? ou print listcompte dans la boucle?

Merci pour ton aide!

"j'aime bien quand c élaboré... :-|
0
cs_liquide Messages postés 1016 Date d'inscription samedi 22 mars 2003 Statut Membre Dernière intervention 24 juin 2008
27 juil. 2004 à 12:40
salut
c'est exact pour le val et val2, ce sont des type string, cependant
autant les mettre en Dim Val, Val2 as string

puis
ListCompte(ubound(ListCompte()) = compte
redim preserve ListCompte(ubound(ListCompte()+1)

l'erreur doit venir de l'affectation au tableau de la valeur compte, au 1er, la grandeur du tableau est de 0 et quand il y un -1, la grandeur du tableau n'existe pas.

pour l'ecriture dans le fichier, ce n'est pas permis a ce niveau la, il faut faire tous les calculs, puis une fois que tout est fait, ecrire par bouclage dans le fichier. Donc d'abord ouvrir le fichier, faire toute la transformation avec le calcul des valeur en entete puis pour terminer ouvrir le dernier fichier et boucler dans l'ordre avec le comptage.
a mon avis ca implique de reprendre le code et je ne suis pas sur que le Do While not EOF a la fin soit nécessaire.

poela_a_frire@hotmail.com si besoin
liquide
0
Rejoignez-nous