Problème avec une chaine de caractères

Sympa74 Messages postés 85 Date d'inscription lundi 25 septembre 2006 Statut Membre Dernière intervention 18 décembre 2008 - 12 oct. 2006 à 12:07
Sympa74 Messages postés 85 Date d'inscription lundi 25 septembre 2006 Statut Membre Dernière intervention 18 décembre 2008 - 14 oct. 2006 à 21:57
Bonjour à tous,

me revoici.. toujours dans la catégorie débutant après une petite soixantaine d'heures de programmation.

J'ai pas mal avancé sur mon projet mais je me heurte sur un petit souci.
J'importe des données depuis un fichier txt avec champs délimités.

Voila le problème :

Dans la base que j'importe il y a un champ "nom" qui contient le nom + le prénom du client.

Dans mon programme, il y a un champ pour le nom et un champ pour le prénom.
J'ai écrit un bout de code pour cela... et cela fonctionne à 80 % seulement....
je me suis d'ailleurs certainement compliqué la vie... j'ai fait une boucle pour lire le nombre de caractères de la chaine, puis
lorsque le code rencontre le 1er espace, il considère que la suite est le prénom.

Seulement voila... dans la base, il y a des noms composés séparés par un espace, et du coup cela me mets la deuxième partie du nom comme un prénom, etc... bref c'est la zone.

Voila ce que j'ai écrit et qui est très certainement très compliqué... y'a forcément plus simple

        Dim chaine1 As String = TB_chaine1.Text
        Dim longueurchaine As Integer = Len(chaine1)
       
        Dim test As Integer = 0
        Dim texte As String = "" ' la chaine saisie dans le textbox en provenance du fichier d'importation
        Dim final1 As String = "" ' contiendra les lettres formant le nom
        Dim final2 As String = "" ' contiendra les lettres formant le prénom
        Dim position As Integer = 0 'la position ou se trouve l'espace lorsqu'il est rencontré

        Try
            For test = 0 To longueurchaine - 1
                texte = chaine1.Substring(test, 1)
                final1 = final1 + texte                If texte " " Then TB_chaine2.Text final1 : position = test
            Next
            texte = ""
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
       
        Try
            position = position + 1
            Dim test2 As Integer
            For test2 = position To longueurchaine - 1
                texte = chaine1.Substring(test2, 1)
                MsgBox(texte)
                final2 = final2 + texte
                TB_chaine3.Text = final2
                position = position + 1
            Next
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try

TB_chaine2.Text = final1     
TB_chaine3.Text = final2

    End Sub

En plus du problème cité... VB ne semble pas vouloir reconnaitre les caractères accentués... les é è ù ç qui sont contenus dans les noms et prénoms du fichier d'importation.

Si une "âme charitable" pouvait me sortir cette épine du doigt.... cela me permettrait de continuer un bout de chemin.

je vous en remercie par avance.

Philippe - Sympa 74
 

16 réponses

B0mbJacK Messages postés 141 Date d'inscription lundi 23 février 2004 Statut Membre Dernière intervention 25 octobre 2006 1
12 oct. 2006 à 12:17
Lu,
dans ta base ki contient le nom et le prenom, utilise un séparateur
exemple
 "Dupont/Christophe"
apres
dim NomPrenom() as string
NomPrenom = split(TaColonneKiContientNomPrenom,"/")

et en sortie tu as :
NomPrenom(0) = Dupont
NomPrenom(1) = Christophe

voila...bon coding...++
0
Molenn Messages postés 797 Date d'inscription mardi 7 juin 2005 Statut Membre Dernière intervention 23 février 2011 7
12 oct. 2006 à 16:00
Une autre idée, mais je ne sais pas si c'est transposable dans ta version de VB (je ne connais que le VBA et VB6) :


Ton champ contient toujours le NOM, un espace et le PRENOOM. Il suffit de chercher le premier espace, en partant de la droite de la chaîne de caractère (à condition que les prénoms composés soient eux, bien reliés par un "-", sinon, effectivement, le plus ismple est d'utiliser un caractère de séparation).


En VBA, cette fonction, c'est InStrRev.


Molenn
0
Sympa74 Messages postés 85 Date d'inscription lundi 25 septembre 2006 Statut Membre Dernière intervention 18 décembre 2008 1
12 oct. 2006 à 16:06
Bonjour,
merci pour vos réponses.
le problème est justement que le fichier de départ (environ 4000 lignes) présente le champ nomprenom avec un peu de tout
c'est à dire que je peux avoir ceci

DUPONT L'HERMITAGE Henri
ou encore
DUPONT-L'HERMITAGE Henri

ou encore

BAUDRUCHE Jean Pierre ou encore BAUDRUCHE Jean Pierre ou encore BAUDRUCHE J.Pierre

et dans tous les cas après importation du fichier, je dois obtenir

BAUDRUCHE
Jean-Pierre

ou BAUDRUCHE
Jean Pierre

ou encore
BAUDRUCHE
J.Pierre

et je ne vois pas trop comment faire pour éviter de retoucher la base initiale manuellement fiche par fiche.

Merci pour les suggestions.

la première réponse proposée avec le
dim NomPrenom() as string
NomPrenom = split(TaColonneKiContientNomPrenom,"/")

peut bien fonctionner à la place de mon bout de code décrit plus haut - (merci c'est effectivement beaucoup plus simple)
par contre cela ne résoud pas l'intégralité du problème vu les différentes possibilités dans la base initiale.

Si vous avez d'autres idées... merci

Philippe - Sympa 74
 
0
B0mbJacK Messages postés 141 Date d'inscription lundi 23 février 2004 Statut Membre Dernière intervention 25 octobre 2006 1
12 oct. 2006 à 19:24
Re, ptite kestion
Le nom de famille est en majuscule ?
et le prénom en minuscule sauf les 2premieres lettre?
0

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

Posez votre question
Sympa74 Messages postés 85 Date d'inscription lundi 25 septembre 2006 Statut Membre Dernière intervention 18 décembre 2008 1
13 oct. 2006 à 07:53
Hello,

Oui effectivement, le seul point d'harmonisation de la base à importer est celui ci :
les noms de famille sont tous en MAJUSCULES et les prénoms sont en principe en minuscule avec la 1ère lettre en majuscule.

ex : DUPONT DE NEMOURS Laurent

Je n'ai vu qu'une ou deux exceptions ou le prénom est enregistré en majuscules, mais vu le nombre très faible, je peux les corriger manuellement.

merci d'avance pour ton aide.

Philippe - Sympa 74
 
0
B0mbJacK Messages postés 141 Date d'inscription lundi 23 février 2004 Statut Membre Dernière intervention 25 octobre 2006 1
13 oct. 2006 à 10:50
Lu,
alors voila : )

on imagine la variable NomPrenom ki contient le nom et prénom
Dim NomPrenom as String, xDecoupe() as String, Nom as String,Prenom as String 
  
NomPrenom = DUPONT DE NEMOURS Laurent
xDecoupe = split(NomPrenom, " ")

for i = 0 to ubound(xDecoupe)
   if xDecoupe(i) = UCASE(xDecoupe(i)) then 
      Nom = Nom & space(1) & xDecoupe(i)
   end if
next i
Prenom = Trim$(mid(NomPrenom,Len(Nom)+1))
Nom = Trim$(Nom)

' j'utilise un séparateur pour connaitre le nombre de mot
dans la boucle je compare si le premier mot et en majuscule, si oui je l'ajoute dans la variable Nom

je prend la valeur de départ, j'enleve la longueur du nom et il me reste que le prénom à recuperé

voila bon coding....++
0
Sympa74 Messages postés 85 Date d'inscription lundi 25 septembre 2006 Statut Membre Dernière intervention 18 décembre 2008 1
13 oct. 2006 à 18:23
Je te remercie beaucoup pour ton aide.

Bon alors j'ai adapté ce que tu m'as indiqué. J'ai donc créé une fonction pour cette procédure.


Function xDecoupe()

        Dim chaine1 As String = Tabligne(enreg, 1)

        Dim i As Integer

        xDecoupe = Split(chaine1, " ")

        For i = 0 To UBound(xDecoupe)

            If xDecoupe(i) = UCase(xDecoupe(i)) Then

                nom = nom & Space(1) & xDecoupe(i)

            End If

        Next i

        prenom1 = Trim$(Mid(chaine1, Len(nom) + 1))

        nom1 = Trim$(nom)

    End Function

Lorque je lance l'importation de mon fichier, j'obtiens le message de bug suivant :
L'exception System.StackOverflowException n'a pas été gérée


qu'est ce que cela veut dire ?


Peut-être faut-il que je te communique un peu plus mon code que voici :


Private Sub Imp_EBP_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load


        '===> ouverture boite de dialogue pour sélection du fichier à ouvrir

        OpenFileDialog1.ShowDialog()


       '=== > compte le nombre de lignes dans le fichier d'importation EBP

        Dim ligne1 As String = 0

        SR = File.OpenText(OpenFileDialog1.FileName)

        Do Until SR.Peek = -1

            ligne1 = SR.ReadLine()

            compteur = compteur + 1

        Loop

        SR.Close()


        '===> LECTURE DU FICHIER IMPORTé et MISE EN TABLEAU DES DIFFERENTS CHAMPS


        Using MyReader As New Microsoft.VisualBasic.FileIO.TextFieldParser _

                    (OpenFileDialog1.FileName)

            MyReader.TextFieldType = FileIO.FieldType.Delimited

            MyReader.SetDelimiters(";") 'affichage du délimiteur de champ


            Dim ligne As String()

            Dim champ As String

            Dim numchamp As Integer = 0

            Dim numligne As Integer = 0


            ' boucle pour lire du début à la fin du fichier

            ' tant que la fin de fichier n'est pas obtenue, on lit les enregistrement

            While Not MyReader.EndOfData

                Try

                    ligne = MyReader.ReadFields ' variable ligne

                    'contient la ligne extraite du fichier


                    For Each champ In ligne

                        Tabligne(numligne, numchamp) = champ

                        'MessageBox.Show(numchamp, numligne)

                        numchamp = numchamp + 1

                    Next

                    numchamp = 0

                    If numchamp 0 Then numligne numligne + 1


                Catch ex As Exception

                    MsgBox("enregistrement invalide")

                End Try

            End While

        End Using

    End Sub


ensuite j'ai une SUB pour générer l'enregistrement dans le nouveau fichier. elle donne ceci :
Cette sub enregistrement est appelée suite au lancement du travail depuis un bouton click

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        ' == => lancement de l'enregistrement dans le nouveau fichier
        ' lecture de chaque ligne du tableau et enregistrement dans la base GESCLI

        For enreg = 0 To compteur
            enregistrement() 'vers sub
            TextBox1.Text = enreg ' affiche le numéro d'enregistrement traité
            TextBox1.Refresh()
            enreg = enreg + 1
        Next
    End Sub


 '>>>>>>>>>>>>>>>>>>>>>>>>>>  SUB ENREGISTREMENT


    Sub enregistrement()


        Dim rec1 As String ' la variable comprenant tous les champs

        Dim separ As String = "¤" ' le séparateur de champ


        xDecoupe()      ' vers éclatement de la chaine en NOM + Prénom


        cleprimaire () ' vers sub pour calcul de la clé primaire du compte


       

        civilite = Tabligne(enreg, 0)

       nom = nom1 'variable utilisée dans la fonction xdecoupe

       prenom = prenom1 'variable utilisée dans la fonction xdecoupe

        add1 = Tabligne(enreg, 2)

        add2 = Tabligne(enreg, 3)

        add3 = Tabligne(enreg, 4)

        cpos = Tabligne(enreg, 5)

        ville = Tabligne(enreg, 6)

        pays = Tabligne(enreg, 7)

        telpriv = Tabligne(enreg, 8)

        telbur = Tabligne(enreg, 9)

        telport = Tabligne(enreg, 10)

        telfax = ""

        email = Tabligne(enreg, 11)  'email

        datcreat = Tabligne(enreg, 12) 'date creat

        categcli = Tabligne(enreg, 13) ' catégorie

        codetarif = Tabligne(enreg, 14) ' code tarif

        intracom = Tabligne(enreg, 15) ' intracom

        carteclub = Tabligne(enreg, 16) ' carte club

        expirclub = Tabligne(enreg, 17) ' expire

        rattachzone = ""                   ' rattachzone

        cbnum = Tabligne(enreg, 18)  ' cbnum

        validcb = Tabligne(enreg, 19) ' validité

        cryptocb = Tabligne(enreg, 20)  ' crypto

        categcli = Tabligne(enreg, 13) ' catégorie

        envoipub = Tabligne(enreg, 22)  ' envoi pub

        datecatal = Tabligne(enreg, 23)  ' date catal

        statutcli = "Actif"

        dernpub = Tabligne(enreg, 24)

        datemodif = CStr(mydate)

        codemodif = "Auto"

        observ = ""


        '===> préparation de la variable pour l'enregistrement dans GESCLI

        rec1 = cleprimaire & separ & civilite & separ _

                & nom & separ & prenom & separ & add1 & separ & _

                add2 & separ & add3 & separ & cpos & separ & ville & _

                separ & pays & separ & telpriv & separ & telbur & separ _

                & telport & separ & telfax & separ & email & separ & datcreat _

                & separ & categcli & separ & codetarif & separ & intracom _

                & separ & carteclub & separ & expirclub & separ & rattachzone _

                & separ & cbnum & separ & validcb & separ & cryptocb _

                & separ & commercial & separ & envoipub & separ & datecatal & _

                separ & statutcli & separ & dernpub & separ & datemodif & separ _

                & codemodif & observ


        '===> ouverture de la base dans GESCLI, enregistrement et fermeture du fichier


        Dim SW As StreamWriter = File.AppendText("C:\GESINAT\GESCLI\bd_clients.dat")

        SW.WriteLine(rec1)

        SW.Close() 'fermeture du fichier après enregistrement


      

    End Sub

Je te remercie d'avance pour ton aide et tes conseils.

Philippe - Sympa 74
 
0
B0mbJacK Messages postés 141 Date d'inscription lundi 23 février 2004 Statut Membre Dernière intervention 25 octobre 2006 1
13 oct. 2006 à 18:36
re,
c'est dans cette partie ke tu as une erreur ?
Dim ligne1 As String = 0
        SR = File.OpenText(OpenFileDialog1.FileName)
        Do Until SR.Peek = -1
            ligne1 = SR.ReadLine()
            compteur = compteur + 1
        Loop
        SR.Close()

si oui, regarde si ton compteur est en integer et passe le en long
0
Sympa74 Messages postés 85 Date d'inscription lundi 25 septembre 2006 Statut Membre Dernière intervention 18 décembre 2008 1
14 oct. 2006 à 10:27
Bonjour,

Non ce n'est pas dans cette partie que j'ai une erreur... car cela fonctionnait auparavant.

Le message apparait sur la ligne
xDecoupe = Split(chaine1, " ")

Le message d'erreur est :
Une exception non gérée du type 'System.StackOverflowException' s'est produite dans mscorlib.dll
et le conseil de dépannage est :
assurez-vous que vous n'avez pas une boucle infinie ou une récurrence infinie.

le plantage s'effectue sur la 1ère ligne de lecture du fichier alors que la variable "chaine1" contient bien a priori le NOM Prénom du client séparé par un espace.

Donc c'est bien cette partie du code qui fait planter

Function xDecoupe()
        Dim chaine1 As String = Tabligne(enreg, 1)
        Dim i As Integer
        xDecoupe = Split(chaine1, " ")
        For i = 0 To UBound(xDecoupe)
            If xDecoupe(i) = UCase(xDecoupe(i)) Then
                nom = nom & Space(1) & xDecoupe(i)
            End If
        Next i
        prenom1 = Trim$(Mid(chaine1, Len(nom) + 1))
        nom1 = Trim$(nom)

    End Function

Merci d'avance.

Philippe - Sympa 74
 
0
B0mbJacK Messages postés 141 Date d'inscription lundi 23 février 2004 Statut Membre Dernière intervention 25 octobre 2006 1
14 oct. 2006 à 12:40
 
Lu
' test ca ,ta variable chaine1 à eu un dépassement de capacité
' le fait de supprimer les espaces des 2extremités va surement eviter cette erreur

Public Sub xDecoupe() 
Dim chaine1 As String ,i As Integer
chaine1 = space(Len(Trim$(Tabligne(enreg), 1)))
chaine1 =  Trim$(Tabligne((enreg), 1))
xDecoupe = Split(chaine1, " ")
For i = 0 To UBound(xDecoupe)
If xDecoupe(i) = UCase(xDecoupe(i)) Then
nom1 = nom1 & Space(1) & xDecoupe(i)
End If
Next i
prenom1 = Trim$(Mid(chaine1, Len(nom1) + 1))
nom1 = Trim$(nom1)
End Function
0
Sympa74 Messages postés 85 Date d'inscription lundi 25 septembre 2006 Statut Membre Dernière intervention 18 décembre 2008 1
14 oct. 2006 à 13:18
Ok... si je passe le code tel quel... il y a plusieurs messages d'erreurs...

sur la ligne
chaine1 = space(Len(Trim$(Tabligne(enreg), 1)))
un erreur est indiquée sur enreg : le nombre d'indices est inférieur aux dimensions du tableau indéxé.

sur la ligne : xDecoupe = Split(chaine1, " ")
l'erreur indique pour xDecoupe : cette expression est une valeur et ne peut donc pas être la cible d'une assignation

ensuite sur For i = 0 To UBound(xDecoupe) "cette expression ne produit pas de valeur"

et enfin sur les lignes
If xDecoupe(i) = UCase(xDecoupe(i)) Then
                nom1 = nom1 & Space(1) & xDecoupe(i)
le i donne comme erreur : arguments trop nombreux pour public sub sDecoupe()

Ca ce complique on dirait... d'autant plus que je ne comprends pas grand chose à ces messages...

c'est grave docteur ?

Si je remplace Public sub xDecoupe() par function xDecoupe()
ces principaux messages d'erreur disparaissent.

par contre subsiste le premier à savoir sur la ligne

chaine1 = space(Len(Trim$(Tabligne(enreg), 1)))

un erreur est indiquée sur enreg : le nombre d'indices est inférieur aux dimensions du tableau indéxé.

Si je mets cette ligne en remarque pour ne pas la prendre en compte et que je lance le programme, alors je me retrouve avec la même erreur initiale à savoir : Une exception non gérée du type 'System.StackOverflowException' s'est produite dans mscorlib.dll
sur la ligne xDecoupe = Split(chaine1, " ")

Voila le résultat des courses... as tu une autre idée ?

en tant que grand débutant... ce que je trouve dommage... c'est à mon sens la pas très claire explication des messages d'erreur de la part de VB... mais bon...

au plaisir de te lire...

Philippe - Sympa 74
 
0
B0mbJacK Messages postés 141 Date d'inscription lundi 23 février 2004 Statut Membre Dernière intervention 25 octobre 2006 1
14 oct. 2006 à 16:06
Lu,
voici une nouvelle version

Public sub  NomPrenom()
Dim chaine1 As String = Tabligne(enreg, 1)
Dim i As Integer, xDecoupe() as string
chaine1 = Trim$(chaine1)
xDecoupe = Split(chaine1, " ")
        For i = 0 To UBound(xDecoupe)
            If xDecoupe(i) = UCase(xDecoupe(i)) Then
                nom = nom & Space(1) & xDecoupe(i)
            End If
        Next i
        prenom1 = Trim$(Mid(chaine1, Len(nom) + 1))
        nom1 = Trim$(nom)
End Sub
0
Sympa74 Messages postés 85 Date d'inscription lundi 25 septembre 2006 Statut Membre Dernière intervention 18 décembre 2008 1
14 oct. 2006 à 17:37
Ok je viens d'essayer.

Cette nouvelle version donne le résultat suivant.

1) y'a plus de plantage... ca fonctionne.. presque.

par contre, la variable nom1 contient à chaque fois le nom de la ligne précédente + la ligne en cours, etc. et la variable prénom1 reste desespérément vide, hormis, sur le 1er enregistrement ou ca se passe bien.

au final ca donne donc cela dans le fichier :

1ère ligne :
Monsieur¤TOTO¤Lucien¤15 rue de ....

2ème ligne
Madame¤TOTO DUCHMOL¤¤

3ème ligne

Monsieur ¤TOTO DUCHMOL BOURDAINE¤¤

Comme tu peux le voir, la variable NOM1 semble garder en mémoire le nom précédent.
J'ai donc ajouté un NOM1="" et PRENOM1 = "" après avoir enregistré dans le fichier et avant de traiter l'enregistrement suivant, mais cela ne change rien.

Je sens qu'on est proche de la solution...

Philippe - Sympa 74
 
0
Sympa74 Messages postés 85 Date d'inscription lundi 25 septembre 2006 Statut Membre Dernière intervention 18 décembre 2008 1
14 oct. 2006 à 17:57
Yes yes yes.. j'ai vu le problème..

en fait dans
For i = 0 To UBound(xDecoupe)
            If xDecoupe(i) = UCase(xDecoupe(i)) Then
                nom = nom & Space(1) & xDecoupe(i)
            End If
        Next i

tu utilises la variable nom qui est aussi la même variable que j'utilisais pour l'enregistrement dans le nouveau fichier.

J'ai donc corrigé nom = nom & Space(1) & xDecoupe(i)
par nom2 = nom2 & Space(1) & xDecoupe(i)

puis prenom1 = Trim$(Mid(chaine1, Len(nom2) + 1))
        nom1 = Trim$(nom2)

et ca marche... merci beaucoup.... beaucoup.

Une dernière chose si ce n'est pas trop abusé... comment faire lors de l'importation pour que le programme reconnaisse les caractères accentués... car lors de la lecture des prénoms (par exemple) le fichier que j'importe contient

Marie-Thérèse et au final ca donne Marie Thrse
ou encore vronique pour véronique, etc..

Philippe - Sympa 74
 
0
B0mbJacK Messages postés 141 Date d'inscription lundi 23 février 2004 Statut Membre Dernière intervention 25 octobre 2006 1
14 oct. 2006 à 21:39
Ca fait plaisir : )
sinon .....
pour ta kestion...aucune idée
je t'invite à la mettre dans le forum

bon coding....++
0
Sympa74 Messages postés 85 Date d'inscription lundi 25 septembre 2006 Statut Membre Dernière intervention 18 décembre 2008 1
14 oct. 2006 à 21:57
OK et encore merci pour tout.
Heureusement qu'il y a une entraide.. sinon dur dur d'être débutant.

Bon week-end à toi.

Philippe - Sympa 74
 
0
Rejoignez-nous