{"id":768,"date":"2012-12-15T12:12:13","date_gmt":"2012-12-15T11:12:13","guid":{"rendered":"http:\/\/www.unicoda.com\/?p=768"},"modified":"2018-06-13T09:59:07","modified_gmt":"2018-06-13T07:59:07","slug":"accessgestion-auto-de-la-liaison-des-tables","status":"publish","type":"post","link":"https:\/\/www.unicoda.com\/?p=768","title":{"rendered":"[Access]Gestion Auto de la Liaison des Tables"},"content":{"rendered":"<p>Je sais que j&rsquo;ai plut\u00f4t l&rsquo;habitude d&rsquo;\u00e9crire \u00e0 propos de logiciel libre, et que je pr\u00e9f\u00e8re aborder un point concernant GNU\/Linux que le syst\u00e8me privateur Windows et ses outils associ\u00e9s. Seulement parfois, un \u00e9tudiant en informatique n&rsquo;a pas le choix des technos \u00e0 utiliser pour r\u00e9aliser son projet et est contraint d&rsquo;utiliser des solutions privatrices. Ce fut le cas sur un projet de base de donn\u00e9es o\u00f9 le logiciel impos\u00e9 \u00e9tait Access. Cet article va donc aborder un point pr\u00e9cis qui m&rsquo;avait demand\u00e9 de nombreuses heures de recherche, essais, etc avant d&rsquo;arriver \u00e0 r\u00e9aliser la fonctionnalit\u00e9 voulue. En esp\u00e9rant que ces informations pourront aider d&rsquo;autres \u00e9tudiants par la suite et leur feront gagner un peu de temps. Je vais donc aborder la mise en place d&rsquo;un syst\u00e8me de liaison automatique des tables dans Access.<\/p>\n<p>Tout d&rsquo;abord, il faut savoir que dans notre situation, nous poss\u00e9dons deux fichiers. L&rsquo;un contient l&rsquo;ensemble des tables de notre base de donn\u00e9es, l&rsquo;autre contient l&rsquo;application les utilisant. Dans le fichier de l&rsquo;application, il est n\u00e9cessaire de r\u00e9aliser la liaison avec les tables de notre base de donn\u00e9es. Cette liaison peut \u00eatre facilement r\u00e9alis\u00e9e \u00e0 la main. N\u00e9anmoins, un probl\u00e8me se pose avec cette fa\u00e7on de faire. En effet, Access retient l&#8217;emplacement absolu de votre fichier de donn\u00e9es depuis la racine du disque dur soit quelque chose comme C:\\Utilisateurs\\Public\\MonProjet\\data.mdb par exemple. Et c&rsquo;est l\u00e0 que l&rsquo;on commence \u00e0 s&rsquo;arracher les cheveux puisque si je d\u00e9place le dossier MonProjet, la liaison des tables continue de pointer vers C:\\Utilisateurs\\Public\\MonProjet\\data.mdb. L&rsquo;horreur quand vous \u00eates amen\u00e9 \u00e0 changer d&rsquo;ordinateur. Il existe pourtant une solution qui consiste \u00e0 v\u00e9rifier l&rsquo;attachement des tables \u00e0 chaque lancement de l&rsquo;application. Si le chemin est correct, pas de probl\u00e8me, sinon, on refait la liaison automatiquement en construisant nous m\u00eame le chemin absolu jusqu&rsquo;au fichier. Il faut noter que dans l&rsquo;exemple que je vais d\u00e9velopper, le formulaire de d\u00e9marrage de l&rsquo;application ne fait aucune requ\u00eate vers la base de donn\u00e9es, afin d&rsquo;\u00e9viter des erreurs (bien qu&rsquo;il doit \u00eatre possible de faire ces requ\u00eates seulement lorsque la liaison a \u00e9t\u00e9 v\u00e9rifi\u00e9 et est correcte).<\/p>\n<p>Je cr\u00e9e donc un fichier Access qui contiendra ma base de donn\u00e9e et le nomme EXEMPLE_DATA. Pour notre exemple, on y ajoute une table PERSONNES avec divers champs. Par ailleurs, il faut cr\u00e9er le fichier qui contiendra l&rsquo;application EXEMPLE_APPLI. Maintenant que nous disposons de nos deux fichiers, nous allons pouvoir effectuer la premi\u00e8re liaison des tables manuellement. Onglet <em>External Data<\/em>, ic\u00f4ne <em>Linked Table Manager<\/em>. <a href=\"https:\/\/www.unicoda.com\/wp-content\/uploads\/2012\/11\/linked-table-manager.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-969\" title=\"Ic\u00f4ne Linked Table Manager\" src=\"https:\/\/www.unicoda.com\/wp-content\/uploads\/2012\/11\/linked-table-manager.png\" alt=\"\" width=\"72\" height=\"77\" \/><\/a>Une fois la liaison effectu\u00e9e, nous ajoutons un b\u00eate formulaire d&rsquo;accueil dans notre application. Celui-ci ne contient rien d&rsquo;autre qu&rsquo;un simple texte. Nous pouvons alors mettre en \u00e9vidence notre probl\u00e8me, couper\/coller votre fichier EXEMPLE_DATA dans un autre dossier que le dossier courant, r\u00e9-ouvrez EXEMPLE_APPLI, le fichier contenant les tables est maintenant introuvable. Nous allons donc y rem\u00e9dier en mettant en place la liaison automatique des tables \u00e0 chaque d\u00e9marrage de l&rsquo;application. Il est bien s\u00fbr possible de mettre en place un syst\u00e8me permettant de ne lier les tables que si le fichier de base de donn\u00e9es est introuvable.<\/p>\n<p>Dans notre application, nous allons donc ajouter le module suivant nomm\u00e9 liaison_auto qui contient les fonctions dont nous avons besoin pour la liaison. Enfin, \u00e0 l&rsquo;ouverture de notre formulaire d&rsquo;accueil, nous appelons les fonctions qui vont bien.<\/p>\n<pre>Option Compare Database\r\n\r\nPublic Function VerifAttach() As Boolean\r\nDim tdf As DAO.TableDef, strTemp As Variant, strPath As String, i As Long\r\nFor Each tdf In CurrentDb.TableDefs\r\n' Recherche d'une table li\u00e9e\r\nIf tdf.Connect &lt;&gt; \"\" Then\r\nstrTemp = Split(tdf.Connect, \";\")\r\nFor i = LBound(strTemp) To UBound(strTemp)\r\n' Recherche du param\u00e8tre de connection\r\nIf strTemp(i) Like \"DATABASE=*\" Then\r\nstrPath = Split(strTemp(i), \"=\")(1)\r\n' V\u00e9rification de l'existence de la bdd\r\nIf Dir(strPath) &lt;&gt; \"\" Then\r\nVerifAttach = True\r\nExit Function\r\nEnd If\r\nEnd If\r\nNext i\r\nEnd If\r\nNext\r\nEnd Function\r\n\r\nPublic Sub DeleteTables()\r\n' Supprimer toutes les tables attach\u00e9es\r\nOn Error Resume Next\r\nDim db As DAO.Database 'Database to import\r\nDim tdf As DAO.TableDef\r\nDim arrTablename() As String, i As Long\r\nReDim arrTablename(0)\r\nSet db = CurrentDb\r\n' R\u00e9pertorier les tables \u00e0 supprimer\r\nFor Each tdf In db.TableDefs\r\nIf tdf.Connect &lt;&gt; \"\" Then\r\nReDim Preserve arrTablename(UBound(arrTablename) + 1)\r\narrTablename(UBound(arrTablename)) = tdf.Name\r\nEnd If\r\nNext\r\n' Suppression\r\nFor i = LBound(arrTablename) To UBound(arrTablename)\r\ndb.TableDefs.Delete arrTablename(i)\r\nNext i\r\nSet db = Nothing\r\nEnd Sub\r\n\r\nPublic Function ActualiserAttaches(ByVal strCheminBd As String, Optional ByVal strMotPasse As String = \"\") As Boolean\r\nOn Error GoTo ActualiserAttaches_Err\r\nDim tdf As DAO.TableDef\r\n\r\nstrSourceConnect = \"MS Access;PWD=\" &amp; strMotPasse &amp; \";DATABASE=\" &amp; strCheminBd\r\n' Supprimer les tables avant tout\r\nDeleteTables\r\n\r\n'Permet de lier toutes les tables\r\nDim strConnect As String\r\nDim strNomsTables() As String\r\nDim strTemp As String\r\nDim i As Integer\r\nDim oDb As DAO.Database\r\nDim oDbSource As DAO.Database\r\nDim oTbl As DAO.TableDef\r\nDim oTblSource As DAO.TableDef\r\n\r\n'D\u00e9finit la chaine de connexion permettant la liaison des tables\r\nstrConnect = \"MS Access;pwd=\" &amp; strMotPasse &amp; \";DATABASE=\" &amp; strCheminBd\r\n'Instancie l'objet Database de la base courante\r\nSet oDb = CurrentDb\r\n'Instancie l'objet Database de la base prot\u00e9g\u00e9e\r\nSet oDbSource = DBEngine.OpenDatabase(strCheminBd, True, True, strConnect)\r\n\r\n'Parcours l'ensemble des tables de la base de donn\u00e9es prot\u00e9g\u00e9e\r\n'et stocke leur nom\r\nFor Each oTblSource In oDbSource.TableDefs\r\n\u00a0\u00a0\u00a0 'Ignore les tables system\r\n\u00a0\u00a0\u00a0 If (oTblSource.Attributes And dbSystemObject) = 0 Then\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 strTemp = strTemp &amp; oTblSource.Name &amp; \"|\"\r\n\u00a0\u00a0\u00a0 End If\r\nNext\r\n'Ferme la base de donn\u00e9es sources (imp\u00e9ratif pour la liaison)\r\noDbSource.Close: Set oDbSource = Nothing\r\n'Parcours le tableau de noms de tables\r\nstrNomsTables = Split(Left(strTemp, Len(strTemp) - 1), \"|\")\r\nFor i = 0 To UBound(strNomsTables)\r\n\u00a0 'Cr\u00e9e une nouvelle table dans la base de donn\u00e9es courante\r\n\u00a0 Set oTbl = oDb.CreateTableDef(strNomsTables(i))\r\n\u00a0 'Lie les deux tables\r\n\u00a0 oTbl.Connect = strConnect\r\n\u00a0 oTbl.SourceTableName = strNomsTables(i)\r\n\u00a0 'Ajoute la table \u00e0 la base de donn\u00e9es\r\n\u00a0 oDb.TableDefs.Append oTbl\r\nNext i\r\n\r\n'Rafraichit la liste des tables\r\noDb.TableDefs.Refresh\r\n\r\nActualiserAttaches = True\r\n\r\nIf ActualiserAttaches = True Then\r\n\u00a0\u00a0\u00a0 MsgBox \"Tables de la base de donn\u00e9es \" &amp; strCheminBd &amp; \" li\u00e9es avec succ\u00e9s\"\r\nEnd If\r\n\r\nExit Function\r\nActualiserAttaches_Err:\r\nMsgBox \"Error \" &amp; Err.Number &amp; \" (\" &amp; Err.Description &amp; _\r\n\") in Function ActualiserAttaches of Module mdFonctions\", vbCritical\r\nEnd Function<\/pre>\n<p>Ce code devrait donc vous permettre de r\u00e9aliser sans difficult\u00e9 la liaison automatique des tables au d\u00e9marrage de votre application. Il est bien s\u00fbr possible de ne faire l&rsquo;op\u00e9ration de liaison que lorsque celle-ci est n\u00e9cessaire, ce que j&rsquo;avais fait \u00e0 l&rsquo;\u00e9poque mais qui me levait des erreurs pour cet exemple et que j&rsquo;ai donc simplifi\u00e9, n&rsquo;ayant pas envie de d\u00e9bugger du VBA pendant des heures ;). Impl\u00e9menter la fonctionnalit\u00e9 en s&rsquo;inspirant de cet exemple devrait donc \u00eatre plut\u00f4t rapide.<\/p>\n<p>Il reste toutefois un peu de code \u00e0 \u00e9crire du c\u00f4t\u00e9 du formulaire d&rsquo;accueil. Celui-ci est relativement simple, \u00e0 noter tout de m\u00eame que l&rsquo;on consid\u00e8re que nos deux fichiers sont stock\u00e9s au m\u00eame endroit sur le disque pour la g\u00e9n\u00e9ration du chemin vers la base Data.<\/p>\n<pre>Option Compare Database\r\n\r\nPrivate Sub Form_Open(Cancel As Integer)\r\n' Permet de contr\u00f4ler la mise \u00e0 jour des tables\r\n\r\nDim strTemp As String\r\nDim strChemin As String\r\n\r\n\u00a0 'CHANGER LE NOM DE LA BASE DATA ICI\r\n\u00a0 strChemin = CurrentProject.Path &amp; \"\\EXEMPLE_DATA.accdb\"\r\n\r\n\u00a0 DeleteTables\r\n\r\n\u00a0 If ActualiserAttaches(strChemin) = True Then\r\n\u00a0   VerifAttach\r\n\r\n\u00a0 Else\r\n\r\n\u00a0   MsgBox \"Mise \u00e0 jour des Tables non \u00e9ffectu\u00e9es, \" &amp; vbCrLf &amp; _\r\n\u00a0\u00a0\u00a0   \"veuillez contacter l'administrateur de la base.\", vbCritical,\r\n     \u00a0\"Liaisons des tables\"\r\n\u00a0\u00a0\u00a0 'Fermeture de l'application\r\n\u00a0\u00a0\u00a0 DoCmd.Close\r\n\r\n\u00a0 End If\r\nEnd Sub<\/pre>\n<p>J&rsquo;esp\u00e8re que cet exemple sera utile au lecteur qui aura fait l&rsquo;effort de me lire jusqu&rsquo;au bout. Enfin, n&rsquo;h\u00e9sitez pas \u00e0 laisser une remarque, addition ou autre en commentaire.<\/p>\n<p>Zip contenant les fichiers d&rsquo;exemple: <a href=\"https:\/\/www.unicoda.com\/wp-content\/uploads\/2012\/11\/EXEMPLE.zip\">EXEMPLE.<\/a><\/p>\n<p>&nbsp;<\/p>\n<p>Articles int\u00e9ressants pour un projet Access:<br \/>\n<a href=\"http:\/\/cafeine.developpez.com\/access\/tutoriel\/photos\/\">Gestion de photos par formulaire<\/a><br \/>\n<a href=\"http:\/\/loufab.developpez.com\/tutoriels\/access\/splashscreen\/\">Splash-screen<\/a><br \/>\n<a href=\"http:\/\/dolphy35.developpez.com\/article\/access\/basesreseaux\/\">Mode Multi-Utilisateurs<\/a><\/p>\n<p>Note: Le module de liaison avait \u00e9t\u00e9 trouv\u00e9 sur le net, tr\u00e8s certainement sur developpez.com.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Je sais que j&rsquo;ai plut\u00f4t l&rsquo;habitude d&rsquo;\u00e9crire \u00e0 propos de logiciel libre, et que je pr\u00e9f\u00e8re aborder un point concernant GNU\/Linux que le syst\u00e8me privateur Windows et ses outils associ\u00e9s. Seulement parfois, un \u00e9tudiant en informatique n&rsquo;a pas le choix des technos \u00e0 utiliser pour r\u00e9aliser son projet et est contraint d&rsquo;utiliser des solutions privatrices. &hellip; <a href=\"https:\/\/www.unicoda.com\/?p=768\" class=\"more-link\">Continuer la lecture<span class=\"screen-reader-text\"> de &laquo;&nbsp;[Access]Gestion Auto de la Liaison des Tables&nbsp;&raquo;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[73,74,72,75],"class_list":["post-768","post","type-post","status-publish","format-standard","hentry","category-code","tag-access","tag-bdd","tag-liaison-auto","tag-vba"],"_links":{"self":[{"href":"https:\/\/www.unicoda.com\/index.php?rest_route=\/wp\/v2\/posts\/768","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.unicoda.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.unicoda.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.unicoda.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.unicoda.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=768"}],"version-history":[{"count":11,"href":"https:\/\/www.unicoda.com\/index.php?rest_route=\/wp\/v2\/posts\/768\/revisions"}],"predecessor-version":[{"id":3108,"href":"https:\/\/www.unicoda.com\/index.php?rest_route=\/wp\/v2\/posts\/768\/revisions\/3108"}],"wp:attachment":[{"href":"https:\/\/www.unicoda.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=768"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.unicoda.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=768"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.unicoda.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=768"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}