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

VB.NET Discussion :

Réduction de la durée de conversion et lecture


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé Avatar de megamario
    Homme Profil pro
    VB6/VB.net/C/C++/C#
    Inscrit en
    Septembre 2008
    Messages
    931
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : VB6/VB.net/C/C++/C#
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2008
    Messages : 931
    Par défaut Réduction de la durée de conversion et lecture
    Bonjour à tous,

    La présentation

    J'ai une application VB6 (c'est bien le .net qui m’intéresse) qui me récupère et stock des données en CSV sous la forme:

    Test1;0
    Battery Current;Adc
    20/07/2010 08:50:38;26/07/2010 02:20:38
    20/07/2010 08:50:38;-50.2
    20/07/2010 09:00:38;-50.2
    20/07/2010 09:10:38;-50.2
    20/07/2010 09:20:38;8.7
    20/07/2010 09:30:38;8.4
    20/07/2010 09:40:38;4.9
    20/07/2010 09:50:38;4.6
    20/07/2010 10:00:38;4.2
    20/07/2010 10:10:38;-38.00
    20/07/2010 10:20:38;-70.9
    20/07/2010 10:30:38;-70.1

    etc...
    Le 1er champs et donc l'heure d'acquisition de la donnée, le 2eme étant la donnée. Les 3 première ligne d’entête permet de connaitre:
    1ere ligne: Le nom du site, ici "Test1" suivit de la version du fichier (il peut y avoir plusieurs "Test1").
    2eme ligne étant le nom de la mesures suivi de l'unité.
    3eme ligne étant la date de début suivi de la date de fin, ce qui me permet quand j'affiche tout les fichiers disponibles, de parcourir que ces 3 lignes pour m'indiquer ce que les fichiers contiennent.

    Voila pour la mise en place du programme VB6

    Pour la lecture de ce fichier j'utilise un programme qui va m'afficher la courbe grâce à la dll ZedGraph, Voici ce que donne la courbe de Test1:



    Le fichier a un poids de 22Ko et 829 lignes

    Voila pour la présentation.

    Mon souci

    Le client (dans le monde entier) peut m'envoyer un fichier à ouvrir en France. comme vous pouvez le constater, les données sont avec des points. Et mon souci c'est que en France si j'utilise la fonction Val ( "54.5") cela me crée une exception car il n'arrive pas a convertir avec le point. Mais avec un PC US pas de souci.
    Ainsi pour que cela soit compatible partout j'ai crée une petit rustine:

    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
     
        Public Function ConversionRegional(ByVal str As String) As Double
            Dim val As Double
            Try
                If Not _DebLecture Then
                    If str.Contains(".") Then
                        _Point = True
                    Else
                        _Point = False
                    End If
                    _DebLecture = True
                End If
                If Not _Conversion Then
                    val = Convert.ToDouble(str)
                Else
                    If _Point Then
                        str = Replace(str, ".", ",")
                    Else
                        str = Replace(str, ",", ".")
                    End If
                    val = Convert.ToDouble(str)
                End If
                ConversionRegional = val
            Catch ex As Exception
                If _Point Then
                    str = Replace(str, ".", ",")
                Else
                    str = Replace(str, ",", ".")
                End If
                val = Convert.ToDouble(str)
                _Conversion = True
                ConversionRegional = val
            End Try
        End Function
    Le principe: J'envoie mon string à convertir, je crée une 1er tentative de conversion et si j'ai une exception je regarde si j'ai un point ou une virgule (par s'adapter à n'importe quelle fichier) puis je remplace et je reconverti pour enfin récupérer mon Double.
    Pour la 2eme conversion si il y a eue une exception avant je remplace tout de suite le point ou la virgule. Etc...

    Cela marche très bien mais c'est très long.

    Par exemple pour convertir mon fichier de 22K il met presque 10 secondes (mon PC est certes pas rapide du tout comparer a celui de mon chef)

    Pour envoyer ensuite les données à zedgraph c'est quasiment instantané, donc c'est vraiment cette conversion qui me bloque.

    Voici le code qui me lit le fichier et me stocke les données dans un dico:

    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
     
    Public Function LireFichier(ByVal _NomFichier As String, ByVal _DateMini As Date, _
                                    ByVal _DateMaxi As Date, ByVal COurbe As frmCourbe) As Dictionary(Of Date, Double)
            Dim Lecture As StreamReader = New StreamReader(_ChDonnee & "\" & _NomFichier)
            Dim EcritureEr As StreamWriter
            Dim Ligne As String
            Dim Tab(2) As String
            Dim Dico As New Dictionary(Of Date, Double)
            Dim Defaut As ArrayList = New ArrayList
            Dim Err As Integer
            Dim Time As Date
            Dim OK As Boolean = False
            Dim Val As Single
            Dim TextErr As String = ""
            Err = 0
            Try
                Tab = Lecture.ReadLine().Split(";")
                Tab = Lecture.ReadLine().Split(";")
                Ligne = Lecture.ReadLine()
                Ligne = Lecture.ReadLine()
                While Not Ligne Is Nothing
                    Tab = Ligne.Split(";")
                    Time = Convert.ToDateTime(Tab(0))
                    Val = ConversionRegional(Tab(1))
                    If (_DateMini <= Time) And (Time <= _DateMaxi) Then
                        While Not OK
                            If Not Dico.Keys.Contains(Time) Then
                                Dico.Add(Tab(0), Val)
                                OK = True
                            Else
                                Err = Err + 1
                                Defaut.Add(_MaLangue.LoadPrgString("Message2") & vbCrLf & _
                                           _MaLangue.LoadPrgString("Message4") & Tab(0) & vbCrLf & _
                                           _MaLangue.LoadPrgString("Message3") & vbCrLf & _
                                           "---------------------------------------------")
                                'Ajout d'une seconde à la valeur identique
                                Time = DateAdd(DateInterval.Second, 1, Time)
                                Tab(0) = Time
                            End If
                        End While
                        OK = False
                    End If
                    Ligne = Lecture.ReadLine
                    _Courbe.rafraichir()
                End While
                If Err <> 0 Then
                    EcritureEr = New StreamWriter(_ChDonnee & "\" & _NomFichier & "_Err.txt")
                    For i As Integer = 0 To Defaut.Count - 1
                        EcritureEr.WriteLine(Defaut(i))
                    Next i
                    EcritureEr.Close()
                    MessageBox.Show(Err.ToString & " " & _MaLangue.LoadPrgString("Message5") & vbCrLf & _NomFichier & "_Err.txt")
     
                End If
            Catch ex As Exception
                MessageBox.Show("Error : 604 " & vbCrLf & _MaLangue.LoadPrgString("Message6") & vbCrLf & _MaLangue.LoadPrgString("Message4") & Tab(0) & vbCrLf & ex.ToString)
            End Try
            Return Dico
        End Function

    Voila c'est un peut long mais je pense que vous avez tout pour essayer si vous le voulez bien, me dire comment réduire ce temps de lecture. Sachant qu'a Zegraph je lui donne la date du point et la données "Double" dans une boucle après cette conversion mais c'est presque instantané.

    Merci

  2. #2
    Rédacteur
    Avatar de Nathanael Marchand
    Homme Profil pro
    Expert .Net So@t
    Inscrit en
    Octobre 2008
    Messages
    3 615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert .Net So@t
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Par défaut
    Sinon dans le framework y'a Double.Parse qui permet qu'on lui passe la culture invariante

  3. #3
    Membre chevronné
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2011
    Messages
    453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

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

    Informations forums :
    Inscription : Mars 2011
    Messages : 453
    Par défaut
    Tu n'as pas besoin de ta fonction de conversion, si tu mets directement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    monString.Replace(".",",")
    dans ta ligne il convertira automatiquement tout les "." qu'il rencontrera par des ","...

    Edit: Sinon c'est vrai que Nathanael (qui a été un peu plus rapide) a une solution encore plus élégante

  4. #4
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 197
    Par défaut
    http://msdn.microsoft.com/fr-fr/libr...=vs.80%29.aspx

    le problème vient surtout du fait que ton fichier n'a pas de norme, il aurait fallu que peu importe le pc (et le pays) sur lequel il est exécuté il écrive la même chose, pas un coup un . et un coup une ,
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  5. #5
    Membre éprouvé Avatar de megamario
    Homme Profil pro
    VB6/VB.net/C/C++/C#
    Inscrit en
    Septembre 2008
    Messages
    931
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : VB6/VB.net/C/C++/C#
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2008
    Messages : 931
    Par défaut
    Citation Envoyé par Pol63 Voir le message
    http://msdn.microsoft.com/fr-fr/libr...=vs.80%29.aspx

    le problème vient surtout du fait que ton fichier n'a pas de norme, il aurait fallu que peu importe le pc (et le pays) sur lequel il est exécuté il écrive la même chose, pas un coup un . et un coup une ,
    Je suis parfaitement d'accort avec toi mais ce n'est pas moi qui est crée le logiciel VB6.

    on si non j'ai trouvé d'ou viens mon gros ralentissement, il y a quelque temps j'effectuais la conversion directement et je générais donc pour chaque données une exception ce qui me prenait énormément de temps aussi. j'avais donc par souci de temps mis un petit Gif animé de "Load", mais pour que celui ci se visualise je rafraîchissais la form.

    Puis au lieu de crée une exeption a chaque donnée je regardait la 1ere uniquement pour effectuer la même chose sur les suivantes, avec le code si dessus.
    Mais je n'est pas enlever le rafraîchissement et en l'enlevant c'est presque instantané maintenant.

    Toutefois je vais regarder le Double.Parse ce qui me ferais un code plus propre je pense.

    Pour répondre a Shadam: Le souci c'est que suivant la provenance de mon fichier je n'est pas forcement que des points.

    Voulant faire un programme VB.net qui s'adapterais à tout nos logiciels dans la nature

  6. #6
    Membre chevronné
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2011
    Messages
    453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

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

    Informations forums :
    Inscription : Mars 2011
    Messages : 453
    Par défaut
    Citation Envoyé par megamario Voir le message
    Le souci c'est que suivant la provenance de mon fichier je n'est pas forcement que des points.
    Ce n'est pas un problème, le Replace remplace uniquement si il trouve des ".", si il tombe sur des "," il ne fait rien et passe à la suite.

  7. #7
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 197
    Par défaut
    Citation Envoyé par Shadam Voir le message
    Ce n'est pas un problème, le Replace remplace uniquement si il trouve des ".", si il tombe sur des "," il ne fait rien et passe à la suite.
    cette solution n'est pas propre
    si on change les paramètres régionaux (même sur un os francais) double.parse("5,3") plantera car il attendra ce coup ci un point

    il existe une propriété shared quelque part sur la culture indiquant le caractère séparateur de décimal du pc sur lequel on est
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  8. #8
    Membre chevronné
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2011
    Messages
    453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

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

    Informations forums :
    Inscription : Mars 2011
    Messages : 453
    Par défaut
    Citation Envoyé par Pol63 Voir le message
    cette solution n'est pas propre
    si on change les paramètres régionaux (même sur un os francais) double.parse("5,3") plantera car il attendra ce coup ci un point

    il existe une propriété shared quelque part sur la culture indiquant le caractère séparateur de décimal du pc sur lequel on est

    Je ne sais pas mais sur mon application du moment je replace tout le temps les . par des , pour faire des opérations sur les double, et pour certain tri sur des datagridview je faist un sortCompare avec un double.parse(maValeur) qui a été enregistrée en BDD avec des , et ça fonctionne très bien.

  9. #9
    Membre éprouvé Avatar de megamario
    Homme Profil pro
    VB6/VB.net/C/C++/C#
    Inscrit en
    Septembre 2008
    Messages
    931
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : VB6/VB.net/C/C++/C#
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2008
    Messages : 931
    Par défaut
    Citation Envoyé par Shadam Voir le message
    Ce n'est pas un problème, le Replace remplace uniquement si il trouve des ".", si il tombe sur des "," il ne fait rien et passe à la suite.
    Oui effectivement j'avais pas pensé de cet façon. Mais j'ai le même souci dans l'autre sens comme l'annonce "Pol63" car le logiciel de création de la courbe est aussi fourni aux clients donc dans différent lieu de la planète et donc avec des paramètres régionaux différents.

  10. #10
    Membre chevronné
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2011
    Messages
    453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

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

    Informations forums :
    Inscription : Mars 2011
    Messages : 453
    Par défaut
    Citation Envoyé par megamario Voir le message
    Oui effectivement j'avais pas pensé dans ce sens. Mais j'ai le même souci dans l'autre sens comme l'annonce "Pol63" car le logiciel de création de la courbe est aussi fourni au client donc dans différent lieu de la planète et donc avec des paramètres régionaux différent.
    Dans ce cas
    Citation Envoyé par Pol63 Voir le message
    tant mieux pour toi
    mais un jour sur un pc ca plantera ...
    Je ne vois pas pourquoi ça fonctionnerais aujourd'hui et que dans quelques temps VB se dise "Ah mince ça fait 6 mois que j'oublie de planter sur cette ligne"....

  11. #11
    Membre éprouvé Avatar de megamario
    Homme Profil pro
    VB6/VB.net/C/C++/C#
    Inscrit en
    Septembre 2008
    Messages
    931
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : VB6/VB.net/C/C++/C#
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2008
    Messages : 931
    Par défaut
    Comme j'ai fait, cela me semblait pas mal pour être sur que cela marche partout mais je le reconnais que c'est pas très propre et je m'attendais à ce qu'il y est quelque chose de plus pratique.

    Bon la avec mon rafraîchissement enlevé cela va déjà nettement mieux, mais le fichier ne fait que 22K, lorsqu'il y aura 3 ans de stockage de données à récupérer avec une mesure toutes les 10 minutes cela va faire bien plus que 22k.

    Pour avoir une indication de chargement dans la même fenêtre que ma courbe, sans pour autant augmenté la durée par des rafraîchissements, vous préconisez quoi?
    voila ce que j'avais mis:


    Je suppose qu'il faut le charger dans un autre thread

  12. #12
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 197
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Public Module ExtendString
     
        <System.Runtime.CompilerServices.Extension()> _
        Public Function ConvertToDoubleCulture(ByVal s As string) as double
           s = s.Replace(".", System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator)
                        s = s.Replace(",",  System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator)
          return cdbl(s)
        End Function
     
    end module

    voici une méthode d'extension qui résout les 2 cas, et qui s'utilise comme ca :
    dim d as double = unstring.ConvertToDoubleCulture



    pour info, une exception est quelque chose de très couteux, il vaut mieux faire des tests plutot que d'essayer un truc et que si ca catch on fait autre chose
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réduction de la durée de préavis de licenciement
    Par Reeter dans le forum Licenciement
    Réponses: 6
    Dernier message: 10/03/2010, 10h49
  2. overflow occured during datatype conversion.
    Par eldrad95 dans le forum SQL
    Réponses: 1
    Dernier message: 11/12/2009, 16h51
  3. conversion ou lecture
    Par melmouj dans le forum Linux
    Réponses: 0
    Dernier message: 29/02/2008, 13h54
  4. Conversion de date en durée
    Par Invité dans le forum C
    Réponses: 17
    Dernier message: 19/10/2006, 20h05
  5. Conversion char/int à la lecture d'un fichier
    Par Gotterfdom dans le forum C++
    Réponses: 5
    Dernier message: 22/01/2006, 23h48

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