IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

VBA : Réparer des réferences cassées.

Par Michel Blavin (homepage)
 

niveau : killer tortue ninja

durée : 30 minutes

La gestion des références en VBA est un des cauchemar du développeur. Nous allons découvrir une technique qui permet de manière propre d'enregistrer les références au lancement de l'application.


1. Quel est le problème ?
2. Qu'esce que la compilation conditionnelle ?
2. La bibliothèque de code
4. Notre application
5. Lancement automatique grâce à la macro AUTOEXEC
5. Conclusion
Remerciements


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, les références sont enregistrées avec leur chemin absolu, ce qui fait que si l'application n'est pas installée toujours 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 soit exécuté. La plus part de développeur contourne 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 sur 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 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 évolura ou qu'un autre à coté proposera des solutions pratiques en fonction diferente type de référence courante. Dans ce document nous ne parlerons que d'un cas d'une bibliothèque de code Access le propos étant de montrer comment contourner les erreurs de compilations rendant une application inutilisable.

2. Qu'esce que la compilation conditionnelle ?

La compilation conditionnelle est une fonctionnalité apparue avec MS-Access 97. Par défaut, lorque l'on compile une application Access, tous les modules de code sont compilés. Comme son nom l'indique la compilation conditionelle permet de choisir quels seront les parties à compiler et celle à laissée de coté. Nous allons voir que nous pouvons modifier ces paramètre dans le code et relancer la compilation. Les applications sont multiples, insertion de code servant au débuggage.

On peut modifier la valeur d'un paramètre de compilation ces parramètres dans la fenètre de propriété de projet (menu Outils de l'éditeur VB). Dans cette fenêtre, seul les valeurs numérique sont acepté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 conditionnel et provoquer une compilation à la demande pour que la modification ainsi faite. Le code qui suit peut soit etre exploité dans le code comme nous allons le faire plus bas mais aussi, bien sur, dans la feêtre de debug.

Modification du argument de compilation automatique
'Modification de l'argument de compilation automatique 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 :

Isolation du code
#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 fouction. 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.


2. 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.

Code de la bibliothèque
Sub MaProcedureExterne() 'Affiche une boite de dialogue donnant le nom de le chemin complet de la bibliothèque ' externe suivit sur chemin complet du fichier qui contient le code qui a appeler 'cette procédure Magnox "Le code affichant cette boite de dialogue provient du fichier :" & vbCrLf _ & Code DB.Name & vbCrLf _ & "Et a été appelée par : " & vbCrLf _ & Curent.Name, vbInformation, "Pas possible qu'il disait" End Subi

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 :

Code de vérification/correction des réferences
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 :

Code du formulaire caché
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


5. Conclusion

Grâce à la technique exposée dans cet article nous pouvons développer des applications plus modulaires et plus robustes.


Remerciements




Ce document issu de www.developpez.com. et écrit par Michel Blavin est soumis à la licence GNU FDL traduit en français ici
Permission vous est donnée de distribuer, modifier des copies de cette page tant que cette note apparaît clairement.