Introduction▲
Il y quelques temps une idée saugrenue est sortie de mon cerveau malade. Je pense qu'elle
pourra être utile à certains d'entre vous, je vais donc l'exposer ici.
Vous pouvez télécharger
une base exemple accompagnée de la bibliothèque de code. Décompresser l'archive et lancer le fichier appli.mdb.
Au démarrage, l'application va enregistré la bibliothèque codebibli.mdb qui doit se trouver dans le
même répertoire, et lancer l'exécution d'un code dans cette bibliothèque. Dans le code,
j'ai fait un usage intensif de la sortie de deug, n'hésitez pas à y jeter un coup d'œil.
1. Quel est le problème ? ▲
Le développement d'applications modulaires permet un développement plus
rapide et une maintenance plus aisée des applications. Malheureusement,
dans Access, les références sont enregistrées avec leur chemin absolu, ce qui fait que
si l'application n'est pas toujours installée dans le même répertoire
elle ne fonctionnera plus et il faudra supprimer manuellement
les références et les réenregistrer de la même manière, inacceptable !
Il n'est pas toujours possible
d'imposer le répertoire dans lequel l'application sera installée,
souvent ces fichiers devront se trouver dans le répertoire personnel, qui
dépend de l'utilisateur. On ne peut pas non plus
enregistrer les références par code au démarrage puisque toute exécution
de code provoquera une erreur avant même que la première ligne de code ne
soit exécutée. La plupart des développeurs contournent le problème en important
tout le code dans le fichier principal. Cette solution n'est pas
satisfaisante, elle rend la maintenance bien trop complexe. En effet, lorsque
vous mettez à jour un morceau de code dans une de vos applications vous devez
reporter ces modifications dans toutes vos applications, avec les oublis qui
se produiront inévitablement. Vous ne serez jamais sûr que vous utilisez bien
la dernière version de votre code.
Récapitulons, si le code contenant un appel vers une
bibliothèque externe est compilé alors plus rien ne fonctionne. La solution ?
Empêcher que le code contenant des appels à des bibliothèques
externes ne soit compilé tant que l'on n'a pas vérifié et, si nécessaire, corrigé,
les références. Pour cela nous allons utiliser une fonctionnalité
intéressante et peu connue : la compilation conditionnelle.
Le but de cet article est de montrer qu'il est possible d'enregistrer une référence au lancement d'une application, pas de fournir une solution clé en main. Je pense que cet article évoluera ou qu'un autre proposera des solutions pratiques propre aux références les plus courantes. Nous ne parlerons que du cas d'une bibliothèque de code Access le propos étant de montrer comment contourner les erreurs de compilations rendant une application inutilisable, et non pas de rentrer dans les détails d'implémentation qui brouilleraient le propos.
2. Qu'est-ce que la compilation conditionnelle ? ▲
La compilation conditionnelle est une fonctionnalité apparue avec MS-Access 97. Par défaut, lorsque l'on compile une application Access, tous les modules de code sont compilés. Comme son nom l'indique la compilation conditionnelle permet de choisir quels seront les parties à compiler et celle à laissée de coté. Nous allons voir que nous pouvons modifier ces paramètres dans le code et relancer la compilation en cours d"exécution. Les applications sont multiples :
- insertion de code servant au débogage
- déploiement de plusieurs version d'une application
- etc.
On peut modifier la valeur d'un paramètre de compilation ces paramètres dans la fenêtre de propriété de projet (menu Outils de l'éditeur VB). Dans cette fenêtre, seules les valeurs numériques sont acceptées (O pour faux et toutes les autres valeurs pour vrai).
Pour que cette fonctionnalité nous serve il faut que nous puissions, modifier l'argument de compilation conditionnelle et provoquer une compilation à la demande pour que la modification ainsi faite soit prise en compte. Le code qui suit peut soit être exploité dans le code comme nous allons le faire plus bas mais aussi, bien sûr, dans la fenêtre de débogage.
'Modification de l'argument de compilation conditionelle
Application.SetOption
"Conditional Compilation Arguments"
, "AcceptLibraryCode = true"
'Recompilation et enregistremnt du code
RunCommand acCmdCompileAndSaveAllModules
Les modifications ainsi faites sont visibles dans la fenêtre de propriétés de l'application. Une fois notre argument (ou nos arguments) défini(s) nous encadrons les blocs de codes que l'on veut isoler de la manière suivante :
#If MonArgument then
' Je place ici le code que je veux ne compiler qu'à certaine condition
' dans notre cas tous les appels vers des bibliothèques externes
#ElseIf UnAutreArgument Then
....
#Else
'dans tous les autres cas
#End If
Ces instructions de branchement, agissant au niveau de la compilation, peuvent se trouver n'importe ou dans le code, il n'est pas nécessaire qu'ils se trouvent à l'intérieur d'une procédure ou fonction. Nous verrons plus bas qu'il est possible d'isoler un module entier en une seule fois. Maintenant que nous avons les connaissances nous permettant de faire ce que l'on veut, voyons comment les exploiter.
3. La bibliothèque de code▲
Nous allons créer une nouvelle base de données, appelons la Codebibli.md, et insérons le code suivant dans un module de code.
4. Notre application▲
Maintenant, créons une deuxième base qui figurera notre application. Nous l'enregistrerons sous le nom de Appli.md. Insérons le code suivant dans un module de code :
Function
EnregistreReferences
(
)
Dim
strLibraryName As
String
Dim
strLibraryPath As
String
Dim
strLibraryRelativePath As
String
Dim
ref As
Reference
On
Error
GoTo
MajReference_Error
strLibraryName =
"CodeBibli"
strLibraryRelativePath =
"\"
strLibraryPath =
CurrentProject.Path
&
strLibraryRelativePath &
strLibraryName &
".mdb "
Debug.Print
"Enregistrement de la référence : "
&
strLibraryPath
Application.References.AddFromFile
strLibraryPath
Debug.Print
"AcceptLibraryCode = 1 "
Application.SetOption
"Conditional Compilation Arguments"
, "AcceptLibraryCode = true"
Debug.Print
"Recompilation de l'application"
RunCommand acCmdCompileAndSaveAllModules
Debug.Print
"maintenant je peut utiliser ma bibliothèque"
ToiTuSors
:
Set
ref =
Nothing
Exit
Function
MajReference_Error
:
Select
Case
Err
.Number
Case
29060
'Fichier non trouvé
Debug.Print
"Echec de l'enregistrement ! :("
MsgBox
"Le Fichier : "
&
strLibraryPath &
" est introuvable"
Case
32813
' bibliothèque existante
Debug.Print
"la réference exite deja"
For
Each
ref In
Application.References
If
ref.Name
=
strLibraryName And
ref.IsBroken
Then
Debug.Print
"elle est cassée on la supprime"
Application.References.Remove
ref
Debug.Print
"et on relance l'ajout"
Resume
Else
Debug.Print
"elle est pas cassé, alors on saute l'enregistrement"
Resume
Next
End
If
Next
ref
Case
Else
' default message, handy to find where the problem happened.
MsgBox
"Error "
&
Err
.Number
&
" ("
&
Err
.Description
&
")"
_
&
" in procedure MajReference of Module basEnregistrementBibli"
End
Select
Resume
ToiTuSors
End
Function
Maintenant créons un formulaire sur lequel sur lequel on ne mettra aucun contrôle puisqu''il sera caché, et un contrôle caché c'est gâché :). Insérons le code suivant le code suivant sur l'événement chargement :
Private
Sub
Form_Load
(
)
#If AcceptLibraryCode Then
'ici je peux appeler du code de ma bibliothèque
MaProcedureExterne
#End If
End
Sub
Private
Sub
Form_Unload
(
Cancel As
Integer
)
'A la fermeture du formulaire on remet en place la compilation conditionnel pour
' qu'à la prochaine ouverture le contrôle de dépendances soit à nouveau. Cela autorise
' de déplacer l'application dans un autre répertoire sans cassé les références.
Debug.Print
"AcceptLibraryCode = False"
Application.SetOption
"Conditional Compilation Arguments"
, "AcceptLibraryCode = False"
Debug.Print
"Recompilation de l'application"
RunCommand acCmdCompileAndSaveAllModules
End
Sub
5. Lancement automatique grâce à la macro AUTOEXEC▲
La macro AUTOEXEC se lance automatiquement au démarrage de l'application elle a l'avantage de permettre de lancé un formulaire masqué. Ce formulaire permet de remettre l'argument de compilation à False à la fermeture de l'application. Cela n'est pas obligatoire vous pouvez considérer qu'un fois que les références on été contrôler
6. Conclusion▲
Grâce à la technique exposée dans cet article nous pouvons développer des applications plus modulaires et donc plus robustes.
Remerciements▲
Merci à toute l'équipe de developpez.com et en particulier aux corecteurs de cet article Papy turbo et Maxence Hubiche pour leur remarque constructive, qui ont eu une influence relative ;).