VBA : Enregistrement des références.

La gestion des références en VBA est un des cauchemar du développeur. Je vais vous faire découvrir une technique qui permet de d'enregistrer proprement les références au lancement de l'application.

Article lu   fois.

L'auteur

Site personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

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 du argument de compilation automatiquement
Sélectionnez

'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 :

Isolation du code
Sélectionnez

#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 :

Code de vérification/correction des réferences
Sélectionnez

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é
Sélectionnez


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 ;).

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

Access :
Introduction aux modules de classes
Enregistrement des références au démarage.
Formulaire calendrier en pop-up
blogs
Mon blog

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.