VBA : pbm import champ access (avec formule)

Bonjour à tous,

J'ai une base de données Access avec des requêtes sur mes tables, et un programme vba qui importe ces tables dans différentes feuilles d'un fichier Excel. Tout ça marche très bien. Sauf que... Dans une de mes requêtes, je calcule la médiane des valeurs d'une table, à l'aide d'une fonction que j'ai créée et mis dans un module de ma base Access. Lorsque je cherche à importer cette table, j'obtiens l'erreur suivante :
Erreur d'exécution '-2147217900 (80040e14)' :
Fonction 'fMediane' non définie dans l'expression

Voici la sub vba qui me permet d'importer ma table:
Sub Import_tab_access(TAS As String, wk_encours As String, feuil_encours As String, nom_tab_access As String, indic As String, premiereligne As Integer) 
Dim oRs As ADODB.Recordset 
Dim oCnn As ADODB.Connection 
Dim nom_tab As String 
nom_tab = nom_tab_access & indic 

    Workbooks(wk_encours).Sheets(feuil_encours).Cells(premiereligne, 1).Value = indic 
     
     
    'Connect to your Access db 
    Set oCnn = New ADODB.Connection 
    oCnn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=chemin\P_" & TAS & "_test_en_cours.mdb;" 'User Id=admin;Password=;" 
    oCnn.Open 
     
    'Create your recordset 
    Set oRs = New ADODB.Recordset 
    oRs.Open "SELECT * FROM " & nom_tab & ";", oCnn, adOpenKeyset, adLockReadOnly, adCmdText 
     
    'Add to your current workbook and add the field names as column headers (optional) 
    For i = 0 To oRs.Fields.Count - 1 
        Workbooks(wk_encours).Sheets(feuil_encours).Cells(premiereligne, i + 2).Value = oRs.Fields(i).Name 
    Next 
     
    'Workbooks(wk_encours).Sheets(feuil_encours).Range("1:1").Font.Bold = True 
    Workbooks(wk_encours).Sheets(feuil_encours).Cells(premiereligne + 1, 2).CopyFromRecordset oRs 
     
    'Clean up ADO Objects 
     oRs.Close 
     Set oRs = Nothing 
     oCnn.Close 
     Set oCnn = Nothing 
End Sub


L'erreur est au niveau de la ligne

oRs.Open "SELECT * FROM " & nom_tab & ";", oCnn, adOpenKeyset, adLockReadOnly, adCmdText


Merci d'avance pour tout conseil ou toute suggestion!

7 réponses

  • Votes
  • Date
  • Date décroissante
  1. Bonjour,

    oCnn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=chemin\P_" &

    chemin\P_: ne doit pas convenir, c'est du texte pas une variable qui indique un chemin

    A voir

    Bonne suite
    1. Merci pour ta réponse, en fait j'ai remplacé le vrai chemin "C:\ etc." par le mot chemin uniquement ici, histoire de le garder confidentiel...:p Desolée pour la confusion. C'est la seule manip de ce genre que j'ai faite.
      1. Re,
        Merci de nous le preciser. Pourquoi vous avez :

        nom_tab = nom_tab_access & indic

        J'ai teste la ligne ou vous avez l'erreur en remplacent nom_tab par une table d'une de mes bases, je n'ai pas d'erreur.

        A+
        1. Oui, cette macro marche très bien "en général" avec les tables Access. Là où ça ne fonctionne plus c'est pour importer une requête Access qui fait appel à une fonction (fMediane en l'occurence) créée par moi-même dans un module...

          (nom_tab = nom_tab_access & indic est là seulement parce que je fais en réalité appel à la sub Import_tab_access dans une autre sub, avec des boucles sur plusieurs macros variables.)
          1. Re,
            Je viens de retester la ligne d'erreur en mettant un nom de table bidon par rapport a ma base de donnees, la j'ai votre erreur.

            Il faudrait mettre le pointeur de la souris sur la ligne d'erreur quand elle se produit pour voir le nom de la table que vous avez ou mettez le pointeur sur nom_table au debut de la subroutine.

            A+
            1. Re bonjour et merci pour toute l'attention que vous portez à ma question. Mon souci est que ma requête existe bien...
              Je pense que je ne suis pas assez claire. Pour l'être, je me permets de remettre mon code, mais débarrassé de tous les paramètres qui pourraient porter à confusion.
              Sub test()
              Dim oRs As ADODB.Recordset
              Dim oCnn As ADODB.Connection
              
                  Set oCnn = New ADODB.Connection
                  oCnn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Documents and Settings\toto\Bureau\P_test_en_cours.mdb;" 
                  oCnn.Open
                  
                  Set oRs = New ADODB.Recordset
                  oRs.Open "select * from R_stat_descriptives_dec ;", oCnn, adOpenKeyset, adLockReadOnly, adCmdText
                  
              For i = 0 To oRs.Fields.Count - 1
                      Workbooks("Sorties_resultats").Sheets("toto").Cells(1, i + 2).Value = oRs.Fields(i).Name
               Next
                  
                   Workbooks("Sorties_resultats").Sheets("toto").Cells(2, 2).CopyFromRecordset oRs
                  
                   oRs.Close
                   Set oRs = Nothing
                   oCnn.Close
                   Set oCnn = Nothing
              End Sub


              Quand je lance la fonction test() avec une requête Access lambda, cela fonctionne. Mais dans la requête R_stat_descriprives_dec, il y a le calcul de la médiane des valeurs d'une table, calcul qui se fait par l'appel de la fonction fMediane(), qui se trouve dans Module1 d'Access. Et c'est cette fonction que vb ne trouve pas... :p
              L'erreur se produit à la ligne
              " oRs.Open "select * from R_stat_descriptives_dec ;", oCnn, adOpenKeyset, adLockReadOnly, adCmdText"
              La table R_stat_descriptives_dec existe bien dans P_test_en_cours.mdb...

              Merci d'avance pour toute idée!
              1. Re,

                Mon souci est que ma requête existe bien...
                La table R_stat_descriptives_dec existe bien dans P_test_en_cours.mdb...

                Juste une info pour moi : R_stat_descriptives_dec c'est une table ou une requete??????
              2. Euh... les deux? ;) En fait c'est une requête sur une table X, mais j'ai gardé plusieurs colonnes, ce qui en fait une table, à moins que je n'utilise pas le bon vocabulaire.
                En gros, j'ai une table X de base, sur laquelle je fais des statistiques descriptives, c'est à dire que je récupère la moyenne, le min, le max (toutes des fonctions prédéfinies dans Access) d'une variable dec, et enfin la médiane. Toutes ces infos sont dans R_stat_descriptives_dec. Je réponds à ta question?
              3. Re,
                Oui, vous faites une requete sur une le resultat d'une requete.
            2. Coucou,

              Merci pour tous ceux qui ont lu mon sujet. J'ai trouvé une façon détournée de régler mon problème:) (même si je pense qu'il doit exister quelque part une option à cocher pour qu'Excel et vba se parlent mieux...)
              Pour info donc, j'ai créé ma table R_stat_descriptives_dec qui contient toutes les stat descriptives dont j'avais besoin mais pas la médiane.
              J'ai mis la fonction fMediane dans vba Excel, et je l'ai adaptée pour que la médiane se calcule sur la base Access à partir d'Excel. Je fais donc une requête sur une table Access à partir d'Excel en fait. Et j'importe le résultat de la requête dans une cellule de ma feuille Excel de résultats.
              Merci à tous, à bientôt! :)

              Public Function fMediane(strTable As String, Strfield As String) As Variant
              
              Dim oDBS As DAO.Database
              Dim oRST As DAO.Recordset
              Dim blnEven As Boolean
              Dim vntMedian As Variant
              
                Set oDBS = CurrentDb()
                Set oRST = oDBS.OpenRecordset("SELECT * FROM " & strTable & " ORDER BY " & Strfield)
                
                If oRST.EOF = False Then
                   oRST.MoveLast
                   'Is there an even number of records in the recordset?
                   blnEven = (oRST.RecordCount Mod 2 = 0)
                   'Rounds down if there is an even number of records...
                   oRST.PercentPosition = 50
                   vntMedian = oRST.Fields(Strfield)
                        
                   If blnEven Then
                       oRST.MoveNext
                       '...so take the average of the this and the next value up
                       vntMedian = (vntMedian + oRST.Fields(Strfield)) / 2
                   End If
                End If
                
                fMediane = vntMedian
                oRST.Close
                Set oRST = Nothing
                Set oDBS = Nothing
              
              End Function