none
DAO 3.6 et VB.net VS2008 RRS feed

  • Question

  • Bonjour,

    Je developpe depuis plusieur années des app sur des bases de données access.

    Aujourd'hui je migre vers Vb.net et j'ai des soucis pour deploier ma petite app.

    J'utilise DAO 3.6 pratique pour moi, simple et rapide je trouve et surtout je maitrise.

    au moment de lancer l'app erreur :

    ************** Texte de l'exception **************
    System.IO.FileNotFoundException: La récupération de la fabrique de classe COM pour le composant avec le CLSID {00000100-0000-0010-8000-00AA006D2EA4} a échoué en raison de l'erreur suivante : 8007007e.
       à Ordonnancier.ModuleOrdonnance.CorrectionDBOrdo()

     J'ai besoin d'une aide car je ne trouve pas de solution a ca.

    Merci par avance

    vendredi 9 septembre 2011 21:36

Réponses

  • Bonjour,

    Ne nos jours, il faut oublier le principe "Curseur" ou "Fichier" (= mode COBOL). Il faut raisonner en SQL et en terme de table.

    Voici 2 bouts de code qui vous montre comment exécuter les requêtes de tout type pour exploiter une base de données Access :

            ' Code permettant d'exécuter une requête de type "NonQuery" (UPDATE, DELETE, INSERT, CREATE TABLE,...)
            Using connexion As OleDbConnection = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\MaBD.mdb;User Id=yyyyyyyy;Password=xxxxxxxx;")
                Using commande As OleDbCommand = New OleDbCommand("UPDATE Table SET Colonne = Valeur", connexion)
                    connexion.Open()
                    Dim nbLignesModifiées As Integer = commande.ExecuteNonQuery()
    
                    ' nbLignesModifiées contient le nombre de ligne modifiées
                End Using
            End Using
    
            ' Code permettant d'exécuter une requête de type "SELECT"
            Dim dt As DataTable = New DataTable()
    
            Using connexion As OleDbConnection = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\MaBD.mdb;User Id=yyyyyyyy;Password=xxxxxxxx;")
                Using commande As OleDbCommand = New OleDbCommand("SELECT * FROM MaTable WHERE MaColonne > 1664", connexion)
                    Using dataAdapter As OleDbDataAdapter = New OleDbDataAdapter(commande)
                        dataAdapter.Fill(dt)
                    End Using
                End Using
            End Using
    

    En espérant que cela puisse vous aider.

    Cordialement


    Gilles TOURREAU - MVP C#
    Architecte .NET/Consultant/Formateur chez Winwise
    Blog : http://gilles.tourreau.fr
    - MCPD : Enterprise Developper / Windows Developper 3.5 / ASP .NET 3.5
    - MCTS : ADO .NET 3.5 / SQL Server 2008 Developper / Windows Forms 3.5 / ASP .NET 3.5
    dimanche 11 septembre 2011 12:38
    Modérateur
  • Bonjour,

    Pour ajouter une ligne :

    Dim dr As DataRow = DataS.Tables(0).NewRow()
    dr("MaColonne") = "Ma valeur"
    DataS.Tables(0).Rows.Add(dr)
    

    Pour modifier une ligne (ici la ligne n°1 et donc à l'indice 0) :

    DataS.Tables(0).Rows(0)("MaColonne") = "Valeur"
    

    Cordialement


    Gilles TOURREAU - MVP C#
    Architecte .NET/Consultant/Formateur chez Winwise
    Blog : http://gilles.tourreau.fr
    - MCPD : Enterprise Developper / Windows Developper 3.5 / ASP .NET 3.5
    - MCITP : SQL Server 2008 Developper
    - MCTS : ADO .NET 3.5 / SQL Server 2008 Developper / Windows Forms 3.5 / ASP .NET 3.5
    mardi 13 septembre 2011 19:58
    Modérateur

Toutes les réponses

  • Bonjour,

    Je vous déconseille fortement d'utiliser DAO en VB. NET. En effet, c'est une technologie d'accès aux données qui est obsolète depuis presque 10 ans !

    La solution d'accès aux données dans le monde .NET est ADO .NET. Plus d'informations : http://msdn.microsoft.com/en-us/library/aa286484.aspx

    Cordialement


    Gilles TOURREAU - MVP C#
    Architecte .NET/Consultant/Formateur chez Winwise
    Blog : http://gilles.tourreau.fr
    - MCPD : Enterprise Developper / Windows Developper 3.5 / ASP .NET 3.5
    - MCTS : ADO .NET 3.5 / SQL Server 2008 Developper / Windows Forms 3.5 / ASP .NET 3.5
    samedi 10 septembre 2011 20:36
    Modérateur
  • Bonjour,

    Merci de votre reponse.

    Cela signifie au moin deux fois plus de code a saisir ?

    dimanche 11 septembre 2011 09:33
  • Bonjour,

    Non... Vous obtiendrais de meilleur performances (pas de notion de curseur) et si vous utilisez Entity Framework qui est intégré dans le .NET Framework 3.5 et 4.0, votre code sera beaucoup plus "objet" est beaucoup plus natuel à l'écriture.

    Cordialement


    Gilles TOURREAU - MVP C#
    Architecte .NET/Consultant/Formateur chez Winwise
    Blog : http://gilles.tourreau.fr
    - MCPD : Enterprise Developper / Windows Developper 3.5 / ASP .NET 3.5
    - MCTS : ADO .NET 3.5 / SQL Server 2008 Developper / Windows Forms 3.5 / ASP .NET 3.5
    dimanche 11 septembre 2011 09:37
    Modérateur
  • Par exemple : avec DAO 3.6

            DAOEngine = New dao.DBEngine
            DAODatabase = DAOEngine.OpenDatabase(OrdonnanceDB, False, False, ";UID=" & UtilisateurOrdonnanceDB & ";PWD=" & PasswordOrdonnanceDB)
            Dim NumRapport As Double = Val(Me.IDRapportDiag.Text)
            If NumRapport = 0 Then
            MyDAORecordset = DAODatabase.OpenRecordset("SELECT [IDRapport] FROM [Affections] ORDER BY [IDRapport]")
            If MyDAORecordset.EOF = 0 Then
             MyDAORecordset.MoveLast()
            NumRapport = MyDAORecordset("IDRapport").Value + 1
            End If
            MyDAORecordset.Close()
            End If
            '
            MyDAORecordset = DAODatabase.OpenRecordset("SELECT * FROM [Affections] WHERE [IDRapport]=" & NumRapport)
            If MyDAORecordset.EOF = 0 Then MyDAORecordset.Edit() Else MyDAORecordset.AddNew()
            MyDAORecordset("IDRapport").Value = NumRapport
            MyDAORecordset("NumPiece").Value = Val(Me.NumeroOrdo.Text)
            MyDAORecordset("Date").Value = Me.DateTimePicker1.Value.ToString
            MyDAORecordset("IDPatient").Value = Val(Me.Label2.Text)
            If Me.Affection.Text <> "" Then MyDAORecordset("Affection").Value = Me.Affection.Text Else MyDAORecordset("Affection").Value = ""
            '
            MyDAORecordset("Taille").Value = Val(Me.Taille.Text)
            MyDAORecordset("Poids").Value = Val(Me.Poids.Text)
            MyDAORecordset("Pouls").Value = Val(Me.Pouls.Text)
            MyDAORecordset("Tension artérielle").Value = Val(Me.Tension.Text)
            MyDAORecordset.Update()
            MyDAORecordset.Close()
            DAODatabase.Close()

    Maintenant avec ADO

            ADOOrdoConnexion = New ADODB.Connection
            MyADOOrdoRecordset = New ADODB.Recordset
            ADOOrdoConnexion.ConnectionString = ConnexionStringLectureOrdo
            'Ouverture de la base de données
            ADOOrdoConnexion.Open()
            If NumRapport = 0 Then
                ' si numero rapport =0 en creer un nouveau
                MyADOOrdoRecordset.Open("SELECT [IDRapport] FROM [Affections] ORDER BY [IDRapport]", ADOOrdoConnexion)
                If MyADOOrdoRecordset.EOF = 0 Then
                    MyADOOrdoRecordset.MoveLast()
                    NumRapport = MyADOOrdoRecordset("IDRapport").Value + 1
                End If
                MyADOOrdoRecordset.Close()
            End If
            '
            ' sauve le rapport
            'MySQl = ""
            MyADOOrdoRecordset.Open("SELECT * FROM [Affections] WHERE [IDRapport]=" & NumRapport, ADOOrdoConnexion)
            If MyADOOrdoRecordset.EOF = 0 Then
                ' si le rapport existe le modifier
                MySQl = "UPDATE [Affections] SET "
                MySQl = MySQl & "[IDRapport]=" & NumRapport & ","
                MySQl = MySQl & "[NumPiece]=" & Val(Me.NumeroOrdo.Text) & ","
                MySQl = MySQl & "[Date]='" & Format(Me.DateTimePicker1.Value, "dd/MM/yyyy").ToString & "',"
                MySQl = MySQl & "[IDPatient]=" & Val(Me.Label2.Text) & ","
                If Me.Affection.Text <> "" Then
                    MySQl = MySQl & "[Affection]='" & Me.Affection.Text & "',"
                Else
                    MySQl = MySQl & "[Affection]=Null,"
                End If
                MySQl = MySQl & "[Taille]=" & Val(Me.Taille.Text) & ","
                MySQl = MySQl & "[Poids]=" & Val(Me.Poids.Text) & ","
                MySQl = MySQl & "[Pouls]=" & Val(Me.Pouls.Text) & ","
                MySQl = MySQl & "[Tension artérielle]=" & Val(Me.Tension.Text)
                MySQl = MySQl & " WHERE [IDRapport]=" & NumRapport
            Else
                ' rapport inexistant le creer
                MySQl = "INSERT INTO [Affections]([IDRapport],[NumPiece],[Date],[IDPatient],"
                MySQl = MySQl & "[Affection],[Taille],[Poids],[Pouls],[Tension artérielle])"
                MySQl = MySQl & " VALUES("
                MySQl = MySQl & NumRapport & ","
                MySQl = MySQl & Val(Me.NumeroOrdo.Text) & ","
                MySQl = MySQl & "'" & Format(Me.DateTimePicker1.Value, "dd/MM/yyyy").ToString & "',"
                MySQl = MySQl & Val(Me.Label2.Text) & ","
                If Me.Affection.Text <> "" Then
                    MySQl = MySQl & "'" & Me.Affection.Text & "',"
                Else
                    MySQl = MySQl & "Null,"
                End If
                MySQl = MySQl & Val(Me.Taille.Text) & ","
                MySQl = MySQl & Val(Me.Poids.Text) & ","
                MySQl = MySQl & Val(Me.Pouls.Text) & ","
                MySQl = MySQl & Val(Me.Tension.Text)
                MySQl = MySQl & ");"
            End If
            MyADOOrdoRecordset.Close()
            ADOOrdoConnexion.Execute(MySQl)
            ADOOrdoConnexion.Close()
            ADOOrdoConnexion = Nothing
            MyADOOrdoRecordset = Nothing
    

    Le dois trouver un paliatif.

    Je n'utilise pas de connexion a un serveur, juste du local ou un dossier partagé avec la Bd.

    Dans mon exemple ma procedure creer le rapport NumX si il n'existe pas dans la db et modifi l'existant si il existe.

    Y a t il plus simple ?
     

    dimanche 11 septembre 2011 11:05
  • Bonjour,

    Vous utilisez ADO (qui est aussi obsolète). Vous devez utiliser ADO .NET comme ceci :

    Que voulez-vous faire exactement ?

    Cordialement


    Gilles TOURREAU - MVP C#
    Architecte .NET/Consultant/Formateur chez Winwise
    Blog : http://gilles.tourreau.fr
    - MCPD : Enterprise Developper / Windows Developper 3.5 / ASP .NET 3.5
    - MCTS : ADO .NET 3.5 / SQL Server 2008 Developper / Windows Forms 3.5 / ASP .NET 3.5
    dimanche 11 septembre 2011 11:13
    Modérateur
  • Il s'agit d'une app executable (fichier exe) en Visual Basic VS2008, pas site web

    Dans une base de donnée MSAccess 97 (cela je ne peut pas le changer), ajouter, modifier des enregistrements, avec la possibilité de creer de nouvelles tables avec de nouveau champs dynamiquement dont certains doivent pouvoir acceuillir le allowLengthZero en proprieté ( cela aussi est une obligation).

    Parfois changer les propriete de certains champs en fonctions d'obligations diverses.

    Voila en regle générale.

     


    • Modifié Dave Path dimanche 11 septembre 2011 11:34
    dimanche 11 septembre 2011 11:20
  • Bonjour,

    Ne nos jours, il faut oublier le principe "Curseur" ou "Fichier" (= mode COBOL). Il faut raisonner en SQL et en terme de table.

    Voici 2 bouts de code qui vous montre comment exécuter les requêtes de tout type pour exploiter une base de données Access :

            ' Code permettant d'exécuter une requête de type "NonQuery" (UPDATE, DELETE, INSERT, CREATE TABLE,...)
            Using connexion As OleDbConnection = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\MaBD.mdb;User Id=yyyyyyyy;Password=xxxxxxxx;")
                Using commande As OleDbCommand = New OleDbCommand("UPDATE Table SET Colonne = Valeur", connexion)
                    connexion.Open()
                    Dim nbLignesModifiées As Integer = commande.ExecuteNonQuery()
    
                    ' nbLignesModifiées contient le nombre de ligne modifiées
                End Using
            End Using
    
            ' Code permettant d'exécuter une requête de type "SELECT"
            Dim dt As DataTable = New DataTable()
    
            Using connexion As OleDbConnection = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\MaBD.mdb;User Id=yyyyyyyy;Password=xxxxxxxx;")
                Using commande As OleDbCommand = New OleDbCommand("SELECT * FROM MaTable WHERE MaColonne > 1664", connexion)
                    Using dataAdapter As OleDbDataAdapter = New OleDbDataAdapter(commande)
                        dataAdapter.Fill(dt)
                    End Using
                End Using
            End Using
    

    En espérant que cela puisse vous aider.

    Cordialement


    Gilles TOURREAU - MVP C#
    Architecte .NET/Consultant/Formateur chez Winwise
    Blog : http://gilles.tourreau.fr
    - MCPD : Enterprise Developper / Windows Developper 3.5 / ASP .NET 3.5
    - MCTS : ADO .NET 3.5 / SQL Server 2008 Developper / Windows Forms 3.5 / ASP .NET 3.5
    dimanche 11 septembre 2011 12:38
    Modérateur
  • Merci pour votre aide, j'ai repris pesque tout mon code de lecture, mais par endroit cela augmente la quantité de codes.

    Mais j'ai un soucis dans ce cas :

    Je voudrais savoir ce que je devrais utiliser dans ce cas:

    J'ai besoin de controler l'existance d'un enregistrement dans une table avec une requete sql de ce genre :

    "SELECT * FROM [Corps Ordonance] WHERE [NumPiece]=" & Val(Me.RefOrdonnance.Text) & " AND [Ligne]=" & Val(Me.RefLigneOrdonnance.Text)

    Dans le cas ou  l'enregistrement est inexistant creer un nouvel enregistrement (ADDNEW) si il est existant je le met a jour (UPDATE)

    A votre avis ?

     


    • Modifié Dave Path lundi 12 septembre 2011 19:00
    lundi 12 septembre 2011 18:59
  • Bonjour,

    Vous devez créer et exécuter des requêtes INSERT et UPDATE en fonction de vos besoins.

    Je ne suis pas spécialiste d'Access, mais sachez que sous SQL Server, vous pouvez utiliser l'opérateur MERGE qui permet en une seule requête de réaliser des opérations INSERT/UPDATE en fonction de deux SELECT.

    Cordialement


    Gilles TOURREAU - MVP C#
    Architecte .NET/Consultant/Formateur chez Winwise
    Blog : http://gilles.tourreau.fr
    - MCPD : Enterprise Developper / Windows Developper 3.5 / ASP .NET 3.5
    - MCITP : SQL Server 2008 Developper
    - MCTS : ADO .NET 3.5 / SQL Server 2008 Developper / Windows Forms 3.5 / ASP .NET 3.5
    lundi 12 septembre 2011 19:50
    Modérateur
  • Bonjour,

    Ma base de donnée n'est pas sous SQLserver. je pensais pouvoir realiser avec un dataset une chose equivalente a cela :

    DAOEngine = New dao.DBEngine
    DAODatabase = DAOEngine.OpenDatabase(OrdonnanceDB, False, False, ";UID=" & UtilisateurOrdonnanceDB & ";PWD=" & PasswordOrdonnanceDB)
    '
    MyDAORecordset = DAODatabase.OpenRecordset("SELECT * FROM [Corps Ordonance] WHERE [NumPiece]=" & Val(Me.RefOrdonnance.Text) & " AND [Ligne]=" & Val(Me.RefLigneOrdonnance.Text))
    If MyDAORecordset.EOF = 0 Then 
    	MyDAORecordset.Edit() 
    Else 
    	MyDAORecordset.AddNew()
    endif
    MyDAORecordset("NumPiece").Value = Val(Me.RefOrdonnance.Text)
    MyDAORecordset("Date").Value = Me.RefDateOrdonnance.Text
    MyDAORecordset("Ordonnance Num").Value = 0
    
    MyDAORecordset.Update()
    MyDAORecordset.Close()
    DAODatabase.close

    Mais je ne maitrise pas encore ca et j'ai des petit soucis, si vous aviez un exemple ou une traduction cela m'aiderait beaucoup.

    Merci
     

    mardi 13 septembre 2011 06:45
  • j'en suis arrivé la :

            Conn.Open()
            Dim oledbAdapter As OleDbDataAdapter = New OleDbDataAdapter("SELECT * FROM [Corps Ordonance] WHERE [NumPiece]=" & Val(Me.RefOrdonnance.Text) & " AND [Ligne]=" & Val(Me.RefLigneOrdonnance.Text), Conn)
            oledbAdapter.Fill(DataS)
            oledbAdapter.Dispose()
            Conn.Close()
            If DataS.Tables(0).Rows.Count = 0 Then
                ' inexistant
            Else
                ' existant
            End If
            DataS.Dispose()
    
    

    Apres pour remplir les champ de la table cela ce complique, ou mettre le addnew et le edit.

    mardi 13 septembre 2011 07:17
  • Bonjour,

    Pour ajouter une ligne :

    Dim dr As DataRow = DataS.Tables(0).NewRow()
    dr("MaColonne") = "Ma valeur"
    DataS.Tables(0).Rows.Add(dr)
    

    Pour modifier une ligne (ici la ligne n°1 et donc à l'indice 0) :

    DataS.Tables(0).Rows(0)("MaColonne") = "Valeur"
    

    Cordialement


    Gilles TOURREAU - MVP C#
    Architecte .NET/Consultant/Formateur chez Winwise
    Blog : http://gilles.tourreau.fr
    - MCPD : Enterprise Developper / Windows Developper 3.5 / ASP .NET 3.5
    - MCITP : SQL Server 2008 Developper
    - MCTS : ADO .NET 3.5 / SQL Server 2008 Developper / Windows Forms 3.5 / ASP .NET 3.5
    mardi 13 septembre 2011 19:58
    Modérateur