[VBA/SQL] communication Excel<-->Access

Résolu
lalilu Messages postés 36 Statut Membre -  
 YATA -
Bonjour,
veuillez m'excuser par avance pour la longueur de mon message.
j'ai beau parcourir les forums et tutorials, je ne trouve pas le moyen de faire ce que je veux. voici mon problème.

j'ai un classeur Excel dont le but est de réaliser des calculs de simulation biologique (peu importe...). ces calculs sont faits par des fonctions personnalisées VBA qui prennent tout un tas de paramettres.

ex : vitesse_croissance(poids, alpha, beta, gamma, truc, machin, bidule).

ma simulation est réalisable sur plusieurs espèces d'animaux et les paramètres alpha, beta, etc sont spécifiques de l'espèce.

ce que je voudrais c'est stocker les paramètres dans une base de donnée Access et organiser la communication entre le classeur et la BD de la façon suivante:
- l'utilisateur choisit l'espèce qu'il veut parmi une liste déroulante dans Excel (ça c'est bon je sais faire)
- le choix est repris dans des requètes SQL de sélection. un truc du genre:
SELECT alpha FROM MaTable
WHERE espece="Mon_Choix_Dans_Excel"
- le résultat de la requète est utilisé pour calculer la vitesse de croissance dans ma fonction Excel VBA. un truc du genre:
dim alpha as double
set alpha="Le_Résultat_De_MaRequète_SQL".

ma question est donc la suivante : existe-t'il un moyen de faire ça et si oui pourriez vous me l'expliquer?
merci d'avance !
Configuration: Windows XP
Internet Explorer 6.0

16 réponses

  1. Polux31 Messages postés 7219 Statut Membre 1 204
     
    La méthode de connexion ADO est la plus simple pour communiquer avec une base Access, et on peut difficilement s'en passer.

    L'exemple sur le lien demande quelques connaissances en programmation.

    Voilà un exemple pour ce connecter à une base Access. Il faut créer un module, le nommer ModBdd et coller le code ci dessous dans le module :
    '---------------------------------------------------------------------------------------
    ' Module    : ModuleBdD
    ' Author    : Polux
    ' Date      : 27/10/2008
    ' Référence : /!\ DECLARER DANS LES REFERENCES :  Microsoft ActiveX Data Object
    '---------------------------------------------------------------------------------------
    
    'Obligation de déclaration des variables.
    Option Explicit
    
    '/////////////////////////////////'
    '// Variables globales du module
    '/////////////////////////////////'
    Private CmdSql As ADODB.Command
    Private NbRs As Long
    Public cnx As ADODB.Connection
    Private rs As ADODB.Recordset
    
    '////////////////////////////////'
    '// Constantes à modifier selon le
    '// le cas d'utilisation
    '///////////////////////////////'
    Public Const bdd = "C:\ma_base.mdb"
    'Private Const pw = "pwd"
    'Private Const user = "user"
    
    '//////////////////////////////////////
    '// Accesseurs des variables globales
    '//////////////////////////////////////
    
    'procédure qui stocke le nombre d'enregistrement dans le recordset
    Public Sub setNbRs(ByVal nb As Integer)
        NbRs = nb
    End Sub
    
    'fonction qui retourne le nombre d'enregistrement dans le recordset
    Public Function getNbRs() As Long
        getNbRs = NbRs
    End Function
    
    'fonction qui retourne le recordset
    Public Function getRs() As ADODB.Recordset
        Set getRs = rs
    End Function
    
    'fonction qui retourne la connexion
    Public Function getAdoCnx() As ADODB.Connection
        getAdoCnx = AdoCnx
    End Function
    
    'fonction qui retourne le chemin de la base de données
    Public Function getBdd() As String
        getBdd = bdd
    End Function
    
    
    '//////////////////////////////////
    '// Méthodes du module
    '//////////////////////////////////
    
    'procédure de connexion à la base de donnée
    
    Public Sub ConnectBdd()
        Set cnx = New ADODB.Connection
        
        cnx.CursorLocation = adUseServer
        'Définition du pilote de connexion
        cnx.Provider = "Microsoft.Jet.OLEDB.4.0"
    
        'Définition de la chaîne de connexion
        cnx.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & bdd & ";Persist Security Info=False;"
        cnx.ConnectionString = cnx.ConnectionString
       
        'Ouverture de la base de données
        cnx.Open
    
    End Sub
    
    'fonction qui retourne un booléen.
    'Paramètres entrées : la requête, l'objet recordset
    'Passe la requête à la base de données et récupère le résultat dans le recordset
    Public Function OpenRecordset(ByVal requete As String, ByRef rs As ADODB.Recordset) As Boolean
        
    On Error Resume Next
      
        On Error Resume Next
        rs.Open requete, ModuleBdD.cnx, , , adCmdText   'passage de la requête
        
        If Err > 0 Then         'en cas d'erreur la fonction retourne Faux et on sort de la fonction
            OpenRecordset = False
            Exit Function
        End If
        
        rs.MoveFirst        'la connexion a réussi, on se place sur le 1er enregistrement
        NbRs = rs.RecordCount   'on compte le nombre de ligne retournée
        OpenRecordset = True  'la fonction retourne Vrai
        
    End Function
    
    'fonctions Suivant, Précédent, Premier, Dernier qui retourne un booléen.
    'Paramètre entrée : l'objet recordset
    'Fonctions qui permettent de parcourir les enregistrements d'un recordset
    Public Function RSLireSuivant(ByRef rs As ADODB.Recordset) As Boolean
    
        On Error Resume Next
        rs.MoveNext
        If rs.EOF Then
            RSLireSuivant = False
            Exit Function
        End If
        
        If Err <> 0 Then
            RSLireSuivant = False
            MsgBox Err.Numbre & ": " & Err.Description
            Exit Function
        End If
        
        RSLireSuivant = True
        
    End Function
    
    Public Function RSLirePrecedent(ByRef rs As ADODB.Recordset) As Boolean
    
        On Error Resume Next
        rs.MovePrevious
        If rs.BOF Then
            RSLirePrecedent = False
            Exit Function
        End If
        
        If Err <> 0 Then
            RSLirePrecedent = False
            Exit Function
        End If
        
        RSLirePrecedent = True
        
    End Function
    
    Public Function RSLirePremier(ByRef rs As ADODB.Recordset) As Boolean
    
        On Error Resume Next
        rs.MoveFirst
        If Err <> 0 Then
            RSLirePremier = False
            Exit Function
        End If
        
        RSLirePremier = True
        
    End Function
    
    Public Function RSLireDernier(ByRef rs As ADODB.Recordset) As Boolean
    
        On Error Resume Next
        rs.MoveLast
        If Err <> 0 Then
            RSLireDernier = False
            MsgBox Err.Number & " : " & Err.Description
            Exit Function
        End If
        
        RSLireDernier = True
        
    End Function
    
    'procédure qui ferme la connexion à la base de données
    Public Sub CloseBdd()
        AdoCnx.Close
    End Sub
    
    'procédure qui ferme le recordset
    Public Sub CloseRs()
        rs.Close
    End Sub


    N'hésite pas à revenir pour avoir des explication.

    ;o)
    6
  2. lalilu Messages postés 36 Statut Membre 1
     
    je me permet de m'auto monter dans le classement...
    2
  3. Polux31 Messages postés 7219 Statut Membre 1 204
     
    Bonjour,

    As-tu déjà une connexion avec Access ?

    Peux-tu dire plus explicitement ce que tu n'arrives pas à faire ?

    Merci.

    ;o)
    1
  4. lalilu Messages postés 36 Statut Membre 1
     
    merci !
    rien de tel qu'un code bien commenté !!! j'ai cependant quelques questions.

    qu'est que c'est exactement le recordSet ? je vois ça comme le résulat d'une requête sous forme de tableau. Me trompe-je ?
    y à t'il un RecordSet par requête ?

    cette méthode permet d'utiliser une BD dans excel, mais comment fait on pour utiliser le contenu d'une cellule Excel comme critère de sélection dans une requete SQL?
    y a-t-il un moyen d'extraire le contenu d'une cellule et de l'écrire à la suite du WHERE dans la requète d'Access ?
    ou peut on carément écrire du SQL dans une Sub ou fuction VBA ?

    je ne suis pas sûre d'être très claire ...
    1
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. Polux31 Messages postés 7219 Statut Membre 1 204
     
    Un recordset contient effectivement le résultat d'une requête sous forme de tableau.

    Il faut donc un recordset par requête passer à la base de données.

    On peut utiliser une variable d'un fichier Excel (le contenu d'une cellule) comme critère de choix dans une requête SQL. Pour cela, on écrit la requête en utilisant le code VBA.

    Par exemple, en utilisant, le code passé ci dessus on peut faire :

    - Dans un module de UserForm ou autre
    Sub AfficheRequete()
    Dim oRs As ADODB.Recordset
    Dim Query As String
    Dim ok As Boolean
    Dim i As Long
    
       'Construction de la requête
       Query = "Select * From MaTable Where mon_champ = '" & Worksheets(1).Range("C10").Value & " ' "
       'Création de l'objet recordset
       Set oRs = New ADODB.Recordset
       'Numéro de la première ligne pour l'affichage des résultats
       i = 2
       '
       ' On passe la requête à la base. Si le résultat est True on commence la lecture du recordset
       If ModBdd.OpenRecordset(Query, oRs) = True Then
          'On lit le premier enregistrement du recordset
          ok = ModBdd.LirePremier(oRs)
          'Tant que LireSuivant est True on affiche le résultat
          While ok = True
             Worksheets(2).Range("A" & i).Value = oRs.Fields(0) ' 1er champ de l'enregistrement Bdd en cours
             Worksheets(2).Range("B" & i).Value = oRs.Fields(1) ' 2ème champ de l'enregistrement Bdd en cours
             Worksheets(2).Range("C" & i).Value = oRs.Fields(2) ' 3ème champ de l'enregistrement Bdd en cours
             ' etc pour chaque champ de la table
             i = i + 1  'on ajoute une ligne pour afficher la ligne suivante
             ok = ModBdd.LireSuivant(oRs) 'On passe à la ligne suivant
          Wend
       End If
    End Sub
    

    J'espère que c'est clair !!! pas sûr ...

    N'hésites pas à demander des explications.

    ;o)
    1
  7. Polux31 Messages postés 7219 Statut Membre 1 204
     
    Si la requête existe déjà sous Access, elle se présente sous forme de table. Il suffit de faire :

    Query = "Select * From requête1" 'Avec une clause Where éventuellement
    ok = ModBdd.OpenRecordset(Query, oRs)

    ;o)
    1
  8. YATA
     
    Dsl de faire remonter se topic !
    je suis tombé dessur par hazard
    Je tiens à remercier polux pour son aide et le temps que je vais gagner dans mon travail !
    encore merci
    1
  9. lalilu Messages postés 36 Statut Membre 1
     
    ça n'a pas l'air de vous inspirer ...
    -1
  10. lalilu Messages postés 36 Statut Membre 1
     
    le truc c'est que ça m'a l'air bien compliqué !!!
    j'espérait qu'il existe queque chose de plus pratique (ou du moins facile)...
    0
  11. lalilu Messages postés 36 Statut Membre 1
     
    et concernant la connection avec access : non je l'ai pas ...
    0
  12. lalilu Messages postés 36 Statut Membre 1
     
    ça m'a l'air pas mal du tout ...

    et si j'ai déjà des requêtes qui existent dans ma BD Access, puis-je les appeler directement dans ma function VBA, ou dois-je obligatoirement réécrire le code SQL dans la dite function ?
    un truc du genre:
    Query = Modbbd.requete1; ?
    -1
  13. lalilu Messages postés 36 Statut Membre 1
     
    Formidable !

    je devrais pouvoir m'en sortir maintenant ...

    merci pour ton aide Polux31 !
    0
  14. Polux31 Messages postés 7219 Statut Membre 1 204
     
    De rien, je le fais avec plaisir.

    Bonne continuation

    ;o)

    PS : N'oublie pas de mettre en résolu et n'hésite à revenir si problème.
    0
  15. DarkAurora Messages postés 443 Statut Membre 27
     
    j'ai un autre problème que celui ci
    j'aimerais grâce à recordset sélectionné tout une colonne ( ce qui je crois est fait ) mais ensuite je souhaite envoyé ces données dans une requête sous access que j'ai crée

    voici mon code :
    Private Sub pointeur_Click()
    Dim valeur As String
    Dim truc As DAO.Recordset
    Dim requete As String
    valeur = pointeur.Value
    If (valeur = "<<TOUS>>") Then
    requete = "SELECT * FROM [R_effectif];"
    DoCmd.RunSQL requete
    End If
    End Sub

    comme avec runsql on ne peut pas faire sélection on doit utiliser recordset le problème c'est que je ne sais pas utiliser recordset pour faire ce que je veux
    0
  16. Polux31 Messages postés 7219 Statut Membre 1 204
     
    Bonjour,

    Voilà un exemple pour utiliser un recordset avec un objet DAO:

    Sub OpenRecordset ()
        Dim oDb As DAO.Database, oRs As DAO.Recordset
        Dim sQuery As String
        ' Ouverture de la base de données 
        Set oDb = DBEngine.OpenDatabase ("c:\mabase.mdb")   'mettre le chemin d'accès de la base ou dans Access mettre Set oDb = CurrentDb
        sQuery =  "Select champ1, champ2 From matable"
        ' Ouverture du recordset 
        Set oRs = db.OpenRecordset (sQuery, dbOpenForwardOnly, dbReadOnly)
    
        'Lecture du recordset
        While Not oRs.EOF
              msgBox oRs.Fields(0) & " " & oRs.Fields(1)
        oRs.MoveNext
        Wend
    
        ' Fermeture du Recordset
        oRs.Close
        oDb.Close
    End Sub


    ;o)
    0