VBA : pbm import champ access (avec formule)

soficaat -  
 soficaat -
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

  1. f894009 Messages postés 17417 Date d'inscription   Statut Membre Dernière intervention   1 717
     
    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
    0
  2. soficaat
     
    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.
    0
  3. f894009 Messages postés 17417 Date d'inscription   Statut Membre Dernière intervention   1 717
     
    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+
    0
  4. soficaat
     
    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.)
    0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. f894009 Messages postés 17417 Date d'inscription   Statut Membre Dernière intervention   1 717
     
    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+
    0
  7. soficaat
     
    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!
    0
    1. f894009 Messages postés 17417 Date d'inscription   Statut Membre Dernière intervention   1 717
       
      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??????
      0
    2. soficaat
       
      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?
      0
    3. f894009 Messages postés 17417 Date d'inscription   Statut Membre Dernière intervention   1 717
       
      Re,
      Oui, vous faites une requete sur une le resultat d'une requete.
      0
  8. soficaat
     
    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
    
    0