Mon objectif est de créer un nœud enfant avec une clé spécifique en sélectionnant le nœud parent dans mon treeview
TreeViewToolBox
en utilisation ce code ci -dessous:
Dim StatusDate As String
StatusDate = InputBox("Saisir le Nom du dossier que vous voulez créer dans " & fils.Text)
If StatusDate = "" Then
MsgBox("Vous devez saisir un Nom.")
Exit Sub
Else
Dim trace As String = System.DateTime.Now.ToString("ddMMyyyy" & "HHmmss")
' Add(Of String, String)
Dim newNode As New TreeNode With {.nom = trace, .Text = StatusDate}
TreeViewToolBox.SelectedNode.Nodes.Add(newNode)
Me.Textkey.Text = newNode.nom
End If
End If
Dans mon code j'attribue une clé spécifique (trace) à chaque nœud enfant créé.
Ce procédé fonctionne sur le coup car quand je sélectionne le nœud enfant que je viens de créer j'obtiens bien le text
trace
avec ce code
MsgBox(TreeViewToolBox.SelectedNode.nom)
.
Jusqu'ici pas de souci .
Mon treeview est stocké dans une base qui se charge à l'ouverture du Form.
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim conn = New SQLiteConnection("Data Source=BDD.s3db;Version=3")
Try
Using (conn)
conn.Open()
Dim sql = "Select * FROM ARBORESCENCE"
Dim cmdDataGrid As SQLiteCommand = New SQLiteCommand(sql, conn)
Dim da As New SQLiteDataAdapter
da.SelectCommand = cmdDataGrid
Dim dta As New DataTable
da.Fill(dta)
dgvDataArbo.DataSource = dta
TreeViewToolBox.Nodes.Clear()
For Each dr As DataRow In dta.Rows
AddNode(dr("PARENT").ToString, dr("FILS").ToString)
Next
end if
Problème :Problème
Après l’ouverture de la Form , j'ai toujours le nœud enfant créé mais sa clé (trace) a disparu !!!
Est ce un souci de stockage dans la BDD , si oui pourriez vous m'aider à créer la clé et conserver la spécifique pour chaque nœud créé?
Bonjour
Tu dis : Après l’ouverture de la Form , j'ai toujours le nœud enfant créé mais sa clé (trace) a disparu !!! Cette clé est-elle sauvegardé dans la base de données avec le nœud correspondant ?
Bonjour VB95
Merci pour ta réponse
C'est bien ça mon problème . je ne sais pas comment ou plutôt ou sauvegarder cette clé dans la BDD.
J'avais pensé créer une colonne nommée Key sur ma BDD mais comment la charger avec le nœud correspondant?
Dim ARBORESCENCE As New m_ARBORESCENCE(0) If SelID = 0 Then Ajouter2() Dim conn = New SQLiteConnection("Data Source=BDD.s3db;Version=3") Using (conn) conn.Open() Dim sql = "SELECT * FROM ARBORESCENCE" Dim cmdDataGrid As SQLiteCommand = New SQLiteCommand(sql, conn) Dim da As New SQLiteDataAdapter da.SelectCommand = cmdDataGrid Dim dt As New DataTable da.Fill(dt) dgvDataArbo.DataSource = dt
End Using TreeViewToolBox.ExpandAll() MsgBox("enregistré")
Private Sub Ajouter2() Dim ARBORESCENCE = New m_ARBORESCENCE(DBNewIndexARBORESCENCE) ARBORESCENCE.FILS = fils.Text ARBORESCENCE.INDEXFILS = filsindex.Text ARBORESCENCE.PARENT = parent.Text ARBORESCENCE.INDEXPARENT = parentindex.Text ARBORESCENCE.key = Textkey.Text DBaddARBORESCENCE(ARBORESCENCE) End Sub
Public Sub DBaddARBORESCENCE(ByVal ARBORESCENCE As m_ARBORESCENCE) Try Dim strSQL As String = "INSERT INTO ARBORESCENCE VALUES (@Id,@FILS,@INDEXFILS,@PARENT,@INDEXPARENT,@key)" Dim cmd = New SQLiteCommand(strSQL, CON) cmd.Parameters.AddWithValue("@ID", ARBORESCENCE.ID) cmd.Parameters.AddWithValue("@FILS", ARBORESCENCE.FILS) cmd.Parameters.AddWithValue("@INDEXFILS", ARBORESCENCE.INDEXFILS) cmd.Parameters.AddWithValue("@PARENT", ARBORESCENCE.PARENT) cmd.Parameters.AddWithValue("@INDEXPARENT", ARBORESCENCE.INDEXPARENT) cmd.Parameters.AddWithValue("@key", ARBORESCENCE.key) cmd.ExecuteNonQuery() cmd.Dispose() Catch ex As Exception MessageBox.Show(ex.Message) End Try
Bonjour
Désolée du "code chiffon"
ci dessous avec la coloration Syntaxique
Dim ARBORESCENCE As New m_ARBORESCENCE(0)
If SelID = 0 Then Ajouter2()
Dim conn = New SQLiteConnection("Data Source=BDD.s3db;Version=3")
Using (conn)
conn.Open()
Dim sql = "SELECT * FROM ARBORESCENCE"
Dim cmdDataGrid As SQLiteCommand = New SQLiteCommand(sql, conn)
Dim da As New SQLiteDataAdapter
da.SelectCommand = cmdDataGrid
Dim dt As New DataTable
da.Fill(dt)
dgvDataArbo.DataSource = dt
End Using
TreeViewToolBox.ExpandAll()
MsgBox("enregistré")
Private Sub Ajouter2()
Dim ARBORESCENCE = New m_ARBORESCENCE(DBNewIndexARBORESCENCE)
ARBORESCENCE.FILS = fils.Text
ARBORESCENCE.INDEXFILS = filsindex.Text
ARBORESCENCE.PARENT = parent.Text
ARBORESCENCE.INDEXPARENT = parentindex.Text
ARBORESCENCE.key = Textkey.Text
DBaddARBORESCENCE(ARBORESCENCE)
End Sub
Public Sub DBaddARBORESCENCE(ByVal ARBORESCENCE As m_ARBORESCENCE)
Try
Dim strSQL As String = "INSERT INTO ARBORESCENCE VALUES (@Id,@FILS,@INDEXFILS,@PARENT,@INDEXPARENT,@key)"
Dim cmd = New SQLiteCommand(strSQL, CON)
cmd.Parameters.AddWithValue("@ID", ARBORESCENCE.ID)
cmd.Parameters.AddWithValue("@FILS", ARBORESCENCE.FILS)
cmd.Parameters.AddWithValue("@INDEXFILS", ARBORESCENCE.INDEXFILS)
cmd.Parameters.AddWithValue("@PARENT", ARBORESCENCE.PARENT)
cmd.Parameters.AddWithValue("@INDEXPARENT", ARBORESCENCE.INDEXPARENT)
cmd.Parameters.AddWithValue("@key", ARBORESCENCE.key)
cmd.ExecuteNonQuery()
cmd.Dispose()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Bonjour
Dans ton premier message tu as bien utilisé la coloration syntaxique . Pourquoi ne pas l'avoir utilisé dans ton dernier message ?
De plus dans tout code un minimum de commentaires est plus que bénéfique . Cela permet de savoir ce que le code fait et de plus dans quelques temps si tu reviens sur ce code ces indications te seront précieuses .
Tertio dans le premier bloc de code la procédure n'est pas complète . Du coup difficile pour nous de comprendre exactement le rôle de chaque procédure .
Ici, il te faut un champ supplémentaire dans la base de données et y enregistrer la valeur de trace
Public Sub DBaddARBORESCENCE(ByVal ARBORESCENCE As m_ARBORESCENCE)
Try
Dim strSQL As String = "INSERT INTO ARBORESCENCE VALUES (@Id,@FILS,@INDEXFILS,@PARENT,@INDEXPARENT,@key)"
Dim cmd = New SQLiteCommand(strSQL, CON)
cmd.Parameters.AddWithValue("@ID", ARBORESCENCE.ID)
cmd.Parameters.AddWithValue("@FILS", ARBORESCENCE.FILS)
cmd.Parameters.AddWithValue("@INDEXFILS", ARBORESCENCE.INDEXFILS)
cmd.Parameters.AddWithValue("@PARENT", ARBORESCENCE.PARENT)
cmd.Parameters.AddWithValue("@INDEXPARENT", ARBORESCENCE.INDEXPARENT)
cmd.Parameters.AddWithValue("@key", ARBORESCENCE.key)
cmd.ExecuteNonQuery()
cmd.Dispose()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
sub DBaddARBORESCENCE (ByVal ARBORESCENCE As m_ARBORESCENCE)
tu enregistres des objets de types m_ARBORESCENCE qui à priori viennent de tes noeuds de treeview.
Mais le code de lecture de base de données charge un datagridview (pas de trevieew) sans créer d'instances de m_ARBORESCENCE.
Donc soit tu n'as pas montré le bon code, soit c'est pas cohérent.
Si tu veux enregistre des serviettes, il faut lire des serviettes, pas des torchons.
Bonjour merci de ta réponse
dans la procédure sub DBaddARBORESCENCE (ByVal ARBORESCENCE As m_ARBORESCENCE)
tu enregistres des objets de types m_ARBORESCENCE qui à priori viennent de tes nœuds de treeview.
.
Oui c'est bien ça
Mais le code de lecture de base de données charge un datagridview (pas de trevieew) sans créer d'instances de m_ARBORESCENCE.
le datagridview et le treeview ont la même source
'''A l'ouverture de la form
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'''Connxion à la base de donnée BDD et acces à la table ARBORESCENCE
Dim conn = New SQLiteConnection("Data Source=BDD.s3db;Version=3")
Try
Using (conn)
conn.Open()
Dim sql = "Select * FROM ARBORESCENCE"
Dim cmdDataGrid As SQLiteCommand = New SQLiteCommand(sql, conn)
Dim da As New SQLiteDataAdapter
da.SelectCommand = cmdDataGrid
'datatable dta crée qui va enrichir la BDD et treeview
Dim dta As New DataTable
da.Fill(dta)
''BDD ARBORESEBCE alimentéé
dgvDataArbo.DataSource = dta
''épuration du treeview
TreeViewToolBox.Nodes.Clear()
''Alimentation du treeview
For Each dr As DataRow In dta.Rows
AddNode(dr("PARENT").ToString, dr("FILS").ToString)
Next
end if
Je ne peux pas essayer ton code car, il en manque des morceaux utiles (AddNode par exemple) et surtout je n'ai pas trouvé d'où sortent les classes SQLiteConnection, SQLiteCommand et SQLiteDataAdapter
J'ai donc essayé de te faire un exemple avec un csv.
J'ai imaginé que ta classe métier dérive de TreeNode.
Imports System.Windows.Forms
Class NoeudJulia
Inherits TreeNode
Public Property ID As Integer
Public Property IdParent As Integer
Public Property IdEnfant As Integer
Public Property Enfant As NoeudJulia
End Class
Y'a qu'un enfant par noeud pour simplifier l'exemple
J'ai un formulaire avec 3 boutons, un datagridview et un treeview.
Le 1er bouton crée une liste de 4 noeuds, qu'on pourra ensuite enregistrer en CSV avec le bouton adéquat.
Le dernier bouton lit charge fichier csv dans la liste.
Que la liste soit créée par le bouton ou lue dans le csv, elle est affichée dans le datagridview et le treeview
Imports System
Imports System.Collections.Generic
Imports System.Data
Imports System.IO
Imports System.Linq
Imports System.Windows.Forms
Public Partial Class frmJulia
Inherits Form
Private fichierCsv As String = "noeudsJulia.csv"
Public Sub New()
InitializeComponent()
'si le fichier existe déjà, il faut le lire
If File.Exists(fichierCsv) Then butCreerListe.Enabled = False
butLire.Enabled = Not butCreerListe.Enabled
End Sub
Private noeuds As List(Of NoeudJulia)
''' <summary>
'''Création de la liste "neuve"
'''</summary>
''' <param name="sender"></param>
'''<param name="e"></param>
Private Sub butCreerListe_Click(ByVal sender As Object, ByVal e As EventArgs)
noeuds = New List(Of NoeudJulia) From {
New NoeudJulia With {
.ID = 1,
.IdEnfant = 2,
.IdParent = 0,
.Name = "Nom 1",
.Text = "Nom 1"
},
New NoeudJulia With {
.ID = 2,
.IdEnfant = 3,
.IdParent = 1,
.Name = "Nom 2",
.Text = "Nom 2"
},
New NoeudJulia With {
.ID = 3,
.IdEnfant = 4,
.IdParent = 2,
.Name = "Nom 3",
.Text = "Nom 3"
},
New NoeudJulia With {
.ID = 4,
.IdEnfant = 0,
.IdParent = 3,
.Name = "Nom 4",
.Text = "Nom 4"
}
}
AfficheNoeuds()
End Sub
''' <summary>
''' Affiche la liste en cours
''' </summary>
Private Sub AfficheNoeuds()
dataGridView1.DataSource = Nothing
dataGridView1.DataSource = noeuds
treeView1.Nodes.Clear()
For Each n As NoeudJulia In noeuds
n.Enfant = noeuds.SingleOrDefault(Function(x) x.ID = n.IdEnfant)
If n.IdParent = 0 Then
treeView1.Nodes.Add(n)
Else
treeView1.SelectedNode.Nodes.Add(n)
End If
treeView1.SelectedNode = n
Next
End Sub
''' <summary>
''' Enregistrement dans le fichier CSV
''' </summary>
'''<param name="sender"></param>
''' <param name="e"></param>
Private Sub butEnregistrer_Click(ByVal sender As Object, ByVal e As EventArgs)
File.WriteAllLines(fichierCsv, noeuds.[Select](Function(n) String.Format("{0};{1};{2};{3}", n.ID, n.IdParent, n.IdEnfant, n.Name)))
butCreerListe.Enabled = False
butLire.Enabled = True
End Sub
Private Sub butLire_Click(ByVal sender As Object, ByVal e As EventArgs)
noeuds = (From ligne In File.ReadAllLines(fichierCsv) Let tab = ligne.Split(";"c) Select New NoeudJulia With {
.ID = Convert.ToInt32(tab(0)),
.IdParent = Convert.ToInt32(tab(1)),
.IdEnfant = Convert.ToInt32(tab(2)),
.Name = tab(3),
.Text = tab(3)
}).ToList()
AfficheNoeuds()
End Sub
End Class
Peux tu tester ça dans un projet à part et me dire si cela ressemble à ce que tu cherches à faire?
Bonjour Wishmeril
Gros merci pour ce super job .
Tu as bien compris à 80% mes soucis meme si moi j'utilise
Dim trace As String = System.DateTime.Now.ToString("ddMMyyyy" & "HHmmss")
' Add(Of String, String)
Dim newNode As New TreeNode With {.Name = trace, .Text = StatusDate}
'Dim newNode As TreeNode = New TreeNode(StatusDate)
TreeViewToolBox.SelectedNode.Nodes.Add(newNode)
Dans ton exemple , les nœuds parent et fils avec le name (clé unique) sont crées et le datagridiview est renseigné .ok
je peux stocker tout ça dans une BDD qui servira de source à l'ouverture. ok
Mais comment charger la clé unique (name) attribuée a chaque noeud ?
mon code c'est
''Alimentation du treeview
For Each dr As DataRow In dta.Rows
AddNode(dr("PARENT").ToString, dr("FILS").ToString)
Next
Mon exemple avait pour but de te montrer que si j'enregistre des instances de Machin, pour récupérer toutes les données, à la lecture il faut créer des instances de Machin.
Tu montres, encore et toujours un code qui crée des Nodes et des lignes de datagridview alors que tu as enregistré des instances de m_ARBORESCENCE
La propriété Name ne doit pas être un identifiant unique.
C'est bien pour cela que l'objet que j'ai écrit comme exemple (NoeudJulia) dispose d'une propriété dédiée ID et 2 propriétés IdParent, et IdEnfant (en pratique on devrait pouvoir se débrouiller, juste avec IdParent).
Pour pouvoir t'aider au mieux, il nous faut avant tout cerner ton besoin, il nous manque
le code de AddNode (ça je l'ai déjà écrit)
le code de m_ARBORESCENCE
d'où viennent tes classes de connexion (ça aussi je l'ai déjà écrit)
Bonsoir
le code de AddNode (ça je l'ai déjà écrit)
Public Sub AddNode(parentNode As String, nodeText As String)
Dim node As New List(Of TreeNode)
node.AddRange(TreeViewToolBox.Nodes.Find(parentNode, True))
If Not node.Any Then
node.Add(TreeViewToolBox.Nodes.Add(parentNode, parentNode))
End If
node(0).Nodes.Add(nodeText, nodeText)
End Sub
le code de m_ARBORESCENCE
Private Sub Ajouter2()
Dim ARBORESCENCE = New m_ARBORESCENCE(DBNewIndexARBORESCENCE)
ARBORESCENCE.FILS = fils.Text
ARBORESCENCE.INDEXFILS = filsindex.Text
ARBORESCENCE.PARENT = parent.Text
ARBORESCENCE.INDEXPARENT = parentindex.Text
DBaddARBORESCENCE(ARBORESCENCE)
End Sub
d'où viennent tes classes de connexion (ça aussi je l'ai déjà écrit)
Public Structure m_ARBORESCENCE
Dim ID As Integer
Dim FILS As String
Dim INDEXFILS As String
Dim PARENT As String
Dim INDEXPARENT As String
Public Sub New(ByVal Idx1 As Integer)
ID = Idx1
FILS = ""
INDEXFILS = 0
End Sub
End Structure
peut il y avoir plusieurs enfants par parent ? oui bien sur
Public Structure m_ARBORESCENCE
Dim ID As Integer
Dim FILS As String
Dim INDEXFILS As String
Dim PARENT As String
Dim INDEXPARENT As String
Public Sub New(ByVal Idx1 As Integer)
ID = Idx1
FILS = ""
INDEXFILS = 0
End Sub
End Structure
C'est une structure, admettons, c'est pas trop .Net et gourmand en mémoire, mais ça marche.
Par contre tu dis
peut il y avoir plusieurs enfants par parent ?
oui bien sur
et le membre Fils est juste une string. Il serait plus logique que ce soit une collection de m_Arborescence (une liste par exemple).
Quand je te demande d'où viennent tes classes connexions, je parle de SQLiteCommand et SQLiteDataAdapter. Celles que j'ai trouvées sur le net ne correspondent pas à ton code.
je te passe l'ensemble des codes du module modSQLite.vb
Imports System.Data.SQLite
Imports System.IO
Module modSQLITE
Public Database As String
Dim CON As New SQLiteConnection
Public Sub OpenDataBase()
Try
Database = My.Application.Info.DirectoryPath & "\BDD.s3db"
CON.ConnectionString = "Data Source=" & Database
CON.Open()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
'
Public Sub CloseDatabase()
CON.Close()
End Sub
Public Structure m_ARBORESCENCE
Dim ID As Integer
Dim FILS As String
Dim INDEXFILS As String
Dim PARENT As String
Dim INDEXPARENT As String
Dim key As String
Public Sub New(ByVal Idx1 As Integer)
ID = Idx1
FILS = ""
INDEXFILS = 0
key = 0
End Sub
End Structure
Public Sub DBaddARBORESCENCE(ByVal ARBORESCENCE As m_ARBORESCENCE)
Try
Dim strSQL As String = "INSERT INTO ARBORESCENCE VALUES (@Id,@FILS,@INDEXFILS,@PARENT,@INDEXPARENT,@key)"
Dim cmd = New SQLiteCommand(strSQL, CON)
cmd.Parameters.AddWithValue("@ID", ARBORESCENCE.ID)
cmd.Parameters.AddWithValue("@FILS", ARBORESCENCE.FILS)
cmd.Parameters.AddWithValue("@INDEXFILS", ARBORESCENCE.INDEXFILS)
cmd.Parameters.AddWithValue("@PARENT", ARBORESCENCE.PARENT)
cmd.Parameters.AddWithValue("@INDEXPARENT", ARBORESCENCE.INDEXPARENT)
cmd.Parameters.AddWithValue("@key", ARBORESCENCE.key)
cmd.ExecuteNonQuery()
cmd.Dispose()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Public Function DBgetARBORESCENCE(ByVal Idx As Integer) As m_ARBORESCENCE
Dim strSQL As String = "SELECT * FROM ARBORESCENCE WHERE ID= " & Idx
Dim ARBORESCENCE As New m_ARBORESCENCE
Dim cmd = New SQLiteCommand(strSQL, CON)
Dim DR As SQLiteDataReader = cmd.ExecuteReader
While (DR.Read())
ARBORESCENCE.ID = DR(0)
ARBORESCENCE.FILS = DR(1)
ARBORESCENCE.INDEXFILS = DR(2)
ARBORESCENCE.PARENT = DR(3)
ARBORESCENCE.INDEXPARENT = DR(4)
End While
DR.Close()
cmd.Dispose()
Return ARBORESCENCE
End Function
Public Sub DBdeleteARBORESCENCE(ByVal Idx1 As Integer)
Dim strSQL As String = "DELETE FROM ARBORESCENCE WHERE ID= " & Idx1
Dim cmd = New SQLiteCommand(strSQL, CON)
cmd.ExecuteNonQuery()
cmd.Dispose()
End Sub
Public Function DBNewIndexARBORESCENCE() As Integer
Dim NewID As Integer = 1
Dim cmd = New SQLiteCommand("SELECT MAX(ID) FROM ARBORESCENCE", CON)
Try
Dim DR As SQLiteDataReader = cmd.ExecuteReader
While (DR.Read())
NewID = DR(0)
End While
DR.Close()
Return NewID + 1
Catch ex As Exception
Return NewID
End Try
End Function
End Module
Je te joins dans le lien ci dessous mon projet "brut" pour plus de visibilité .
https://www.cjoint.com/c/JKwjUPiPFEZ
En gros mon souci depuis 3 jours ( Grrr!!!) c'est d'affecter une clé fixe au noeud créé: Clé qui sera la valeur de trace dans mon projet .
Cette clé , une fois crée va être stocké dans la BDD dans la colonne "Key" . Et elle doit être chargée toujours comme clé du noeud correspondant quand je Load le treeview. Ce qui n’est pas le cas .
L'utilité de cette clé sera de pouvoir toujours repérer son noeud dans la BDD et de pouvoir agir dessus .
Je n'ai pas ouvert ton projet, j'ai écrit le mien.
D'abord avec un éditeur de bdd sqlite, j'ai créé une base de test, mon éditeur ne gère pas l'extension que tu as utilisée, alors je l'ai appelée BDD.db
Voici sa structure,
Il est impératif que ID soit unique et auto incrément
Voici les données de départ
Voici 2 classes (je t'expliquerai plus tard si ce code te convient pourquoi il ne faut pas que ce soit des structures)
La premiere c'est ma version de m_arborescence, la seconde dérive de TreeNode et contient un m_arborescence (comme ça c'est toujours lié)
Imports System
Imports System.Collections.Generic
Imports System.Data
Imports System.Data.SQLite
Imports System.Linq
Imports System.Windows.Forms
''' <summary>
''' Classe métier
''' </summary>
Public Class m_ARBORESCENCE
''' <summary>
''' Construction d'une instance à partir d'une ligne de bdd
''' </summary>
Public Sub New(ByVal DR As DataRow)
Nom = DR("Nom").ToString()
ID = Convert.ToInt32(DR("ID"))
IdParent = Convert.ToInt32(DR("IdParent"))
End Sub
''' <summary>
''' Construction d'une instance à partir des données saisies
''' </summary>
Public Sub New(ByVal LeNom As String, ByVal LIdParent As Integer, ByVal CON As SQLiteConnection)
Nom = LeNom
IdParent = LIdParent
InsertBdd(CON)
End Sub
''' <summary>
''' Insère cette nouvelle valeur dans la BDD et récupère l'ID
''' </summary>
''' <param name="CON"></param>
Private Sub InsertBdd(ByVal CON As SQLiteConnection)
Try
Dim strSQL As String = "INSERT INTO ARBORESCENCE VALUES (@ID,@Nom,@IdParent)"
Dim cmd = New SQLiteCommand(strSQL, CON)
cmd.Parameters.AddWithValue("@IdParent", IdParent)
cmd.Parameters.AddWithValue("@Nom", Nom)
cmd.Parameters.AddWithValue("@ID", Nothing) 'pour que l'auto incrément s'active
cmd.ExecuteNonQuery()
cmd.Dispose()
Dim sql As String = "Select last_insert_rowid() FROM ARBORESCENCE"
cmd = New SQLiteCommand(sql, CON)
ID = Convert.ToInt32(cmd.ExecuteScalar()) 'on récupère l'id créé
cmd.Dispose()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Public Property Nom As String
Public Property ID As Integer
Public Property IdParent As Integer
End Class
''' <summary>
''' Classe qui associe une donnée de la BDD et son apparence en TreeNode
''' </summary>
Public Class NoeudJulia
Inherits TreeNode
''' <summary>
''' Construction d'une instance de NoeudJulia, à partir d'une ligne de la BDD
''' </summary>
''' <param name="DR"></param>
''' <param name="LesNoeuds"></param>
Public Sub New(ByVal DR As DataRow, ByVal LesNoeuds As List(Of NoeudJulia))
MyBase.New()
Valeur = New m_ARBORESCENCE(DR)
Text = Valeur.Nom
If Valeur.IdParent = 0 Then
LesNoeuds.Clear()
Else
Dim pere As NoeudJulia = LesNoeuds.SingleOrDefault(Function(nj) nj.Valeur.ID = Valeur.IdParent)
If pere Is Nothing Then Throw New Exception("Parent introuvable")
pere.Nodes.Add(Me)
End If
LesNoeuds.Add(Me)
End Sub
''' <summary>
''' Création d'un NoeudJulia à partir des données saisies
''' </summary>
''' <param name="Nom"></param>
''' <param name="Parent"></param>
''' <param name="LesNoeuds"></param>
Public Sub New(ByVal Nom As String, ByVal Parent As NoeudJulia, ByVal LesNoeuds As List(Of NoeudJulia), ByVal CON As SQLiteConnection)
MyBase.New(Nom)
Valeur = New m_ARBORESCENCE(Nom, Parent.Valeur.ID, CON)
Parent.Nodes.Add(Me)
LesNoeuds.Add(Me)
End Sub
Public Property Valeur As m_ARBORESCENCE
End Class
Et voilà un formulaire avec un treeview, un datagridview et un bouton
Imports System
Imports System.Collections.Generic
Imports System.Data
Imports System.Linq
Imports System.Windows.Forms
Imports System.Data.SQLite
Public Partial Class frmJulia
Inherits Form
Private Database As String
Private CON As SQLiteConnection = New SQLiteConnection()
Private Sub OpenDataBase()
Try
Database = String.Format("{0}\BDD.db", Application.StartupPath)
CON.ConnectionString = "Data Source=" & Database
CON.Open()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Public Sub New()
InitializeComponent()
End Sub
'liste qui va accueuillir les noeuds
Private lesNoeuds As List(Of NoeudJulia) = New List(Of NoeudJulia)()
Private Sub ChargeBdd()
Dim conn As SQLiteConnection = New SQLiteConnection("Data Source=BDD.db;Version=3")
Try
Using (conn)
conn.Open()
Dim sql As String = "Select * FROM ARBORESCENCE ORDER BY IdParent" 'il est impératif pour la suite que le datareader soit trié de la sorte
Dim cmdDataGrid As SQLiteCommand = New SQLiteCommand(sql, conn)
Dim da As SQLiteDataAdapter = New SQLiteDataAdapter()
da.SelectCommand = cmdDataGrid
Dim dta As DataTable = New DataTable()
da.Fill(dta)
'lecture des données et création de la liste de NoeudJulia
For Each dr As DataRow In dta.Rows
New NoeudJulia(dr, lesNoeuds)
Next
End Using
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
''' <summary>
''' Affiche les données, ordonnées par leur ID
''' </summary>
Private Sub AfficheDatas()
treeView1.Nodes.Clear()
treeView1.Nodes.Add(lesNoeuds(0))
Dim lesValeur = lesNoeuds.[Select](Function(nj) nj.Valeur).OrderBy(Function(v) v.ID)
dataGridView1.DataSource = Nothing
dataGridView1.DataSource = lesValeur.ToList()
End Sub
Private Sub frmJulia_Load(ByVal sender As Object, ByVal e As EventArgs)
OpenDataBase()
ChargeBdd()
AfficheDatas()
End Sub
''' <summary>
''' Ajoute une valeur au noeud sélectionné, le nom est la date et l'heure
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
Private Sub butAjouter_Click(ByVal sender As Object, ByVal e As EventArgs)
Dim parent As NoeudJulia = CType(treeView1.SelectedNode, NoeudJulia)
Dim nouveau As NoeudJulia = New NoeudJulia(DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"), parent, lesNoeuds, CON)
AfficheDatas()
End Sub
End Class
L'exception System.NullReferenceException n'a pas été gérée
HResult=-2147467261
Message=La référence d'objet n'est pas définie à une instance d'un objet.
Ok,
en fait, je ne code pas en vb.net, mais en C# et je passe par un convertisseur.
Dans 99.9% des cas ça marche bien et donc avec le temps j'ai perdu l'habitude de tester le code converti.
On est tombé dans le cas où il y a une subtilité que le convertisseur n'a pas géré.
Remplace la boucle par celle-ci
For Each dr As DataRow In dta.Rows
Dim nouveau As New NoeudJulia(dr, lesNoeuds)
Next
Public Sub New(ByVal Nom As String, ByVal Parent As NoeudJulia, ByVal LesNoeuds As List(Of NoeudJulia), ByVal CON As SQLiteConnection)
MyBase.New(Nom)
Valeur = New m_ARBORESCENCE(Nom, Parent.Valeur.ID, CON)
Parent.Nodes.Add(Me)
LesNoeuds.Add(Me)
End Sub
l'erreur c'est : L'exception System.NullReferenceException n'a pas été gérée
HResult=-2147467261
Message=La référence d'objet n'est pas définie à une instance d'un objet.
Quand j'ai fait le test en fait, le lien avec les évènements load du formulaire et click du bouton ne se sont pas fait.
Il m'a fallu double cliquer sur le bouton et le formulaire en mode desgin et copier coller les codes dans les 2 nouvelles méthodes crées.
Ça vient peut-être de là.
J'avoue que je n'ai pas trop bien compris
j'ai fait ça
Private Sub frmJulia_Load_1(sender As Object, e As EventArgs) Handles MyBase.Load
Dim parent As NoeudJulia = CType(TreeView1.SelectedNode, NoeudJulia)
Dim nouveau As NoeudJulia = New NoeudJulia(DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"), parent, lesNoeuds, CON)
AfficheDatas()
End Sub
toujours même erreur
peux tu m'envoyer l'ensemble de la solution de ton exemple ?
Pour Julia
il faut reprendre pour le code de ta Form principale le code que t'as donné Whismeril au message 20
il te manque juste les
Handles
qui vont raccrocher les Sub aux évènements FormJulia_Load et butAjouter_Click
voici le code complet de la Form avec les 2 Handles manquants
Imports System
Imports System.Collections.Generic
Imports System.Data
Imports System.Linq
Imports System.Windows.Forms
Imports System.Data.SQLite
Public Partial Class frmJulia
Inherits Form
Private Database As String
Private CON As SQLiteConnection = New SQLiteConnection()
Private Sub OpenDataBase()
Try
Database = String.Format("{0}\BDD.db", Application.StartupPath)
CON.ConnectionString = "Data Source=" & Database
CON.Open()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Public Sub New()
InitializeComponent()
End Sub
'liste qui va accueuillir les noeuds
Private lesNoeuds As List(Of NoeudJulia) = New List(Of NoeudJulia)()
Private Sub ChargeBdd()
Dim conn As SQLiteConnection = New SQLiteConnection("Data Source=BDD.db;Version=3")
Try
Using (conn)
conn.Open()
Dim sql As String = "Select * FROM ARBORESCENCE ORDER BY IdParent" 'il est impératif pour la suite que le datareader soit trié de la sorte
Dim cmdDataGrid As SQLiteCommand = New SQLiteCommand(sql, conn)
Dim da As SQLiteDataAdapter = New SQLiteDataAdapter()
da.SelectCommand = cmdDataGrid
Dim dta As DataTable = New DataTable()
da.Fill(dta)
'lecture des données et création de la liste de NoeudJulia
For Each dr As DataRow In dta.Rows
New NoeudJulia(dr, lesNoeuds)
Next
End Using
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
''' <summary>
''' Affiche les données, ordonnées par leur ID
''' </summary>
Private Sub AfficheDatas()
treeView1.Nodes.Clear()
treeView1.Nodes.Add(lesNoeuds(0))
Dim lesValeur = lesNoeuds.[Select](Function(nj) nj.Valeur).OrderBy(Function(v) v.ID)
dataGridView1.DataSource = Nothing
dataGridView1.DataSource = lesValeur.ToList()
End Sub
Private Sub frmJulia_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
OpenDataBase()
ChargeBdd()
AfficheDatas()
End Sub
''' <summary>
''' Ajoute une valeur au noeud sélectionné, le nom est la date et l'heure
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
Private Sub butAjouter_Click(ByVal sender As Object, ByVal e As EventArgs) Handles butAjouter.Click
Dim parent As NoeudJulia = CType(treeView1.SelectedNode, NoeudJulia)
Dim nouveau As NoeudJulia = New NoeudJulia(DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"), parent, lesNoeuds, CON)
AfficheDatas()
End Sub
End Class
Cela dit, tu n'as jamais répondu à la question de savoir quelle bibliothèque tu utilises dans le tien pour te connecter à SQlite.
J'ai supposé qu'il s'agit de celle-ci https://system.data.sqlite.org/index.html/doc/trunk/www/index.wiki si ça n'est pas le cas ça peut expliquer des écarts.
Cette bibliothèque s'installe comme package Nuggets avec ses dépendances (6 packages en tout) c'est trop gros pour cjoint, donc dans le zip il n'y pas pas tout le package mais juste le strict nécessaire (les dll)
Bonsoir, je viens de m'apercevoir d'une autre erreur du convertisseur.
Il a mis des By Val dans toutes les signatures de méthode.
Pour certaine, ça ne porte pas trop à conséquence (perte de temps d'exécution et utilisation inutile de la mémoire) mais pour d'autres, il y a perte d'informations.
Il faut donc supprimer tous les By Val du projet que je t'ai envoyé.