[Access]Gestion Auto de la Liaison des Tables

Je sais que j’ai plutôt l’habitude d’écrire à propos de logiciel libre, et que je préfère aborder un point concernant GNU/Linux que le système privateur Windows et ses outils associés. Seulement parfois, un étudiant en informatique n’a pas le choix des technos à utiliser pour réaliser son projet et est contraint d’utiliser des solutions privatrices. Ce fut le cas sur un projet de base de données où le logiciel imposé était Access. Cet article va donc aborder un point précis qui m’avait demandé de nombreuses heures de recherche, essais, etc avant d’arriver à réaliser la fonctionnalité voulue. En espérant que ces informations pourront aider d’autres étudiants par la suite et leur feront gagner un peu de temps. Je vais donc aborder la mise en place d’un système de liaison automatique des tables dans Access.

Tout d’abord, il faut savoir que dans notre situation, nous possédons deux fichiers. L’un contient l’ensemble des tables de notre base de données, l’autre contient l’application les utilisant. Dans le fichier de l’application, il est nécessaire de réaliser la liaison avec les tables de notre base de données. Cette liaison peut être facilement réalisée à la main. Néanmoins, un problème se pose avec cette façon de faire. En effet, Access retient l’emplacement absolu de votre fichier de données depuis la racine du disque dur soit quelque chose comme C:\Utilisateurs\Public\MonProjet\data.mdb par exemple. Et c’est là que l’on commence à s’arracher les cheveux puisque si je déplace le dossier MonProjet, la liaison des tables continue de pointer vers C:\Utilisateurs\Public\MonProjet\data.mdb. L’horreur quand vous êtes amené à changer d’ordinateur. Il existe pourtant une solution qui consiste à vérifier l’attachement des tables à chaque lancement de l’application. Si le chemin est correct, pas de problème, sinon, on refait la liaison automatiquement en construisant nous même le chemin absolu jusqu’au fichier. Il faut noter que dans l’exemple que je vais développer, le formulaire de démarrage de l’application ne fait aucune requête vers la base de données, afin d’éviter des erreurs (bien qu’il doit être possible de faire ces requêtes seulement lorsque la liaison a été vérifié et est correcte).

Je crée donc un fichier Access qui contiendra ma base de donnée et le nomme EXEMPLE_DATA. Pour notre exemple, on y ajoute une table PERSONNES avec divers champs. Par ailleurs, il faut créer le fichier qui contiendra l’application EXEMPLE_APPLI. Maintenant que nous disposons de nos deux fichiers, nous allons pouvoir effectuer la première liaison des tables manuellement. Onglet External Data, icône Linked Table Manager. Une fois la liaison effectuée, nous ajoutons un bête formulaire d’accueil dans notre application. Celui-ci ne contient rien d’autre qu’un simple texte. Nous pouvons alors mettre en évidence notre problème, couper/coller votre fichier EXEMPLE_DATA dans un autre dossier que le dossier courant, ré-ouvrez EXEMPLE_APPLI, le fichier contenant les tables est maintenant introuvable. Nous allons donc y remédier en mettant en place la liaison automatique des tables à chaque démarrage de l’application. Il est bien sûr possible de mettre en place un système permettant de ne lier les tables que si le fichier de base de données est introuvable.

Dans notre application, nous allons donc ajouter le module suivant nommé liaison_auto qui contient les fonctions dont nous avons besoin pour la liaison. Enfin, à l’ouverture de notre formulaire d’accueil, nous appelons les fonctions qui vont bien.

Option Compare Database

Public Function VerifAttach() As Boolean
Dim tdf As DAO.TableDef, strTemp As Variant, strPath As String, i As Long
For Each tdf In CurrentDb.TableDefs
' Recherche d'une table liée
If tdf.Connect <> "" Then
strTemp = Split(tdf.Connect, ";")
For i = LBound(strTemp) To UBound(strTemp)
' Recherche du paramètre de connection
If strTemp(i) Like "DATABASE=*" Then
strPath = Split(strTemp(i), "=")(1)
' Vérification de l'existence de la bdd
If Dir(strPath) <> "" Then
VerifAttach = True
Exit Function
End If
End If
Next i
End If
Next
End Function

Public Sub DeleteTables()
' Supprimer toutes les tables attachées
On Error Resume Next
Dim db As DAO.Database 'Database to import
Dim tdf As DAO.TableDef
Dim arrTablename() As String, i As Long
ReDim arrTablename(0)
Set db = CurrentDb
' Répertorier les tables à supprimer
For Each tdf In db.TableDefs
If tdf.Connect <> "" Then
ReDim Preserve arrTablename(UBound(arrTablename) + 1)
arrTablename(UBound(arrTablename)) = tdf.Name
End If
Next
' Suppression
For i = LBound(arrTablename) To UBound(arrTablename)
db.TableDefs.Delete arrTablename(i)
Next i
Set db = Nothing
End Sub

Public Function ActualiserAttaches(ByVal strCheminBd As String, Optional ByVal strMotPasse As String = "") As Boolean
On Error GoTo ActualiserAttaches_Err
Dim tdf As DAO.TableDef

strSourceConnect = "MS Access;PWD=" & strMotPasse & ";DATABASE=" & strCheminBd
' Supprimer les tables avant tout
DeleteTables

'Permet de lier toutes les tables
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

'Définit la chaine de connexion permettant la liaison des tables
strConnect = "MS Access;pwd=" & strMotPasse & ";DATABASE=" & strCheminBd
'Instancie l'objet Database de la base courante
Set oDb = CurrentDb
'Instancie l'objet Database de la base protégée
Set oDbSource = DBEngine.OpenDatabase(strCheminBd, True, True, strConnect)

'Parcours l'ensemble des tables de la base de données protégée
'et stocke leur nom
For Each oTblSource In oDbSource.TableDefs
    'Ignore les tables system
    If (oTblSource.Attributes And dbSystemObject) = 0 Then
        strTemp = strTemp & oTblSource.Name & "|"
    End If
Next
'Ferme la base de données sources (impératif pour la liaison)
oDbSource.Close: Set oDbSource = Nothing
'Parcours le tableau de noms de tables
strNomsTables = Split(Left(strTemp, Len(strTemp) - 1), "|")
For i = 0 To UBound(strNomsTables)
  'Crée une nouvelle table dans la base de données courante
  Set oTbl = oDb.CreateTableDef(strNomsTables(i))
  'Lie les deux tables
  oTbl.Connect = strConnect
  oTbl.SourceTableName = strNomsTables(i)
  'Ajoute la table à la base de données
  oDb.TableDefs.Append oTbl
Next i

'Rafraichit la liste des tables
oDb.TableDefs.Refresh

ActualiserAttaches = True

If ActualiserAttaches = True Then
    MsgBox "Tables de la base de données " & strCheminBd & " liées avec succés"
End If

Exit Function
ActualiserAttaches_Err:
MsgBox "Error " & Err.Number & " (" & Err.Description & _
") in Function ActualiserAttaches of Module mdFonctions", vbCritical
End Function

Ce code devrait donc vous permettre de réaliser sans difficulté la liaison automatique des tables au démarrage de votre application. Il est bien sûr possible de ne faire l’opération de liaison que lorsque celle-ci est nécessaire, ce que j’avais fait à l’époque mais qui me levait des erreurs pour cet exemple et que j’ai donc simplifié, n’ayant pas envie de débugger du VBA pendant des heures ;). Implémenter la fonctionnalité en s’inspirant de cet exemple devrait donc être plutôt rapide.

Il reste toutefois un peu de code à écrire du côté du formulaire d’accueil. Celui-ci est relativement simple, à noter tout de même que l’on considère que nos deux fichiers sont stockés au même endroit sur le disque pour la génération du chemin vers la base Data.

Option Compare Database

Private Sub Form_Open(Cancel As Integer)
' Permet de contrôler la mise à jour des tables

Dim strTemp As String
Dim strChemin As String

  'CHANGER LE NOM DE LA BASE DATA ICI
  strChemin = CurrentProject.Path & "\EXEMPLE_DATA.accdb"

  DeleteTables

  If ActualiserAttaches(strChemin) = True Then
    VerifAttach

  Else

    MsgBox "Mise à jour des Tables non éffectuées, " & vbCrLf & _
      "veuillez contacter l'administrateur de la base.", vbCritical,
      "Liaisons des tables"
    'Fermeture de l'application
    DoCmd.Close

  End If
End Sub

J’espère que cet exemple sera utile au lecteur qui aura fait l’effort de me lire jusqu’au bout. Enfin, n’hésitez pas à laisser une remarque, addition ou autre en commentaire.

Zip contenant les fichiers d’exemple: EXEMPLE.

 

Articles intéressants pour un projet Access:
Gestion de photos par formulaire
Splash-screen
Mode Multi-Utilisateurs

Note: Le module de liaison avait été trouvé sur le net, très certainement sur developpez.com.

Une présentation qui sort de l’ordinaire

Jusqu’à présent, les quelques présentations que j’ai eu l’occasion de faire se limitaient à de simples powerpoints. Mais si ce mode de présentation fonctionne relativement bien avec de la mise en page d’idées, le parcours de schéma n’est pas indiqué. En fait, il est peut-être possible de s’en sortir, mais je n’en sais pas plus à ce sujet.

Ce qui m’intéresse beaucoup plus, ce sont les possibilités de faire des présentations dynamiques et originales avec des outils libres bien sûr. J’ai donc découvert Impress.js qui semble être un moyen intéressant quoiqu’un peu technique de créer une présentation. Néanmoins, ayant besoin de créer un schéma, j’ai préféré laissé cette solution de côté pour me tourner vers Inkscape.

Pourquoi Inkscape me direz-vous. Eh bien, l’idée d’utiliser ce logiciel libre pour réaliser ma présentation me vient de René Méroux avec qui j’ai pu discuter  lors des éditions 2011 et 2012 des RMLL. Dans la présentation qu’il a effectué concernant sa carte du logiciel libre, René présentait en effet la version 6-alpha. C’est là que j’ai découvert la possibilité de faire une présentation en utilisant Inkscape. Cette version de la carte donne d’ailleurs un bon aperçu de ce qu’il est possible de faire. Vous trouverez la carte dans un grand nombre de langues sur le serveur suivant: http://es.gnu.org/~reneme/fsmap/ .

Revenons donc à Inkscape. Pour réaliser la présentation, il est nécessaire d’ajouter une extension appelée Sozi. On réalise donc en premier lieu son schéma, sa présentation avec les outils d’Inkscape, en appréciant bien la puissance du dessin vectoriel qui permet de redimensionner facilement tous les objets graphiques. Une fois cette étape terminée, nous allons dessiner un rectangle correspondant à la première image, le premier slide de notre présentation. Il suffit ensuite d’aller dans le menu Extensions puis Sozi. Lorsque la fenêtre de Sozi s’ouvre, cliquer sur Créer, l’élément SVG sélectionné correspond au rectangle qui vient d’être créer. Modifier les options à votre goût puis valider. Il suffit ensuite de créer un nouveau rectangle pour délimiter votre deuxième image, refaire la procédure via Sozi et ainsi de suite jusqu’à ce que vous soyez satisfait. Pour visualiser sa création, il suffit d’enregistrer son travail et d’ouvrir le fichier avec un navigateur récent, Firefox faisant très bien l’affaire. La navigation s’effectue au choix avec la souris ou via les flèches droite et gauche du clavier.

Voilà donc un moyen de créer une présentation originale en bénéficiant de la puissance du dessin vectoriel, mais qui nécessite un peu plus de temps pour prendre en main le logiciel. L’installation de Sozi est très bien décrite sur le site de l’extension et ne devrait pas poser de problème. Une expérience intéressante donc, qui donne envie d’utiliser plus souvent Inkscape, avec à la clé un résultat concluant.

Le fond de cet exemple tiré du site de Sozi étant transparent, l’animation n’est pas très visible sur ce fond gris, mais reste lisible.

[Vidéo] Azureus Rising

Magnifique court-métrage mettant en scène un mystérieux guerrier dans un univers de science-fiction. Ce proof-of-concept de 2010 a été récompensé à de nombreuses reprises et devait/devrait servir de base pour la création d’un film et d’un jeu vidéo « de nouvelle génération ».

Découvrez Azureus Rising:

Lien vers « Azureus Rising – Proof of Concept Teaser Trailer »

Mocha: path to mocha.opts with -f

Mocha is a wonderful (:D) test framework which allows you to write really understandable tests in JavaScript. I’ve already introduced it in a previous article, so today I’ll focus on a pull request I’ve proposed.

Like other programs, you can pass arguments to mocha, like for instance –reporter used to specified a way to display test results. By the way, you should try once the nyan reporter. Concerning mocha, it’s also possible to set arguments in a file named « mocha.opts ». Interesting feature, but the file must absolutely be stored in your test directory.

So the idea is to add an argument: -f, –fileconf <path>. Furthermore, the –fileconf option allows you to specify the configuration file that will be used, by default “/test/mocha.opts”; allowing you to store your configuration file anywhere you wanted. This modification is very useful if you make tests using the same configuration file in many directories. Without –fileconf, you have to copy your file in each directory, and even a small modification must be done on each file. Using -f, you store the mocha.opts file in a unique place, so that any modifications of the file would immediatly impact all tests.

About the code

Add the parameter with commander:

.option('-f,--config <path>','specify the path to configuration file')

Load the file using commander to parse the command line:

//-f, --config
program.parse(process.argv);
var pathConf = 'test/mocha.opts';
if (program.config && exists(program.config)) {
  pathConf = program.config;
}
try {
  var opts = fs.readFileSync(pathConf, 'utf8')
    .trim()
    .split(/\s+/);

  process.argv = process.argv
    .slice(0, 2)
    .concat(opts.concat(process.argv.slice(2)));
} catch (err) {
  // ignore
}

In fact, this code is not available in mocha yet since « parsing twice might have some strange side-effects »…

An other way to augment argv without using commander:

//-f, --config

var pathConf = 'test/mocha.opts'
  , fIndex = process.argv.indexOf('-f')
  , configIndex = process.argv.indexOf('--config');

if(fIndex !== -1 && exists(process.argv[fIndex + 1]) ) {
  pathConf = process.argv[fIndex + 1];
}

if(configIndex !== -1 && exists(process.argv[configIndex + 1]) ) {
  pathConf = process.argv[configIndex + 1];
}

And I’ll finished this article by quoting visionmedia:

Maybe it’s ok but that’s still pretty hacky.

[Vidéo] The League of Steam

Tout le monde connaît les célèbres Gosthbusters, dotés d’un matériel de pointe dans une Amérique moderne. Il est donc temps de changer d’époque, d’espace temps même, puisque les vidéos de The League of Steam se situe dans « l’époque » SteamPunk. Cette confrérie de chasseur de fantômes et autres manifestations surnaturelles dispose néanmoins de nombreux appareils divers et variés. Il ne recule devant rien… ou presque.

The League of Steam a terminé sa deuxième « saison » de vidéo et une troisième série est d’ores et déjà prévue. Les dialogues sont bien sûr en anglais, mais cela n’empêche en rien de suivre avec plaisir les mésaventures du groupe. Les différents épisodes peuvent pour la plupart être visionnés indépendamment les uns des autres. Le mieux reste de les prendre dans l’ordre chronologique de diffusion.

Voici l’un de mes épisodes préférés de la saison 1.
Direction l’Irlande avec ses créatures fantastiques, et sa musique.

Lien vers «  »Fool’s Gold » – Adventures of the League of STEAM »