[Access] Lier et délier des tables Access

Résolu
Bonjour,

Dans mon travail, je dois réaliser une petite application Access. Pour cela, il me faut lier et delier des tables venant d'un autre fichier Access. Avec l'interface graphique il n'y a pas beaucoup plus simple mais ce que je cherche c'est du code qui pourait automatiser la chose.
Je crois pas qu'il soit possible de délier des table mais si je trouve du code pour changer le chemin de liaison, ca me convient aussi.

Je vous remercie d'avance.
Configuration: Windows XP
Internet Explorer 6.0
Office2003

17 réponses

  1. Salut à tous,

    En fait, je donne la solution au cas où quelqu'un aurait le même problème. J'explique rapidement le fonctionnement. JE supprime toutes les tables liées pour recreer le lien.
    Niveau code ça donne :
    'supprimer les tables liées
    Dim BD As DAO.Database
    Set BD = CurrentDb
    Dim tb As DAO.TableDef
    For Each tb In BD.TableDefs
        If Left(tb.Name, 4) <> "MSys" Then
            If Len(tb.Connect) > 0 Then
                DoCmd.RunSQL "DROP TABLE [" & tb.Name & "] ;"
                Debug.Print "effacement de " & tb.Name & " -=#=> " & tb.Connect
            End If
        End If
    Next tb
    
    Dim strMotPasse As String
    Dim strConnect As String
    Dim strNomsTables() As String
    Dim strTemp As String
    Dim i As Integer
    Dim oDb As DAO.Database
    Dim oDbSource As DAO.Database
    Dim oTbl As DAO.TableDef
    Dim oTblSource As DAO.TableDef
    strMotPasse = "pass"
    
    'dans strFichierTables on trouve le chemin de ma source style "C:\test.mdb"
    strConnect = "MS Access;pwd=" & strMotPasse & ";DATABASE=" & strFichierTables
    Set oDb = CurrentDb
    Set oDbSource = DBEngine.OpenDatabase(strFichierTables, True, True, strConnect)
    
    For Each oTblSource In oDbSource.TableDefs
        If (oTblSource.Attributes And dbSystemObject) = 0 Then
            strTemp = strTemp & oTblSource.Name & "|"
        End If
    Next
    oDbSource.Close: Set oDbSource = Nothing
    strNomsTables = Split(Left(strTemp, Len(strTemp) - 1), "|")
    For i = 0 To UBound(strNomsTables)
        Set oTbl = oDb.CreateTableDef(strNomsTables(i))
        oTbl.Connect = strConnect
        oTbl.SourceTableName = strNomsTables(i)
    oDb.TableDefs.Append oTbl
    Next i
    
    oDb.TableDefs.Refresh
    


    Voila. Encore une fois, merci pour ton aide Blux.
    10
    1. Modérateur
      Salut,

      on peut obtenir le chemin de connexion et le changer le cas échéant :
      Set Db = CurrentDb
      ' Test des attachements
      ' On exclut les tables système
      ' ainsi que les tables non attachées
      For Each Tb In Db.TableDefs
          'MsgBox Tb.Name
          If Left(Tb.Name, 4) <> "MSys" Then
              If Tb.Connect <> "" Then
                 MsgBox Tb.Properties("Connect")
                 ' Tb.Connect = ";Database=c:\toto\mabase.mdb"
              End If
          End If
      Next
      Pour délier des tables , il suffit de mettre le même nom que la base en cours, soit, dans mon exemple Db.Name, voire mettre à blanc la zone connect... (jamais testé par mes soins !)
      8
      1. voila mon code :
        Set esp = DBEngine.Workspaces(0)
        Set dbData = esp.OpenDatabase(strFichierTables)
        
        ' Test des attachements
        ' On exclut les tables système
        ' ainsi que les tables non attachées
        For Each TableData In dbData.TableDefs
            'MsgBox Tb.Name
            If Left(TableData.Name, 4) <> "MSys" Then
                'If TableData.Connect <> "" Then
                   'MsgBox TableData.Properties("Connect")
                   TableData.Connect = ";DATABASE=" & strFichierTables
                   CurrentDb.TableDefs.Refresh
                'End If
            End If
        Next
        

        si je fais l'affichage, de TableData.Properties("Connect") alors j'ai une msgBox avec le chemin que je veux. Enfin si j'ai bien fais ce que tu attendais de moi...
        1
        1. Bon ben, il faut déjà que je progresse en programation avant de pouvoir mettre en oeuvre un truc comme ça. Je continue à essayer.
          0
          1. Au fait, je n'ai même pas dis merci donc merci beaucoup blux
            0
            1. Modérateur
              Tu diras merci quand ça marchera ! ;-)
              0
            2. Modérateur
              @bluxSalut blux,

              le code que tu as écrit vaut un petit merci quand même :-))
              0
            3. Modérateur
              @lami20jBon ben, si t'insistes...
              0
            4. @lami20jSalut,

              J'ai mis en place du code en m'ispirant fortement du tiens mais j'ai toujours cette meme erreur quand je veux lier les tables,il me dit que la première table existe déjà et il s'arrete la. En fait ca change pas le chemin. Voici mon code :

              mon formulaire
              Private Sub BAttacherTables_Click()
              Dim esp As Workspace
              Dim dbData As Database, TableData As TableDef, TableCree As TableDef
              
              On Error GoTo GestionErreur
              
              Set esp = DBEngine.Workspaces(0)
              Set dbData = esp.OpenDatabase(strFichierTables)
              
              For Each TableData In dbData.TableDefs
                  If TableData.Attributes = 0 Then
                      Set TableCree = CurrentDb.CreateTableDef(TableData.Name)
                      TableCree.Connect = ";DATABASE=" & strFichierTables
                      TableCree.SourceTableName = TableData.Name
                      CurrentDb.TableDefs.Append TableCree
                  End If
              Next
              Set dbData = Nothing
              CurrentDb.TableDefs.Refresh
              
              MsgBox "Attache des tables réalisé avec succès !", vbInformation, "Attache des tables"
              
              GestionErreur_exit:
                  Exit Sub
              
              GestionErreur:
                  MsgBox "Erreur n°" & Err.Number & ":" & vbCrLf _
                      & Err.Description
                  Resume GestionErreur_exit
              
              End Sub
              


              mon module
              Function Attaches() As Boolean
              Dim Chemin As String
              Dim TableLiée As String
              Dim tdf As TableDef
              Dim sPathBase As String
              On Error GoTo gestERR
              
              
              Chemin = ";DATABASE=" & _
              "B:\A\B\FC\APPLI_FC25\Comptes_sociaux_nouvelle appli\31-12-2005 complémentaire\" & "ComptesSociaux_Donnees.mdb"
              For Each tdf In CurrentDb.TableDefs
              If tdf.Connect <> "" Then
                  If InStr(1, tdf.Name, "MSys") = 0 And tdf.Connect <> "" Then
                      Debug.Print tdf.Name
                      DoEvents
                      tdf.Connect = Chemin
                      tdf.RefreshLink
                  End If
              End If
              Next
              
              Attaches = True
              GestExit:
              MsgBox "Fini"
              Exit Function
              gestERR:
              MsgBox Err.Description, vbCritical, "erreur"
              
              Resume GestExit
              Resume Next
              
              End Function
              


              Tout ça c'est du code qui existait déjà et je dois dire que je ne comprends pas tout
              0
            5. Modérateur
              @lami20jBen moi non plus, car ta procédure semble créer des tables :
                      CurrentDb.TableDefs.Append TableCree
              Ca me parait donc normal qu'il te jette si une table existe déjà...

              J'ai pas tout compris l'objet du code...
              0
          2. J'ai mis en place le code que tu m'as donné. Ca donne :

            Set dbData = esp.OpenDatabase(strFichierTables)
            
            ' Test des attachements
            ' On exclut les tables système
            ' ainsi que les tables non attachées
            For Each TableData In dbData.TableDefs
                'MsgBox Tb.Name
                If Left(TableData.Name, 4) <> "MSys" Then
                    If TableData.Connect <> "" Then
                       'MsgBox TableData.Properties("Connect")
                       TableData.Connect = ";DATABASE=" & strFichierTables
                    End If
                End If
            Next
            


            Malheureusement pas de changement en vu pour le chemin de mes tables. Je pense que ca vient du reste de mon code.

            En tout cas merci de m'avoir consacré un peu de temps
            0
            1. Modérateur
              Il faut rajouter un 'TableData.Refresh' après le .Connect.

              Ca n'est pas présent dans mon exemple, je l'ai recopié depuis une base, en allégeant le code, et la ligne a dû sauter...
              0
          3. je le fait juste en dessous de mon bout de code. En fait, quand j'execute cette partie du programme il ne rentre jamais dans la condition
            If TableData.Connect <> "" Then
            Si je l'enlève, j'ai une erreur. As tu une idée ?
            0
            1. Modérateur
              C'est normal, si tes tables sont déjà liées, le contenu de la propriété .connect n'est pas vide, donc tu ne satisfais pas à la condition...
              0
            2. Oui mais si je l'enlève j'ai une erreur. Ce que je veux faire c'est changer le chemin de liaison des tables existantes. Donc si tu peux encore m'aider stp
              0
            3. Modérateur
              @_goniC'est quoi ton erreur ?
              Tu as aussi enlevé le end if qui va avec ?

              Quand est-ce que tu appelles ta procédure ? Car le code (que tu nommes mon module) donné au message 7 n'est jamais appelé...
              0
          4. En fait j'appel pas mon module (message 7). C'est une erreur de ma part. Sinon, quand j'enlève la condition, l'erreur est :

            Erreur n°3219:
            Opération non valide

            Voila
            0
            1. Modérateur
              Tu peux mettre le code que tu emploies après avoir ôté le test de non vide ?

              Et si tu affiches tabledata.connect pour chaque table, tu as quoi ?
              0
              1. Modérateur
                Je t'ai suggéré un tabledata.refreshlink, pas un currentdb.tables.refresh (qui n'est pas forcément obligatoire)...

                De plus, je pense qu'il peut y avoir confusion entre ta base notée dbdata et currentdb...

                Supprime l'affectation de dbdata et remplace par set dbdata=currentdb
                0
                1. Alors je me trouve face à une nouvelle erreur.
                  Erreur n°3011 :
                  Le moteur de base de données Microsoft Jet n’a pas pu trouver l’objet ’31-12-2005-a120#txt’. Assurez vous que l’objet existe et que vous avez correctement saisi son chemin d’accès.
                  

                  Je suis sure de mon chemin d’accès vu que je le fais à l’aide d’un système comme « parcourir ». Ce n’est donc pas moi qui entre le chemin manuellement.
                  Par contre mon chemin contient des espaces :
                   F:\Projet\31-12-2005 complémentaire 
                  0
                  1. petite précision, je n'ai pas le droit de supprimer ce petit espace qui doit etre la raison de cet erreur.
                    0
                    1. Je viens de me rendre compte aussi que le chemin change cette fois-ci. Donc plus qu'a savoir d'où vient cet erreur
                      0
                      1. Modérateur
                        Ton erreur est en quelle ligne ?

                        As-tu fait les modifs suggérées en 18 ?
                        0
                        1. J'ai fait les modifs, c'est ce qui ma fait avoir cet erreur mais je crois vraiment que ca doit venir de mes espaces dans le nom du chemin. Je dois mal prendre ca en compte. Pour ce qui est de la ligne je vais regarder
                          0
                          1. alors c'est au niveau du premier passage sur la ligne TableData.RefreshLink
                            0
                            1. Modérateur
                              J'ai fait un test chez moi :

                              - avec un nom comprenant des espaces, il me met argument non valide sur la ligne refreshlink
                              - directement sous C:\, il me met pilote isam introuvable sur la ligne refreshlink (c'est une erreur de m*$*$ qui n'a rien à voir avec ce qu'on fait, elle est connue comme le houblon, il va falloir que je réinstalle ACCESS...)

                              ... mais je ferai ça en 2007, je pars en congés ce soir, à l'année prochaine !
                              0