Enregistrer un tableau, mais aussi des lignes de text simples

[Résolu]
Signaler
Messages postés
1172
Date d'inscription
jeudi 24 mai 2007
Statut
Membre
Dernière intervention
28 septembre 2013
-
Messages postés
1172
Date d'inscription
jeudi 24 mai 2007
Statut
Membre
Dernière intervention
28 septembre 2013
-
Bonsoir la team.
Voila la question : j'arrive à enregistrer en binaire une listview via la sérialisation d'un tableau, mais je péche pour pouvoir lui y adjoindre des lignes de textes simple. (d'autres données en sommes qui ne font partis du tableau de la listview) ça me saoule grave. Je vous joins le code que j'utilise, d'avance merci bien pour votre coup de pouce. @dn
    '----------------------------------------------------------------------
    ' enregistrement du code et des lignes dans un tableau puis enregistrement via la sub REC()
    '----------------------------------------------------------------------
    Sub save()
        Dim tableau(Form1.ListView1.Items.Count - 1, Form1.ListView1.Columns.Count - 1) As String
        Dim liste As New ListViewItem

        For ligne As Integer = 0 To Form1.ListView1.Items.Count - 1
            liste = Form1.ListView1.Items(ligne)
            For Colonne As Integer = 0 To Form1.ListView1.Columns.Count - 1
                tableau(ligne, Colonne) = liste.SubItems(Colonne).Text
            Next
        Next
        rec(tableau) 'sérialisation du tableau en binaire !
    End Sub
    '----------------------------------------------------------------------
    ' fonction qui sérialise un tableau à n dimension puis l'enregistre en binaire
    '----------------------------------------------------------------------
    Sub rec(ByVal datas As Object) ' enregistre un object en binaire
        Dim myFileStream As Stream = File.Create(ma_sauvegarde)
        Dim serializer As New BinaryFormatter
        serializer.Serialize(myFileStream, datas)
        myFileStream.Close()
    End Sub
    '----------------------------------------------------------------------
    ' fonction qui lit le fichier sérialisé et qui retourne un tableau à n dimensions
    '----------------------------------------------------------------------
    Public Function lire(ByVal fichier As String) As String(,)
        Dim tableau(,) As String = {{""}, {""}} 'création d'un tableau vide
        Try
            Dim myFileStream As Stream = File.OpenRead(fichier)
            Dim deserializer As New BinaryFormatter()
            tableau = CType(deserializer.Deserialize(myFileStream), Array)
            myFileStream.Close()
            Return tableau
        Catch ex As Exception
            MsgBox("impossible à lire")
            Return tableau
        End Try
    End Function
    '----------------------------------------------------------------------


Tiens les balises ne sont pas reconnues ^_____^, zut alors.....

25 réponses

Messages postés
2813
Date d'inscription
mardi 15 avril 2003
Statut
Membre
Dernière intervention
2 juin 2020
38
Re,

Bien ou est le souci ?

Tu serialise un tableau, donc c'est un tableau qui est serialisé (passé en paramètre de ta fonction rec)

Si tu veux enregistrer d'autres type de données, crée une classe, avec des propréiété et serialise celle-ci :

Public Class MaClass 
   Private _Tableau() As String
   Private _Propriete1 As String

   Public Property Tableau() As String()
        Get
          Return _Tableau
        End Get
        Set(ByVal value As String())
          _Tableau = value
        End Set
    End Property
    Public Property Propriete1() As String
        Get
          Return _Propriete1
        End Get
        Set(ByVal value As String())
          _Propriete1 = value
        End Set
    End Property
End Class


Puis tu sérialise,

Dim X As New MaClass
Call Rec(MaClass)


Pense à changer le type pour la déserialisation (Array en MaClass)

Si le déboguage est l'art d'enlever les bogues, la programmation doit être l'art de les créer.
Messages postés
2813
Date d'inscription
mardi 15 avril 2003
Statut
Membre
Dernière intervention
2 juin 2020
38
PS: tu peux même inclure les méthodes de serialisation au sein de ta classe

MaClass.Save(FileName)
Maclass = Maclass.Load(FileName)

Par exemple.

++ Mayzz.

Si le déboguage est l'art d'enlever les bogues, la programmation doit être l'art de les créer.
Messages postés
1172
Date d'inscription
jeudi 24 mai 2007
Statut
Membre
Dernière intervention
28 septembre 2013
1
Oui je te suis, j'ai vraiment pas le reflexe des classes
Cela parrait pourtant tellement évident..
Bon j'essaye et je reviens si je suis ennuyé.
Merci bien et @++
Messages postés
1172
Date d'inscription
jeudi 24 mai 2007
Statut
Membre
Dernière intervention
28 septembre 2013
1
Bien, merci à toi je commence à comprendre en programmant ! bientôt la source dispo sur ce site pour gérer ses comptes bancaires facilement !
et ce grace à toi, oups n'oublie pas dasn la class de rajouter qu'elle esst sérialisable
merci encore à toi et si j'ai d'autre soucis je reviens vers toi
<Serializable()> Public Class Class_fichier_compte

    Private _ligne(,) As String
    Private _Type() As String
    Private _budget() As String
    Private _mdp As String

Je commence à mamuser avec vb.net ! cool
++ poto
Messages postés
2813
Date d'inscription
mardi 15 avril 2003
Statut
Membre
Dernière intervention
2 juin 2020
38
Pas de quoi mais tu sais pour gérer mon compte bancaire, pas besoin d'un soft

Si le déboguage est l'art d'enlever les bogues, la programmation doit être l'art de les créer.
Messages postés
1172
Date d'inscription
jeudi 24 mai 2007
Statut
Membre
Dernière intervention
28 septembre 2013
1
Aie dsl mais cela devrait venir, je te le souhaite.
Sinon voici ce que j'ai écrit pour les méthodes de lecture et d'enregistrement, comme j'ai pas la philosophie class quant penses tu ?

    '----------------------------------------------------------------------
    ' Sub qui sérialise la class Class_fichier_compte puis l'enregistre en binaire dans le fichier passé en paramétre
    '----------------------------------------------------------------------
    Public Sub save(ByVal fichier As String)
        Dim myFileStream As Stream = File.Create(fichier) ' création d'un nouveau fichier à chaque sauvegarde
        Dim serializer As New BinaryFormatter
        serializer.Serialize(myFileStream, Me)
        myFileStream.Close()
    End Sub
    '
    '----------------------------------------------------------------------
    ' fonction qui lit le fichier sérialisé de class Class_fichier_compte et qui retourne les tableaux a n dimensions
    '----------------------------------------------------------------------
    Public Function load(ByVal fichier As String) As Boolean
        Dim lecture As New Class_fichier_compte
        Try
            Dim myFileStream As Stream = File.OpenRead(fichier)
            Dim deserializer As New BinaryFormatter()
            lecture = CType(deserializer.Deserialize(myFileStream), Class_fichier_compte)
            myFileStream.Close()
            Me.mdp = lecture.mdp
            Me.types = lecture.types
            Me.budgets = lecture.budgets
            Me.lignes = lecture.lignes
            Return True
        Catch ex As Exception
            MsgBox("erreur de lecture, désolé", MsgBoxStyle.Critical)
            Return False
        End Try
    End Function

cela marche, mais cela doit être mal écrit.
@ pluche et merci de m'avoir permis de comprendre l'utilité des class, à moi l'automaticien
Messages postés
2813
Date d'inscription
mardi 15 avril 2003
Statut
Membre
Dernière intervention
2 juin 2020
38
Salut ADN,

Tu as totalement saisi le principe je te rassure, ce pendant il manque à ton code une gestion des erreurs d'accès aux fichiers.

Voici un petit exemple concrêt de serialisation, la procédure save utilise un autre méthode que la tienne (la tienne étant la plus adapté) je la poste car c'est un méthode à employer lors ce que l'on a une classe avec des centaines de propriétés (cela évite de la saisie), cela peut servir, dans ton cas, tu peux mettre à jour ton code existant pour la gestion des erreurs de fichiers simplement.

<Serializable()> _
Class TestSerialisable
    '
    Private _Text As String
    '
    Property Text() As String
        Get
            Return _Text
        End Get
        Set(ByVal value As String)
            _Text = value
        End Set
    End Property
    '
    Public Function loadByFile(ByVal fichier As String) As TestSerialisable
        '
        Dim myFileStream As Stream = Nothing
        '
        Try
            '
            myFileStream = New FileStream(fichier, _
                                          FileMode.Open, _
                                          FileAccess.Read, _
                                          FileShare.ReadWrite)
            '
            Dim deserializer As New BinaryFormatter()
            '
            Return CType(deserializer.Deserialize(myFileStream), TestSerialisable)
            '
        Catch ex As Exception
            '
            MessageBox.Show("Impossible de restaurer les valeurs, le fichier à été supprimé ou est utilisé par une autre application.", _
                            "Erreur de lecture", _
                             MessageBoxButtons.OK, _
                             MessageBoxIcon.Exclamation)
            '
            Return Nothing
            '
        Finally
            '
            myFileStream.Close()
            '
        End Try
        ''
    End Function

    Public Sub save(ByVal fichier As String)
        '
        If IO.File.Exists(fichier) Then
            '
            Try
                '
                IO.File.Delete(fichier)
                '
            Catch ex As Exception
                '
                MessageBox.Show("Impossible d'enregistrer les valeurs, le fichier est en cours d'utilisation par une autre application.", _
                                "Erreur", _
                                 MessageBoxButtons.OK, _
                                 MessageBoxIcon.Exclamation)
                '
                Exit Sub
                '
            End Try
            '
        End If
        '
        Dim myFileStream As Stream = Nothing
        '
        Try
            '
            myFileStream = New FileStream(fichier, _
                                          FileMode.Create, _
                                          FileAccess.Write, _
                                          FileShare.None)
            '
            Dim serializer As New BinaryFormatter
            '
            serializer.Serialize(myFileStream, Me)
            '
        Catch ex As Exception
            '
            MessageBox.Show("Impossible d'enregistrer les valeurs, dans le fichier. Vérifiez que votre compte utilisateur possède les droits requis.", _
                            "Erreur d'accès en écriture", _
                             MessageBoxButtons.OK, _
                             MessageBoxIcon.Exclamation)
            '
        Finally
            '
            myFileStream.Close()
            '
        End Try
        ''
    End Sub
End Class   


Pour l'insatiation c'est aussi différent :

        Dim T As New TestSerialisable

        T.Text = "Trahiudhsuidh"
        T.save("c:\test.bin")
        T = T.loadByFile("c:\test.bin")



Si le déboguage est l'art d'enlever les bogues, la programmation doit être l'art de les créer.
Messages postés
2813
Date d'inscription
mardi 15 avril 2003
Statut
Membre
Dernière intervention
2 juin 2020
38
instanciation pardon, instanciation...

Mais si je commence à corriger mon orthographe médiocre... j'ai pas fini...

En tous cas a force de recherches tu vas trouver (la recherche d'ADN, Hohohahahohahouhouhou )

(Oui c'était de l'humour... ===> OK je sors !)

Si le déboguage est l'art d'enlever les bogues, la programmation doit être l'art de les créer.
Messages postés
1172
Date d'inscription
jeudi 24 mai 2007
Statut
Membre
Dernière intervention
28 septembre 2013
1
RE-AIE !
voila e soucis, dans ma class j'ai deux tableaux, les types (cb, chq..) et les budget (maison,voiture,travaux,paye...)
lorsque l'user donne un nouveau type ou un nouveau budget il faut que je le detect pour le sauvegarder, et là j'ai bien le début, mais j'ai un peu de mal avec la fin
voici le code :
        '----------------------------------------------------------------------
        ' enregistrement des tableaux & lignes dans la class mon_compte 
        '----------------------------------------------------------------------
        Dim tableau(ListView1.Items.Count - 1, ListView1.Columns.Count - 1) As String
        Dim liste As New ListViewItem
        For ligne As Integer = 0 To ListView1.Items.Count - 1
            liste = ListView1.Items(ligne)
            For Colonne As Integer = 0 To ListView1.Columns.Count - 1
                tableau(ligne, Colonne) = liste.SubItems(Colonne).Text
            Next
        Next
        'recherche si le budget et le type exist déja ou pas
        For ligne As Integer = 0 To ListView1.Items.Count - 1
            liste = ListView1.Items(ligne)
            Dim recherche_type As String = liste.SubItems(2).Text
            For type As Integer = 0 To choix_type.Length - 1

            Next
            Dim recherche_budget As String = liste.SubItems(3).Text
            For budget As Integer = 0 To choix_budget.Length - 1

            Next
            
        Next ligne
        ' attribut les valeurs des différents tableaux à sérialiser ! merci Mayzz ^^
        mon_compte.lignes = tableau
        mon_compte.budgets = choix_budget
        mon_compte.types = choix_type
        mon_compte.save(ma_sauvegarde)


Tout es lu via une liste box, doc j'imagine un truc du style : 'If choix_budget.ToString <> liste.SubItems(3).Text Then choix_budget() = liste.SubItems(3).Text, mais voila cela sens le bug
si une bonne âme à une idée je prends cela me fera gagner plusieurs heures de recherche !
Faut vraiment que je me trouve une bonne formation moi
d'avance merci
Messages postés
1172
Date d'inscription
jeudi 24 mai 2007
Statut
Membre
Dernière intervention
28 septembre 2013
1
PS : j'ai pas vu que tu avais déja posté ! merci et mouarff pour le coup de l'adn ^______^
oups c'est pas list box mais list view au fait, je tappe plus vite que je ne réfléchi
Bon spa tout ça j'ai du code à modifier mouha ! (faut déja que je décrypte ce que tu post, avec moi cela peu prendre un peu de temps )
Car je viens de te lire et effet c'est plus , hum comment dire ?, balaise ! faut que je pige ^^ je ferais ça demain là j'ai ma dose de prog pour aujourd'hui ^^
Encore merci pour ton aide, tu seras bien cité dans mon soft !
Et bon courage pour les pépéttes
Messages postés
1172
Date d'inscription
jeudi 24 mai 2007
Statut
Membre
Dernière intervention
28 septembre 2013
1
Bonsoir à tous, et surtout à Mayzz (au secours !)
Je m'arrache les cheveux (j'en ai plus beaucoup en plus)
voila le binss
j'alimente une combobox avec un datasource de la class compte, mais voila lorsque je modifie un champ de ces combox il l'enregitre bien dans le fichier mais pas dasn la propriété budget ou type (ceux qui alimente les combosbox )
Voici mon code, si tu pouvais trouver quelques minutes pourme répondre cela serai sympa car le net ne me donne rien :(
la form principal donne les valeurs qui viennent de la class compte dont nous parlons depuis le début du post, jusque là tout vas bien :
        ' lecture des tableaux des combobox dasn le load de la form nouvelle opération
        Combo_budget.DataSource = principal.mon_compte.budgets
        Combo_type.DataSource = principal.mon_compte.types

puis si l'user veux changer un type de paimenent ou un budget via une des combos il le peut cela marche mais je n'arrive pas à enregistrer sa nouvelle saisie dans la classe mon_compte
pourtant j'ai essayé cela :
    Private Sub Combo_budget_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Combo_budget.SelectedIndexChanged
        ' fait rien
    End Sub

    Private Sub Combo_budget_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Combo_budget.TextChanged
        ' fait rien
    End Sub
    Private Sub Combo_budget_DataSourceChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Combo_budget.DataSourceChanged
        ' fait rine non plus
' l code principal.mon_compte.budgets Combo_budget.DataSource
    End Sub

Je pense que cela vient du fait qu'utiliser une datasource place la combo en read_only, alors j'essaye de le faire item par item, mais je vois pas comment enregistrer le tout !
steuplé help me
Merci d'avance pour vos conseils.
Messages postés
2813
Date d'inscription
mardi 15 avril 2003
Statut
Membre
Dernière intervention
2 juin 2020
38
Heu j'ai pas bien compris le but de ton code...

Tu as des tableau dont les valeurs sont sérialisé/déserialisé, OK
Tu as des combos remplis par ces tableau via DataSource, OK

Mais pour le reste, que veux-tu enregistrer ? La nouvelle saisie d'un utilisateur dans le combo vers ton tableau ?
Ou la sélection d'un combo vers => ?

Si tu m'avais dis dès le départ que le but était de stocker des données, je t'aurais orienté vers une base de données SQL Server Compact Ed. (Base de données locale), celle-ci est la solution la plus adapté (donc la plus simple) pour le travaille avec des données.

Si le déboguage est l'art d'enlever les bogues, la programmation doit être l'art de les créer.
Messages postés
1172
Date d'inscription
jeudi 24 mai 2007
Statut
Membre
Dernière intervention
28 septembre 2013
1
Nan pas besoin de BDD, tout marche nickel, juste que lorsqu'un utilisateur tappe une nouvelle entrée dans une combobox, je voudrais la rajouter au tableau du datasource (qui est en fait une des propriétés de la class que nous avons créé).
Donc pour résumer, je lis la class, puis je transfért dans deux combobox les propriétés .type et .budget qui sont des tableaux de string une dimension.
Donc je passe par le datasource des combos.
Cela roule je retrouve toutes les valeurs de ces tableaux dans les choix des combos. Seulement si l'user saisi une nouvelle ligne (par exemple un nouveau budget : crédit voiture) je n'arrive pas à le récuperer pour l'ajouter à la propriété de ma class. En revanche il s'inscrit bien dans la nouvelle ligne de la listview.
Donc soit j'ajoute la nouvelle saisie lors de la modif de la combo (le plus simple), soit je relis tous les items de la listview et je recherche dans le tableau .budget si elle existe ou pas, puis je l'ajoute si pas déja présente dans le tableau .budget (le plus long sur beaucoup d'items)

En gros pour simplifier au max c'est comment ajouter une nouvelle saisie d'une combobox dans un datasource qui l'alimente.
Si vraiment je ne suis pas clair je poste ma source non fini pour que tu vois par toi même.
Merci de ton temps et de ton aide. cordialement.
Messages postés
1172
Date d'inscription
jeudi 24 mai 2007
Statut
Membre
Dernière intervention
28 septembre 2013
1
j'essaye cela en ce moment mais là pas le temps faut que je dorme, plu d'info demain midi ! ++ poto

Private Sub ComboBox1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles ComboBox1.KeyDown
    If e.KeyCode = Keys.Delete Then
        If ComboBox1.Items.Contains(Me.ComboBox1.Text) Then
            Me.ComboBox1.Items.Remove(Me.ComboBox1.Text)
        End If
    ElseIf e.KeyCode = Keys.Enter AndAlso Not ComboBox1.Items.Contains(Me.ComboBox1.Text) Then
        Me.ComboBox1.Items.Add(Me.ComboBox1.Text)
    End If
End Sub
Messages postés
2813
Date d'inscription
mardi 15 avril 2003
Statut
Membre
Dernière intervention
2 juin 2020
38
Oui comme tu le dis, plusieurs choix :

- Possibilité aussi, de vider le tableau (Clear) puis de le remplir avec les éléments du listview, de cette façon, il sera tjs à jour. Cette solution est à appliqué si tu veux un formulaire avec une commande annulé (ne s'applique qu'a la validation du formulaire), pour le reste, si tu veux que ce soit valide à la saisie, ton code est le plus approprié.

Si je comprend bien aussi, ton combo est un DropDownList, donc readOnly et les ajouts se font via un textbox ?



Si le déboguage est l'art d'enlever les bogues, la programmation doit être l'art de les créer.
Messages postés
1172
Date d'inscription
jeudi 24 mai 2007
Statut
Membre
Dernière intervention
28 septembre 2013
1
ah ben la voila la connerie ! il est en effet dropdownlist ! et les ajouts se font directement via la combo. Il faut donc que je trouve comment activer l'ecriture.
De plus lorsque je tappe le code du dessus il me balance une erreur (un datasource est en lecture seul) il faut je pense que je réécrive le datasource et que je le rebalance dans la combo. je test cela de suite. je vais voir s'il accepte :
Not tableau.Items.Contains(Me.ComboBox1.Text) Then tableau.items.add
(Me.ComboBox1.Text)
' puis
combobox1.datasource = tableau 

@ voir, merci et a toute suite.
Messages postés
1172
Date d'inscription
jeudi 24 mai 2007
Statut
Membre
Dernière intervention
28 septembre 2013
1
Bon bien sur marche pas, items n'est pas un membres de array :(
biensur je ne peux pas non plus faire un simple :
If Not principal.mon_compte.budgets.Contains(Combo_budget.SelectedText) Then
            principal.mon_compte.budgets.add(Combo_budget.SelectedText)
        End If

Mais je sens que je m'approche doucement de la soluce
Messages postés
1172
Date d'inscription
jeudi 24 mai 2007
Statut
Membre
Dernière intervention
28 septembre 2013
1
principal.mon_compte.budgets &= Combo_budget.SelectedText
non plus

Ouhou voial la soluce qui à l'air de marcher !
        'transférer dans les tableaux de la class mon_compte.types et budget les modifs éventuels des combobox
        If Not Combo_budget.Items.Contains(Me.Combo_budget.Text) Then 'si detection d'une nouvelle saisie
            ' l'enregistre dans les tableaux de la class mon_compte.budget en redimensionnant le tableau
            ReDim Preserve principal.mon_compte.budgets(principal.mon_compte.budgets.Length)
            principal.mon_compte.budgets(principal.mon_compte.budgets.Length - 1) = Me.Combo_budget.Text
        End If
        If Not Combo_type.Items.Contains(Me.Combo_type.Text) Then 'si detection d'une nouvelle saisie
            ' l'enregistre dans les tableaux de la class mon_compte.type
            ReDim Preserve principal.mon_compte.types(principal.mon_compte.types.Length)
            principal.mon_compte.types(principal.mon_compte.types.Length - 1) = Me.Combo_type.Text
        End If


bon maintenant passons à la suppression d'une ligne de ces fameuse combobox

Desuite je me lance sur :
    Private Sub Combo_budget_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Combo_budget.KeyDown
        If e.KeyCode = Keys.Delete Then
            If Combo_budget.Items.Contains(Me.Combo_budget.Text) Then Me.Combo_budget.Items.Remove(Me.Combo_budget.Text)
        End If
    End Sub

et ben pas le chien ! une datasource est readonly la vache j'en ai marre
bON il faut que je me débrouille pour trouver l'index qui est selected et que je le supp du datasource, pi ensuite le recharger dans la combo enfin j'imagine..brrr ça va pas être simple tout ça...
Messages postés
1172
Date d'inscription
jeudi 24 mai 2007
Statut
Membre
Dernière intervention
28 septembre 2013
1
biensur un simple :
    Private Sub Combo_budget_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Combo_budget.KeyDown
        If e.KeyCode = Keys.Delete Then
            If Combo_budget.Items.Contains(Me.Combo_budget.Text) Then
            ElseIf MessageBox.Show("confirmer la suppression du budget" & vbCrLf & Combo_budget.Text & " ?", "Suppression" _
, MessageBoxButtons.YesNo) = Windows.Forms.DialogResult.Yes Then

            End If
        End If
        'Me.Combo_budget.Items.Remove(Me.Combo_budget.Text)
    End Sub


ne marche pas
bon ben je laisse tomber pour ce soir et désolé pour le roman ^^ mais cela pourra servir je pense ;)
@++
Messages postés
1172
Date d'inscription
jeudi 24 mai 2007
Statut
Membre
Dernière intervention
28 septembre 2013
1
Bon no problémo j'ai tout résolu ... pas si nul que ça l'automaticien
Bientot je post ma source pour que les autres en profite !
Merci encore MAYZZ pour ton aide
Et vive le flood utile