[VB] Connexion à une BDD Access [Résolu/Fermé]

Signaler
Messages postés
16
Date d'inscription
vendredi 19 mars 2010
Statut
Membre
Dernière intervention
12 avril 2010
-
Messages postés
16
Date d'inscription
vendredi 19 mars 2010
Statut
Membre
Dernière intervention
12 avril 2010
-
Bonjour à tous,


Je dispose d'un tableau Excel que je veux pouvoir copier en une BDD Access lorsque je clic sur un bouton présent sur la feuille .xls contenant ledit tableau.

Pour l'instant je suis en train de tester la connexion ainsi que la création de la table. Mon Code ressemble à ceci:


Sub cnxBDD()

chaine = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\Nant\Desktop\MABDD.mdb;Persist Security Info=False"

Set BDD = New ADODB.Connection
Set recSet = New ADODB.Recordset
BDD.Open cSQL
Me.Refresh


Dim BDD As ADODB.Connection
Dim recSet As ADODB.Recordset
Dim cSQL As String

BDD.Execute "CREATE TABLE Test (Nom varchar(60),Prenom varchar(60),Mail varchar(60),Surnom varchar(60),DateAjout date not null)"


End Sub

L'erreur qui se produit est celle-ci :
"ADO : erreur de compilation : type défini par l'utilisateur non défini" et concerne " New ADODB.Connection"

J'ai pu trouver sur ce site ce qui en serait la source https://support.microsoft.com/fr-fr/help/184609/prb-ado-compile-error-user-defined-type-not-defined . Mais je ne suis pas sûr de comprendre. (Je débute en VB et suis encore très mauvais..)

Quelqu'un pourrait-il m'orienter?

Merci.
Nant

11 réponses

Messages postés
6917
Date d'inscription
mardi 25 septembre 2007
Statut
Membre
Dernière intervention
1 novembre 2016
1 128
Bonjour,

Il faut ajouter la référence Microsoft ActiveX Data Objects x.x Library au projet.

Dans le menu de l'éditeur VB => Outils => Références ... cocher la case correspondate.

Ensuite il faut déclarer les objets avant de les créer ...

Dim BDD As ADODB.Connection 
Dim recSet As ADODB.Recordset 
Dim cSQL As String 

Set BDD = New ADODB.Connection 
Set recSet = New ADODB.Recordset

'La chaine connection
chaine = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\Nant\Desktop\MABDD.mdb;Persist Security Info=False"

'On créé la connexion
BDD.Open chaine

'On écrit la requête
cSQL = "CREATE TABLE Test (Nom varchar(60),Prenom varchar(60),Mail varchar(60),Surnom varchar(60),DateAjout date not null)" 

'On passe la requete à la base
recSet.Open cSQL, BDD, , , adCmdText

'On ferme la connexion et on libère les objets
BDD.Close
recSet.Close

Set BDD = Nothing
Set recSet = Nothing



Ca devrait marcher comme ça

;o)
1
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 61245 internautes nous ont dit merci ce mois-ci

Messages postés
6917
Date d'inscription
mardi 25 septembre 2007
Statut
Membre
Dernière intervention
1 novembre 2016
1 128
Bonjour,

C'est étrange, le code fonctionne chez moi sans message d'erreur. J'utilise Access 2003

Ensuite juste une petite remarque sans importance:

Set BDD = New ADODB.Connection 'initialisation des variables [SET]

Ici tu n'initialises pas une variable, tu crées un objet, plus exactement une instance "Connection" de la classe ADODB. Idem pour recSet.

Effectivement, si tu expliques que "tu caches une erreur en utilisant On Error Resume Next", ça risque de faire sourire. Le fait d'intercepter une erreur et la gérer n'a rien de honteux, bien au contraire. Libre à toi d'utiliser le vocabulaire que bon te semble. La gestion des erreurs est chose commune en programmation.

;o)
1
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 61245 internautes nous ont dit merci ce mois-ci

Messages postés
16
Date d'inscription
vendredi 19 mars 2010
Statut
Membre
Dernière intervention
12 avril 2010
1
Pour ceux que ça intéressent, ce code permet, à partir d'un bouton sur une feuille Excel de copier son tableau en une table Access:


Sub insert() 

            
    'Ici l'importation se déclenche en cliquant sur le bouton "Insert" 
    Dim oApp As Excel.Application 
    Dim oWkb As Excel.Workbook 
    Dim oWSht As Excel.Worksheet 
      
    Set oApp = CreateObject("excel.application") 
    Set oWkb = oApp.Workbooks.Open("C:\Users\Nant\Desktop\JeuDeTest2.xls") 'chemin vers le fichier Excel 
    Set oWSht = oWkb.Worksheets("Feuill1") 'nom de la feuille qui contient les données à importer 
      
    'première ligne ou commence l'import, on ne prend pas la 1ère vu qu'il s'agit des noms de champ (valable pour mon cas, pas forcément pour tous) 
    i = 2 
      
    'pour éviter les messages lors de l'ajout des enregistrements 
    DoCmd.SetWarnings False 
     
     
    'requête de création de table et... 
    cSQLCreateTable = "CREATE TABLE CarnetTest(Champ1  varchar(60),Champ2 varchar(60),Champ3 varchar(60),Champ4 varchar(60),Champ5 date);" 
    '...son exécution 
     DoCmd.RunSQL cSQLCreateTable 
     
    'on arrête l'importation quand le programme rencontre une case vide dans le champs "Champ3" / colonne C indice "i"(champs toujours rempli avec Champ5 qui est une date, celui ci choisi car plus judicieux) 
    While oWSht.Range("C" & i).Value <> "" 
      
        'requète SQL (avec en paramètre la ligne i et le numéro de la colonne comme précisé au-dessus) 
         cSQL = "insert into [Feuill1] ( [Champ1], [Champ2], [Champ3], [Champ4], [Champ5] ) values (" & Chr(34) & oWSht.Cells(i, 1) & Chr(34) & ", " & Chr(34) & oWSht.Cells(i, 2) & Chr(34) & ", " & Chr(34) & oWSht.Cells(i, 3) & Chr(34) & ", " & Chr(34) & oWSht.Cells(i, 4) & Chr(34) & ", " & Chr(34) & oWSht.Cells(i, 5) & Chr(34) & ")" 
        'ici, on ne prend que les colonnes A (=1) et B (=2) etc. 
        'exécution de la requète 
        DoCmd.RunSQL cSQL 
         
        'on incrémente la variable i pour passer à la ligne suivante 
        i = i + 1 
      
    Wend 
         
    'on averti l'utilisateur que la Table est créée. 
    MsgBox "Table Access créée sur la Base de données MABDD.mdb . Pensez à l'archiver dans un Dossier." 
     
     
End Sub 
1
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 61245 internautes nous ont dit merci ce mois-ci

Messages postés
6917
Date d'inscription
mardi 25 septembre 2007
Statut
Membre
Dernière intervention
1 novembre 2016
1 128
Bonjour,

Tu mets juste après la déclaration des variables dans ta procédure:

ThisWorkbook.Save


Il faut enregistrer le classeur et non la feuille.
Si tu veux lui donner un autre nom lors de la sauvegarde :

ThisWorkbook.SaveAs("C:\monDossier\nouveauNom.xls")



;o)
1
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 61245 internautes nous ont dit merci ce mois-ci

Messages postés
16
Date d'inscription
vendredi 19 mars 2010
Statut
Membre
Dernière intervention
12 avril 2010
1
Super merci beaucoup, et merci pour les commentaires expliquant le rôle de chaque objet/fonction utilisés :)

J'ai une erreur bizarre "Erreur d'exécution 3704: Cette opération n'est pas autorisée si l'objet est fermé". Pourtant la table se créer bien.

Je vais chercher d'où ça vient ça doit pas être bien grave vu que la connexion se fait et que la requête est executée.

Merci bien pour ton aide Polux31!
Messages postés
16
Date d'inscription
vendredi 19 mars 2010
Statut
Membre
Dernière intervention
12 avril 2010
1
Pour l'erreur 3704,

elle survient pour cette raison :
"Le fournisseur de SQL Server OLEDB (SQLOLEDB) a un nouveau comportement conçu pour fournir des informations plus précises à l'appelant sur Qu'est-il advenu de la procédure. Chaque instruction SQL dans une procédure stockée renvoie un « résultat », soit un nombre de lignes concernées, ou un jeu de résultats.

Le fournisseur ODBC SQL Server (MSDASQL) ne fournit pas informations sur les résultats des instructions SQL individuelles au sein d'une procédure stockée. Le seul résultat qui proviennent de retour d'une exécution d'une procédure stockée est le résultat de l'instruction SELECT si elle possède un. C'est pourquoi le problème ne se manifeste pas avec MSDASQL."
Source :https://support.microsoft.com/fr-fr/help/235340

L'astuce qu'il donne, je n'ai pas réussi à la reproduire, le SET me fait une autre erreur indiquant qu'il attend une suite d'instruction.



Sinon il y a une parade, mais pas très propre :/ qui consiste à empêcher l'affichage de cette erreur :



# 'lorsqu'une erreur 3704 du controle adodc se produit y a un message qu'on ne peut eviter (un bouton ok). il faut mettre ce code dans l'evenement error du adodc pour éviter qu'il s'affiche.
#
# If ErrorNumber = 3704 Then
# fCancelDisplay = True
# End If

#
# 'vous aurez donc :
#
# Private Sub Data1_Error(ByVal ErrorNumber As Long, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, fCancelDisplay As Boolean)
# If ErrorNumber = 3704 Then
# fCancelDisplay = True
# End If
# End Sub

#
# 'pensez à un mettre un "on error resume next" juste avant l'instruction qui provoque l'erreur 3704

Source: https://codes-sources.commentcamarche.net/


De mon côté ça marche. Mais je vais quand même faire qqes tests avec la première solution, j'aime pas trop "cacher" le message d'erreur quand on peut l'empêcher.

Encore merci Polux31 (Toulouse for the win)
Messages postés
6917
Date d'inscription
mardi 25 septembre 2007
Statut
Membre
Dernière intervention
1 novembre 2016
1 128
Bonjour,

Je n'avais pas vu tes réponses (CCM beug pendant la mise en place de la nouvelle interface).

Le "On Error Resume Next" ne "cache" pas une erreur. Il permet d'intercepter l'exception et de la gérer, comme le Try ... Catch en JAVA, VET.NET etc ...
Dans le code que je t'ai donné, il faudrait rajouter en début de code le "On Error Resume Next" et en fin de code un truc du genre :
If Err.Number <> 0 Then
     MsgBox "Connexion à la base impossible",VbExclamation,"ERREUR BDD"
     Exit Sub
End If

Ca permet de ne pas "planter" l'appli et l'utilisateur devant un message incompréhensible pour lui.

C'est très utile dans bien des cas et justement pour celui là. En effet un recordset est sensé retourner des informations. Dans le cas d'une instruction SQL de création de table, aucune donnée n'est retourné et provoque une exception. Tous les cas d'erreurs ne sont pas forcément gérer convenablement par les systèmes. Il faut donc contourner le problème pour pouvoir faire fonctionner convenablement l'application.

Bonne continuation et bon courage.

;o)
Messages postés
16
Date d'inscription
vendredi 19 mars 2010
Statut
Membre
Dernière intervention
12 avril 2010
1
Hello!
Désolé je ne suis pas passé sur le site du WE et je n'avais pas vu ta réponse non plus.

Bien étrangement, avec ta dernière solution je n'arrive pas à faire fonctionner l'appli. Il n'y a plus de message d'erreur, mais la table ne se créer pas. Tandis qu'avec celle que j'avais linké ça marche. Mais bon je vais avoir l'air malin quand j'expliquerai le sourire aux lèvres que je ne fais que cacher l'apparition d'un message d'erreur...

Mon code donne ça pour l'instant:

Sub cnxBDD()  
    'Il faut ajouter la référence Microsoft ActiveX Data Objects x.x Library au projet pour que la connexion marche  
    'Dans le menu de l'éditeur VB => Outils => Références ... cocher la case qui correspond. ici 9.0  

    Dim BDD As ADODB.Connection 'déclaration variable Base De Données pour la connex  
    Dim recSet As ADODB.Recordset 'declaration du recordset => variable contenant le résultat d'une requète sous forme de tableau  
    Dim cSQL As String 'variable contenant la requete SQL  

    Set BDD = New ADODB.Connection 'initialisation des variables [SET]  
    Set recSet = New ADODB.Recordset  
    On Error Resume Next 'voir note plus bas pour les explications  
      
    'La chaine connection  
    chaine = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\Nant\Desktop\MABDD.mdb;Persist Security Info=False"  

    'On créé la connexion  
    BDD.Open chaine  
      
      
    'la requête  
    cSQL = "CREATE TABLE Test (Champ1  varchar(60),Champ2 varchar(60),Champ3 varchar(60),Champ4 varchar(60),Champ5 date not null)"  
      
    'On passe la requete à la base  
    recSet.Open cSQL, BDD, , , adCmdText  
      

    '///////////////////////////////////////////  
    '///// CODE POUR INSERTION DANS LA BDD /////  
    '///////////////////////////////////////////  
      
    'A FINIR FINIR  
      
    '///////////////////////////////////////////  
    '////////////////FIN DU ////////////////////  
    '///// CODE POUR INSERTION DANS LA BDD /////  
    '///////////////////////////////////////////  
      
      
      

    'On ferme la connexion et on libère les objets  
    BDD.Close  
    recSet.Close  
      
    Set BDD = Nothing  
    Set recSet = Nothing  
      
      
      
    'If Err.Number <> 0 Then  
     'MsgBox "Connexion à la base impossible", vbExclamation, "ERREUR BDD"  
     'Exit Sub  
    'End If  

End Sub  

'Une erreur 3704 peut se produire car "Le fournisseur ODBC SQL Server (MSDASQL) ne fournit pas informations  
'sur les résultats des instructions SQL individuelles au sein d'une procédure stockée. Le seul résultat qui  
'proviennent de retour d'une exécution d'une procédure stockée est le résultat de l'instruction SELECT si  
'elle possède un."  

'on peut "cacher" l erreur, ça fait crade mais je n'ai trouvé que ça :  
'pour cette raison qu'il y a la présence en haut du ON ERROR ...  


Sub Data1_Error(ByVal ErrorNumber As Long, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, fCancelDisplay As Boolean)  
    If ErrorNumber = 3704 Then  
    fCancelDisplay = True  
    End If  
End Sub  
Messages postés
16
Date d'inscription
vendredi 19 mars 2010
Statut
Membre
Dernière intervention
12 avril 2010
1
Merci pour toutes tes explications et ta patience !
Messages postés
16
Date d'inscription
vendredi 19 mars 2010
Statut
Membre
Dernière intervention
12 avril 2010
1
Ah par contre si jamais tu passes dans le coin Pollux31 tu peux peut être m'éclairer !

Quand je clic sur le bouton il créer bien la table et y insère le contenu du tableau.
Par contre si j'ai fait des modifications sur le tableau sans sauvegarder, il ne les prend pas en compte. Et je n'ai pas trouvé de commande en VB pour sauvegarder rapidement, l'équivalent de Ctrl S Oo
Comme ça au clic du bouton, il sauvegarde, et hop il lance la procédure. Et là je suis sur qu'il prendra tout en compte :)

(Sheets("Blabla").SaveAs n'a pas l'air de marcher
Messages postés
16
Date d'inscription
vendredi 19 mars 2010
Statut
Membre
Dernière intervention
12 avril 2010
1
Super merci beaucoup! Toujours là à la rescousse ;)