Enregistrer dans une base access

[Résolu]
Signaler
Messages postés
127
Date d'inscription
mardi 10 mai 2005
Statut
Membre
Dernière intervention
2 août 2021
-
Messages postés
16277
Date d'inscription
mardi 11 mars 2003
Statut
Non membre
Dernière intervention
16 septembre 2021
-
Bonjour,
Pour mettre à jour une base de données access, j'utilise le code ci-dessous lorsque la mise à jour concerne une seule ligne

Private Sub MiseAJourSortie()
        'Mise a jour sortie liquidée
        ' On Error Resume Next
        Sql = "SELECT ID, CodeOut, Liquidé FROM Sortie" _
            + " WHERE [CodeOut] Like '" & Trim(TCodOut.Text) & "'"
        Cmd = New OleDb.OleDbCommand(Sql)  
        SOuTA = New OleDb.OleDbDataAdapter(Cmd)
        Cmd.Connection() = GP 
        CDSet = New DataSet 
        SOuTA.Fill(CDSet, "Sortie")
        RowN = SOuT.Rows.Count - 1
        If RowN = SOuT.Rows.Count - 1 Then
            Dim Ligne0 As Integer = CDSet.Tables.Count - 1
            With CDSet
                DTR = CDSet.Tables("Sortie").Rows(Ligne0)
                DTR("Liquidé") = Trim$("OUI")
                CmdB = New OleDb.OleDbCommandBuilder(SOuTA)
                SOuTA.UpdateCommand = CmdB.GetUpdateCommand
                SOuTA.Update(CDSet, "Sortie") : CDSet.Clear()
            End With
        Else
            Exit Sub
        End If
    End Sub


Ma question est :
Comment formuler le code lorsque j'ai plus d'une ligne à mettre à jour en mème temps (Si le DataSet compte 3 lignes par exemple et que sur la colonne "Liquidé" je dois écrire le "OUI" sur les 3 lignes lorsque tous les trois ont en commun le "CodeOut").

merci d'avance

7 réponses

Messages postés
16277
Date d'inscription
mardi 11 mars 2003
Statut
Non membre
Dernière intervention
16 septembre 2021
562
un truc comme ça
    Private Sub MiseAJourSortie()
        'Mise a jour sortie liquidée
        ' On Error Resume Next
        sql = "SELECT ID, CodeOut, Liquidé FROM Sortie" _
            + " WHERE [CodeOut] Like '" & Trim(TCodOut.Text) & "'"
        cmd = New OleDb.OleDbCommand(sql)
        SOuTA = New OleDb.OleDbDataAdapter(cmd)
        cmd.Connection() = GP
        CDSet = New DataSet
        SOuTA.Fill(CDSet, "Sortie")
        For Each row As DataRow In CDSet.Tables("Sortie").Rows
            row("Liquidé") = "OUI"
        Next
        CmdB = New OleDb.OleDbCommandBuilder(SOuTA)
        SOuTA.UpdateCommand = CmdB.GetUpdateCommand
        SOuTA.Update(CDSet, "Sortie") : CDSet.Clear()
    End Sub


Quand j'étais petit, la mer Morte n'était que malade.
George Burns
Messages postés
127
Date d'inscription
mardi 10 mai 2005
Statut
Membre
Dernière intervention
2 août 2021

Bonjour Whismeril,

Ton vieux élève est de retour.
Voulant réutiliser ce bout de code je voudrais savoir comment le formuler dans le cas ou le donnée sa écrire sont différentes sur chaque ligne et non plus les mêmes.
par exemple sur chaque lignes de la grille les données sont différentes et je voudrais les écrire en même temps et non une a une.

La ligne 0 de grille = A
La ligne 1 de la grille = B
La ligne 2 de la grille = 3


 
        For Each row As DataRow In CDSet.Tables("Sortie").Rows
            row("Liquidé") = "OUI"
        Next


Après maintes recherche j'ai ce code sur le net mais iil ne marche pas
Merci d'avance

   Dim output As String = String.Empty
        For Each row As DataGridViewRow In DataGridView1.Rows
            For Each cell As DataGridViewCell In row.Cells
                output += cell.Value & ":"
            Next
            output += vbCrLf
        Next
        MsgBox(output)
Messages postés
16277
Date d'inscription
mardi 11 mars 2003
Statut
Non membre
Dernière intervention
16 septembre 2021
562 >
Messages postés
127
Date d'inscription
mardi 10 mai 2005
Statut
Membre
Dernière intervention
2 août 2021

Bonjour
Je ne comprends pas ton besoin
Messages postés
127
Date d'inscription
mardi 10 mai 2005
Statut
Membre
Dernière intervention
2 août 2021
>
Messages postés
16277
Date d'inscription
mardi 11 mars 2003
Statut
Non membre
Dernière intervention
16 septembre 2021

Bonsoir Whismeril
Pour être simple , je voudrais enregistrer dans une base access une somme de données chargées dans un datagridview
La dernière fois pour enregistrer la même donnée sur plusieurs ligne vous m'aviez envoyer un bout de code qui a été très instructif. Encore merci pour cela.

 
        For Each row As DataRow In CDSet.Tables("Sortie").Rows
            row("Liquidé") = "OUI"
        Next


Cette fois je voudrais enregistrer des modification de plusieurs colonnes sur deux ou trois lignes en même temps.


Mon souhait est d'enregistrer ces 3 lignes du datagridview en même temps si cela est possible par code. voila le datagridview, par exemple, (c'est une capture d'écran).
Si je dois enregistrer toutes les données de chaque cellule dans une table composée de ces 5 colonnes plus celle de la clef primaire, je fais comment svp?

Merci encore pour la disponibilité
Messages postés
16277
Date d'inscription
mardi 11 mars 2003
Statut
Non membre
Dernière intervention
16 septembre 2021
562 >
Messages postés
127
Date d'inscription
mardi 10 mai 2005
Statut
Membre
Dernière intervention
2 août 2021

Ton datagridview est il bindé sur une collection d’une classe métier?
Messages postés
127
Date d'inscription
mardi 10 mai 2005
Statut
Membre
Dernière intervention
2 août 2021
>
Messages postés
16277
Date d'inscription
mardi 11 mars 2003
Statut
Non membre
Dernière intervention
16 septembre 2021

    Private Sub ChargerStockGros()
        'Chargement des données du stock de gros
        Dim Dispo As String = "0"
        Try
            Connection()
            Sql = "SELECT ID, Article, Stock, [USell] AS [Prix(U)], Qté, Montant" _
                   + " FROM StockGros WHERE [Stock] Not Like '" & Dispo.Trim$ & "'"
            Cmd = New OleDb.OleDbCommand(Sql) 
            SkgrTA = New OleDb.OleDbDataAdapter(Cmd)
            Cmd.Connection() = GP 
            CDSet = New DataSet :
           SkgrTA.Fill(CDSet, "StockGros")
            SkgrT = CDSet.Tables("StockGros") 
            GridG.DataSource = CDSet
            GridG.DataMember = "StockGros" :
           GridGStyles()
        Catch ex As Exception
        Finally
            GP.Close()
        End Try
    End Sub
    


Bonjour Whismeril

Non.
Je charge la grille par le code ci-dessus.
Il arrive de modifier des cellules ou d'ajouter certaines données directement dans la grille.
J'applique un filtres qui tries la grille et affiche uniquement les lignes ou il y a eu modification
Ce qui donne la grille ci-après par exemple



Mon souhait c'est d'enregistrer les données de cette grille dans une autre table. Mais comment écrire le code
pour que chaque ligne soit enregistrée. Si c'était une ligne ce serait facile, mais comment enregistrer par
exemple ces 3 lignes directement en une seule fois.

merci d'avance
Messages postés
16277
Date d'inscription
mardi 11 mars 2003
Statut
Non membre
Dernière intervention
16 septembre 2021
562
Bonjour

je n'ai pas pris le temps de réfléchir à ton problème.

Mais je m'interroge sur ces 2 lignes
        RowN = SOuT.Rows.Count - 1
        If RowN = SOuT.Rows.Count - 1 Then ' RowN vaut forcément SOuT.Rows.Count - 1 puisque c'est la valeur que tu viens de lui mettre.

Il me semble que ces 2 lignes ne servent à rien
Messages postés
16277
Date d'inscription
mardi 11 mars 2003
Statut
Non membre
Dernière intervention
16 septembre 2021
562
De rien
Messages postés
127
Date d'inscription
mardi 10 mai 2005
Statut
Membre
Dernière intervention
2 août 2021

Bonsoir Whismeril
Satisfaction totale, ça marche super bien. Merci
Messages postés
16277
Date d'inscription
mardi 11 mars 2003
Statut
Non membre
Dernière intervention
16 septembre 2021
562
Je n’ai pas accès à un pc pour quelques jours.
Je me contente de répondre à des questions simples pour moi, ce n’est pas de le cas de la tienne.

Je reviendrai vers toi mi août si personne ne l’a fait d’ici là
Messages postés
16277
Date d'inscription
mardi 11 mars 2003
Statut
Non membre
Dernière intervention
16 septembre 2021
562
Bonjour

tout d'abord je n'ai pas access, donc certains détails de l'enregistrement peuvent m'échapper.

Je pense que la solution la plus simple à mettre en oeuvre c'est d'écrire une classe métier et de binder ton datagridview sur une collection de cette classe issue de la base de donnée.
Les avantages sont
  • sauvegarde de la clé primaire sans l'afficher
  • connaissances des lignes modifiées sans l'afficher
  • calculs faciles (sans s'embeter avec des row et des columns et surtout directement avec des nombres)


Un inconvénient sera probablement de devoir remanier une bonne partie de ton programme.
Je vais te faire un exemple qui colle à ta capture d'écran à partir d'un fichier csv (puisque je n'ai pas excel).

En attendant je t'invite à lire ce tuto https://codes-sources.commentcamarche.net/faq/1291-utilisation-du-binding-au-travers-de-l-objet-databindingsource
Messages postés
16277
Date d'inscription
mardi 11 mars 2003
Statut
Non membre
Dernière intervention
16 septembre 2021
562
Donc je te propose de créer un projet neuf pour tester ce qui suit.
Dans le repertoire debug tu places ce fichier csv appelé Colby.csv

ID;Article;Stock;PU;Quantité
1;AA;119;2988;4
2;BT;208;9098;2
3;AZ;298;5866;8


Au projet tu ajoutes cette classe
Imports System

Imports System.Collections.Generic

Imports System.ComponentModel

Imports System.Runtime.CompilerServices



Public Class ProduitColby

    Implements INotifyPropertyChanged

    Private _ID As Integer



    Public Sub New(ByVal MonID As Integer, ByVal MonArticle As String, ByVal MonStock As Integer, ByVal MonPU As Double, ByVal MaQuantite As Integer)
        ID = MonID
        lArticle = MonArticle
        leStock = MonStock
        pu = MonPU
        laQuantite = MaQuantite

    End Sub


#Region "PropertyChanged"

    Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged


    ''' <summary>
    ''' Vérifie si la propriété doit être mise à jour.
    ''' Le fait si besoin et déclenche propertyChange
    ''' </summary>
    ''' <typeparamname="T"></typeparam>
    ''' <paramname="field">Champ privé de la propriété</param>
    ''' <paramname="value">Nouvelle valeur</param>
    ''' <paramname="property">Nom de la propriété, passée automatiquement, donc pas besoin de vérifier qu'elle existe.</param>
    ''' <returns></returns>
    ''' <remarks>Méthode implémentée par JD</remarks>
    Protected Function ChangeAndNotify(Of T)(ByRef field As T, ByVal value As T, <CallerMemberName> ByVal Optional [property] As String = Nothing) As Boolean
        ' Vérification de la validité des paramètres
        If Equals([property], Nothing) Then
            Throw New ArgumentNullException("property")
        End If

        ' Vérification de l'utilité de la modification/notification
        If EqualityComparer(Of T).Default.Equals(field, value) Then

            Return False

        End If

        ' Modification
        field = value

        ' Notification
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs([property]))
        Return True

    End Function

#End Region



#Region "Propriétés"

    Public Property ID As Integer

        Get

            Return _ID

        End Get

        Private Set(ByVal value As Integer)

            _ID = value

        End Set

    End Property


    Private lArticle As String

    ''' <summary>
    ''' Nom du produit
    ''' </summary>
    Public Property Article As String

        Get

            Return lArticle

        End Get

        Set(ByVal value As String)

            If ChangeAndNotify(lArticle, value) Then Ischanged = True

        End Set

    End Property


    Private leStock As Integer

    ''' <summary>
    ''' Stock du produit
    ''' </summary>
    Public Property Stock As Integer

        Get

            Return leStock

        End Get

        Set(ByVal value As Integer)

            If ChangeAndNotify(leStock, value) Then Ischanged = True

        End Set

    End Property


    Private pu As Double

    ''' <summary>
    ''' Prix du produit
    ''' </summary>
    Public Property PrixUnitaire As Double

        Get

            Return pu

        End Get

        Set(ByVal value As Double)

            If ChangeAndNotify(pu, value) Then Ischanged = True

        End Set

    End Property


    Private laQuantite As Integer

    ''' <summary>
    ''' Quantité commandée
    ''' </summary>
    Public Property Quantite As Integer

        Get

            Return laQuantite

        End Get

        Set(ByVal value As Integer)

            If ChangeAndNotify(laQuantite, value) Then
                RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Montant")) 'signale que le montant commandé à changé
                Ischanged = True
            End If
        End Set

    End Property


    ''' <summary>
    ''' Prix total commandé
    ''' </summary>
    Public ReadOnly Property Montant As Double

        Get

            Return pu * laQuantite

        End Get

    End Property


    Private _Ischanged As Boolean = False

    Public Property Ischanged As Boolean

        Get

            Return _Ischanged

        End Get

        Private Set(ByVal value As Boolean)

            _Ischanged = value

        End Set

    End Property



#End Region

End Class


Tu génères la solution, tu ajoutes un datagridview et tu l'associes à un bindingsource en suivant le tuto que je t'ai donné à lire.

Dans le formulaire tu ajoutes ces 2 méthodes
    Private Sub ChargeProduitsColbyCSV()

        lesProduits = (From l In File.ReadAllLines("Colby.csv").Skip(1)
                       Let datas = l.Split(";"c)
                       Select New ProduitColby(Integer.Parse(datas(0)), datas(1), Integer.Parse(datas(2)), Double.Parse(datas(3)), Integer.Parse(datas(4)))
                           ).ToList()

        ProduitColbyBindingSource.DataSource = lesProduits

    End Sub



    Private Sub EnregistreProduitColbyCSV()

        Dim aEcrire = From p In lesProduits Where p.Ischanged Select $"{p.ID};{p.Article};{p.Stock};{p.PrixUnitaire};{p.Quantite}"

        File.WriteAllLines("ColbyProduitsModifies.csv", aEcrire)

    End Sub


Tu appelle la méthode de chargement depuis le form load et l'autre depuis un bouton.

Ensuite tu essayes.
Si ça correspond à ce que tu cherches on verra pour l'adapter à Access.

PS en sortant mon projet de tests divers, je me suis aperçu que je t'ai déjà proposé ce type de solution. Alors oui c'est différent que bidouiller avec les cellules, mais c'est comme ça que devrait être écrit un programme VB.Net, avec des objets métiers, car .Net n'est pas simplement orienté objet comme l'était VB6 mais "tout" objet. En plus ça permet que chaque objet ne fasse que ce qui le concerne => un datagridview sert à afficher des données, pas à calculer un prix par exemple.