Mettre en place un gestionnaire de rafraîchissement automatique des tables

Jean-Philippe AMBROSINO

Ce document a pour but de vous montrer comment d'un seul coup d'œil, les données de vos tables sont actualisées automatiquement selon une temporisation prédéfinie. Cet article est plutôt destiné aux développeurs qui souhaitent contrôler en phase de recette utilisateur notamment, la mise à jour de tables de façon automatique tout en exécutant certaines procédures au pas à pas.

Commentez ♪

- Titre : Mettre en place un gestionnaire de rafraîchissement automatique des tables

- Auteur : Jean-Philippe AMBROSINO

- Parution : 9 octobre 2009

- Mise à jour : 9 octobre 2009

- Licence : Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.

Sommaire

- I. Avant-propos

- I-A. Remerciements

- I-B. Contact

- II. Présentation du projet

- II-A. Comment se présente cet automatisme ?

- II-B. Comment fonctionne ce formulaire ?

- III. Création du formulaire

- III-A. Création du formulaire à partir de la table

- III-B. Description du module de classe clsAutoRefresh

- III-B-1. La procédure FormDblClick

- III-B-2. La procédure FormOnLoad

- III-B-3. La procédure FormOnTimer

- III-B-4. Le code du module de classe

- III-B-5. Mise en place du code pour le formulaire

- III-C. Le code événementiel associé au formulaire

- III-D. Duplication du code dans les autres formulaires

- IV. Problème matériel

- V. Conclusion

- VI. Remerciements

I - Avant-propos

Lorsque l'on développe une application sous Access en mode Frontal/Dorsal (recommandé), il est parfois contraignant de ne pas pouvoir visualiser le contenu des tables en temps réel lorsque celles-ci subissent des mouvements d'opérations d'ajout, mise à jour ou suppression sur les enregistrements.
Aussi, lorsque plusieurs tables sont ouvertes en même temps, il vous appartient alors d'aller rafraîchir leur contenu une par une ce qui est loin d'être pratique surtout quand vous avez plusieurs tables à surveiller.

Cela a été mon cas et j'ai eu donc, après quelques-unes de ces contraintes, l'idée de mettre en place quelque chose qui automatise cette tâche.

À l'accoutumée, je travaille sur deux écrans reliés à mon poste de développement où l'un est réservé à l'interface graphique et l'autre à VBE. Dans la situation actuelle, je possède un second ordinateur qui est un poste de test configuré comme un poste utilisateur final dans l'entreprise.
Avant de m'en servir comme poste de recette, je l'ai condamné en serveur de fichiers où j'ai donc ouvert la base de données dorsale pour y contrôler certaines tables nécessitant une surveillance particulière.

L'application concernée traitant des données stratégiques pour l'entreprise, c'est ce poste qui me permettra de contrôler ces cinq tables tout en ayant un regard sur le code.

Situation de travail:
- l'écran de gauche affiche l'interface graphique ;
- l'écran du centre, Visual Basic Editor en mode débogage ;
- l'écran de droite, la base de données dorsale avec les cinq tables ouvertes.

Situation de travail

Je dois vous préciser - et certains d'entre-vous l'avez peut-être vécu aussi - que de contrôler le comportement du code, l'examen des variables locales via l'espion, le bon fonctionnement des gestions d'erreurs, etc., et en même temps, basculer sur l'autre session d'Access contenant votre base dorsale et d'y actualiser les tables pour voir si les données sont valides et correctement insérées peut faire perdre la main et « entre guillemets », faire louper un passage prépondérant : le projet concerné qui fait appel à OLE Automation et le fait d'appuyer sur ALT+TAB pour basculer sur une autre fenêtre peut générer des comportements inattendus lorsque l'on revient sur le code en cours en regard d'une exécution en mode, disons normal.

Dans ce cas précis, j'ai, à plusieurs reprises, eu le message de dialogue fatal avec le bouton « Basculer vers… » qui me bloquait et par voie de conséquence, m'obligeait à recommencer certaines étapes. Sa présence aléatoire était surtout provoquée lorsque la DLL ActiveX maison en référence était elle aussi en mode DEBUG sous l'environnement de développement VB6.
En ayant mis en place cette routine d'automatisation, j'ai en quelque sorte supprimé cette contrainte et ai confortabilisé grandement la phase de mise en recette de mon projet.

Ce tutoriel est expliqué et illustré sur une base de données Access 2003

Pour le mettre en œuvre sur d'autres versions, des adaptations seront peut-être nécessaires.

I-A - Remerciements

Je tiens à remercier tout particulièrement toutes celles et tous ceux qui ont participé à la relecture de ce document en y incluant leurs remarques.

I-B - Contact

Pour tout renseignement complémentaire, veuillez me contacter directement (Argyronet) par MP.

II - Présentation du projet

Il ne s'agit pas d'un projet à part entière puisque la mise en place de cet automatisme s'effectue sur la base dorsale côté serveur et non sur la base frontale.
Bien entendu, il sera conseillé de supprimer cet automatisme si vous jugez qu'il n'aura plus à être utilisé.

Néanmoins, cette suppression n'est pas indispensable du fait que les objets exploitant ce dernier n'interagissent pas sur le fonctionnement de la base de données elle-même. De plus, si vous deviez faire évoluer votre projet, il peut être intéressant de pouvoir à nouveau en bénéficier.

II-A - Comment se présente cet automatisme ?

La mise en œuvre de cet automatisme est toute simple et ne requiert que très peu de code.

Il se présente par la mise en place d'un Module de classe du fait que l'on a besoin de l'instancier pour autant de tables que nécessaire.
Chaque table à surveiller n'est en fait pas vraiment une table, mais un formulaire en mode Feuille de données qui est le reflet exact de la table à surveiller.

En effet, il n'est pas possible de déclencher des événements sur un objet de type Table.

Il sera certainement nécessaire de masquer certaines colonnes superflues pour l'examen des données qu'elles doivent recevoir.

Un formulaire avec rafraîchissement automatisé

Comme vous pouvez le voir ci-dessus, la table/formulaire affichée possède un titre représentant son nom (celui de la table source qui est le nom d'objet affecté par défaut) et juxtaposé, le temps restant avant le prochain rafraîchissement.

Rappel sur la méthode Requery

C'est effectivement cette méthode qui est employée pour rafraîchir les enregistrements de la table.

La méthode Requery met à jour les données sous-jacentes d'un formulaire ou d'un contrôle de manière à tenir compte des nouveaux enregistrements de la source d'enregistrements ou des enregistrements supprimés depuis la dernière interrogation.

§ Extrait de l'aide de Microsoft Access- La méthode Requery exécute à nouveau la requête à partir de laquelle le formulaire ou le contrôle a été créé.
- Elle affiche tous les enregistrements nouveaux ou modifiés ou retire les enregistrements supprimés de la table à partir de laquelle le formulaire ou le contrôle a été créé.
- Elle met à jour les enregistrements affichés en fonction des changements apportés à la propriété Filter du formulaire.

La méthode Requery (Syntaxe)

expression.Requery(NomContrôle)

Quelques exemples.

La méthode Requery (Exemple)

Docmd.Requery
'ou
MyComboBox.Requery
'ou
Me.Requery

La méthode Requery ne passe pas le relais au système d'exploitation dans le but que Windows continue à traiter d'autres tâches.

Si vous souhaitez passer temporairement la main au système d'exploitation, vous devez utiliser la fonction DoEvents.

La méthode Requery est plus rapide que l'action Actualiser.

Avec l'action Actualiser, Microsoft Access ferme la requête et la recharge à partir de la base de données.

Avec la méthode Requery, Microsoft Access exécute à nouveau la requête sans la fermer ni la recharger.

II-B - Comment fonctionne ce formulaire ?

Ce formulaire initialise des propriétés au chargement (Load) puis exploite son événement Timer pour rafraîchir les données qu'il contient.

Un intervalle de 16 secondes est défini par défaut pour que la méthode Requery soit appelée de nouveau.
La routine déclenchée par l'événement Timer exploite une variable statique pour effectuer ce décompte.

III - Création du formulaire

La création du formulaire est on ne peut plus simple.

III-A - Création du formulaire à partir de la table

Étape N° 1

Vous avez plusieurs solutions pour créer le formulaire.

Pour les chevronnés, créez donc un formulaire en mode Feuille de données, provoquez-lui le code événementiel par défaut et passez directement à l'étape N° 2.

Pour les autres, sélectionnez la table concernée et usez donc de l'Assistant formulaire.

Sachez qu'aucune mise en forme, si ce n'est la redimension et le masquage de certaines colonnes, n'est nécessaire.

Pour créer le premier formulaire, sélectionnez alors la table depuis la fenêtre Base de données.

Cliquez alors sur la barre d'outils « Base de données » et dérouler le menu-bouton Nouvel objet : Formulaire automatique.

Choisissez alors la rubrique Formulaire comme indiqué ci-dessous.

Création du formulaire à partir de la table

Dès que la fenêtre de l'assistant s'affiche, cliquez sur Formulaire instantané : feuille de données et cliquez sur OK ou bien double-cliquez sur cette rubrique.

Sélection du type de formulaire

Un très bref instant suffit à afficher le formulaire dans le mode souhaité.

Le formulaire créé en mode feuille de données

Enregistrez-le donc sous son nom par défaut, à savoir, celui de la table source puis passez immédiatement en Mode création.

Passage en mode création

Depuis la barre d'outils « Création de formulaires », cliquez sur le bouton « Code » en sélectionnant « Procédure événementielle » si toutefois vous n'avez pas défini cette option par défaut dans les options d'Access.

Ouvrir l'éditeur VBE

L'éditeur Visual Basic fait alors son apparition avec une feuille vierge.
(Ou du moins, pourvue de l'option Option Compare Database et peut-être Option Explicit si vous avez coché l'option idoine dans les préférences de l'éditeur VBE.)

Définir les préférences dans l'éditeur VBE

Étape N° 2

Dans l'interface VBE et depuis le menu Insertion, ajoutez un Module de classe.

Ajout d'un module de classe au projet

puis nommez-le « clsAutoRefresh ».

Dans la nouvelle feuille de ce module, vous allez ajouter :
- 2 propriétés publiques ;
- 3 procédures Sub(), publiques également.

Les deux propriétés sont dédiées à définir pour l'une le titre de la fenêtre du formulaire en récupérant sa propriété Caption et l'autre de type Integer déterminera le déclenchement du Timer par une valeur comprise entre 0 (Disabled) et 1000 (1 seconde et Enabled).

Vous définirez ces propriétés en Lecture/Écriture et les nommerez respectivement :
- p_strFormCaption ;
- p_intTimerInterval.

Les trois procédures publiques à ajouter seront nommées :
- FormDblClick ;
- FormOnLoad ;
- FormOnTimer.

Comme vous pouvez sans doute le remarquer, les noms de ces procédures ne vous sont pas inconnus.
Ils portent en effet le nom respectif de chaque événement en regard dans le formulaire à savoir, respectivement :
Form_DblClick(), Form_Load() et Form_Timer().

III-B - Description du module de classe clsAutoRefresh

Les propriétés exploitent deux variables privées locales portant un nom identique hormis le préfixe « m » qui détermine leur appartenance à un module comme le veulent les conventions typographiques du code VB.

III-B-1 - La procédure FormDblClick

Cette procédure est appelée lorsque l'utilisateur effectue un double clic sur la zone externe à la feuille de données.
Son rôle se limite à pouvoir arrêter ou reprendre le cycle Timer afin d'interrompre temporairement le rafraîchissement du formulaire.

Cette procédure prend et alimente la valeur de la propriété p_intTimerInterval.
Si sa valeur est différente de 0 donc égale à 1000, alors elle devient égale à 0 et l'intitulé de la fenêtre change pour afficher le fait que le rafraîchissement est en cours.
Sinon, elle prend la valeur de 1000 et affecte la propriété TimerInterval du formulaire passé en paramètre.

III-B-2 - La procédure FormOnLoad

Cette procédure est appelée lors du chargement du formulaire.
Dans cette dernière, les propriétés p_strFormCaption et p_intTimerInterval prennent respectivement les valeurs de la propriété Caption du formulaire et la valeur de 1000 pour affecter un intervalle d'une seconde à l'événement Timer.

III-B-3 - La procédure FormOnTimer

Cette procédure calcule le temps restant par rapport au paramètre ResetTime défini par défaut à 16 secondes.

Vous pouvez bien entendu définir la valeur de votre choix ici.

La variable statique S s'incrémente de 1 à chaque appel de cet événement soit pendant seize secondes puis recommence.

La variable locale D se décrémente de la différence restant entre la valeur de ResetTime et celle de S ce qui permet en outre d'alimenter le titre de la fenêtre du formulaire dynamiquement avec ce temps restant.

Formulaire temporisé

Pendant la décrémentation de la valeur de la variable statique S, la propriété Caption se voit affectée de sa valeur d'origine, à savoir le nom du formulaire défini lors du chargement (Form_Load), concaténée au temps restant ou au message du rafraîchissement imminent selon le cas.

La méthode Requery est alors appelée et les données sont rafraîchies aussitôt.

III-B-4 - Le code du module de classe

Recopiez l'intégralité de ce bloc de code dans le module de classe et enregistrez votre projet :

Le code du module de classe

Option Compare Database
Option Explicit

'**********************************************************************
' Module            : clsAutoRefresh
' Type              : Module de classe
' DateTime          : 10/10/2009
' Author            : Jean-Philippe AMBROSINO
' Purpose           : Classe dédiée au rafraîchissement automatique des données
'**********************************************************************
Option Compare Database
Option Explicit

Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Private m_intTimerInterval                             As Integer
Private m_strFormCaption                              As String

' Propriété de valeur du Timer
Public Property Get p_intTimerInterval() As Integer
p_intTimerInterval = m_intTimerInterval
End Property

Public Property Let p_intTimerInterval(ByVal ip_intTimerInterval As Integer)
m_intTimerInterval = ip_intTimerInterval
End Property

' Propriété de la légende du formulaire
Public Property Get p_strFormCaption() As String
p_strFormCaption = m_strFormCaption
End Property

Public Property Let p_strFormCaption(ByVal sp_strFormCaption As String)
m_strFormCaption = sp_strFormCaption
End Property

' Événement DoubleClick du formulaire (Zone grisée)
Public Sub FormDblClick(ByRef TargetForm As Form, Cancel As Integer)
If p_intTimerInterval Then
p_intTimerInterval = 0
TargetForm.Caption = p_strFormCaption & " (Rafraîchissement stoppé : Pressez un double-clic pour le relancer...)"
Else
p_intTimerInterval = 1000
End If
TargetForm.TimerInterval = p_intTimerInterval
End Sub

' Événement Load du formulaire
Public Sub FormOnLoad(ByRef TargetForm As Form)
p_strFormCaption = TargetForm.Caption
TargetForm.TimerInterval = 1000
End Sub

' Événement Timer du formulaire
Public Sub FormOnTimer(ByRef TargetForm As Form, Optional ByVal ResetTime As Integer = 16)
Dim D                                                  As Integer
Static S                                               As Integer

If S = ResetTime Then
S = 0: D = 0
TargetForm.Caption = "Rafraîchissement imminent...."
Sleep 1000
DoEvents
TargetForm.Requery
End If

S = S + 1
D = ResetTime - S
DoEvents
TargetForm.Caption = p_strFormCaption & " : Rafraîchissement des données dans " & D & " seconde" & IIf(D <= 1, "", "s")
End Sub

III-B-5 - Mise en place du code pour le formulaire

Une fois cela fait, vous allez maintenant enrichir le module de classe du formulaire concerné.

Normalement et si vous avez bien suivi le déroulement de ce tutoriel, vous devez pouvoir accéder à cette classe depuis VBE.

Passage à la classe du formulaire

Ici, vous allez donc gérer les événements correspondants comme expliqués ci-après.

III-C - Le code événementiel associé au formulaire

Comme vu ci-avant, vous allez appliquer le code de l'objet Form pour chacun des événements Load(), DblClick() et Timer().

Le code de chacun des événements est très simple puisqu'il suffit d'appliquer la procédure du même nom avec les paramètres idoines à partir de la variable objet mc_AutoRefresh :

Code de la classe du formulaire

'**********************************************************************
' Module            : TBL_ExcelFileData (DataSheetForm)
' Type              : Document VBA
' DateTime          : 09/10/2009
' Author            : Jean-Philippe AMBROSINO
' Purpose           : Formulaire contenant les importations temporaires Excel
'**********************************************************************
Option Compare Database
Option Explicit

Private mc_AutoRefresh As clsAutoRefresh

Private Sub Form_Close()
Set mc_AutoRefresh = Nothing
End Sub

Private Sub Form_DblClick(Cancel As Integer)
mc_AutoRefresh.FormDblClick Me, Cancel
End Sub

Private Sub Form_Load()
Set mc_AutoRefresh = New clsAutoRefresh
With mc_AutoRefresh
.p_strFormCaption = Me.Caption
.p_intTimerInterval = 1000
Me.TimerInterval = .p_intTimerInterval
End With
End Sub

Private Sub Form_Timer()
mc_AutoRefresh.FormOnTimer Me
End Sub

Dans l'en-tête du module, vous déclarez une variable objet qui va servir à instancier la classe précédemment créée. Vous nommez cette variable mc_AutoRefresh.
C'est l'événement Load() qui va attribuer la référence à cette variable par le biais de l'instruction Set et du mot clé New qui lui, va créer une nouvelle instance de la classe.

La variable de module se voit mettre sa valeur à néant par le biais de Nothing lors de la fermeture du formulaire.

III-D - Duplication du code dans les autres formulaires

Pour appliquer le même effet de rafraîchissement à d'autres formulaires, créez les autres formulaires avec le même mode, à savoir « Feuille de données ».
Recopiez alors le code de la classe du précédent formulaire dans celle de chacun des autres formulaires.

Il n'est pas nécessaire de passer par la fenêtre de Propriétés du formulaire pour affecter chacun des événements.

Le fait de coller le code correctement écrit affecte automatiquement les événements sollicités à savoir, Load(), DoubleClick() et Timer().

Enregistrez le tout et par acquit de conscience, cliquez sur le menu Debogage puis sur la rubrique Compiler <Votre projet> afin de vous assurer que vous n'avez rien omis.

C'est terminé ; vous pouvez appuyer sur la touche F5 depuis la fenêtre principale d'Access afin d'ouvrir chaque formulaire.
Cliquez ensuite sur le menu Fenêtre puis sur Mosaïque horizontale pour les ranger.

Les 5 formulaires ouverts et temporisés

Il est tout à fait envisageable d'automatiser l'ouverture et l'arrangement des fenêtres concernées, mais du fait que ce processus reste pour ma part temporaire d'une part et que sa mise en place ait lieu dans la base de données dorsale, je n'ai pas été dans ce sens considérant aussi que cela reste très accessible à tous.

IV - Problème matériel

Je vais terminer ce tutoriel en évoquant le problème matériel auquel vous pourriez être confronté ici du fait de l'usage d'une configuration matérielle particulière.
Je conçois aisément que de disposer de trois écrans et deux PC pour soi-même reste exceptionnel, mais pas forcément difficile à obtenir ; tout dépend chez qui vous travaillez d'une part et votre degré d'affinité avec votre hiérarchie et/ou le service informatique d'autre part. Tout se justifie.

Si un gain de productivité accrue est soulevé et confirmé, vous ne devriez pas rencontrer d'obstacles.

Dans le cas contraire, pour remédier à ce cas de figure, vous pouvez avoir recours à une machine virtuelle, comme VMWare ou Virtual PC ou tout autre programme de virtualisation équivalent.

Vous y installeriez Windows et Office dans les mêmes versions que celles que vous possédez.

Poste de travail en double écran avec un VMWare

Légèrement grossi, vous pouvez observer la Machine Virtuelle Windows XP avec Office 2003 avec
ma fameuse base de données ouverte sur ses cinq tables à surveiller.

Machine virtuelle sur le poste de développement

Je vous précise qu'une telle configuration est à même de s'intégrer parfaitement à votre environnement et ce, que vous soyez en Active Directory ou non.

Il s'avère qu'un certain nombre de droits devront peut-être vous être octroyés, ne serait-ce que pour paramétrer l'accès aux serveurs.

Dans son utilisation, l'usage d'une machine virtuelle, bien qu'extrêmement pratique pour les tests, n'est pas aussi souple et aussi convivial, car il nécessite tout de même un arrangement des fenêtres de vos applications avec un éventuel ALT+TAB pour basculer sur la fenêtre de cette dernière.

Par ailleurs, une telle configuration est très consommatrice de ressources ce qui n'est pas forcément un avantage lors de vos tests.
Bref, un PC équipé de 2 Go de RAM minimum et un espace disque libre de plusieurs dizaines de gigaoctets libres peuvent aisément assurer avec ce choix.

V - Conclusion

Ce tutoriel peut s'avérer utile pour les développeurs qui souhaitent agrémenter de façon conviviale le développement de leurs projets.

Il faut préciser que cela s'oriente aussi bien aux administrateurs de bases de données qu'aux développeurs.
Notez aussi que pour ma part, travaillant essentiellement dans le milieu bancaire, cela s'est avéré hyper pratique pour les projets que j'ai eu à développer à cette période.
Aussi, j'ai eu, comme de nombreuses fois, l'idée de le partager avec vous pour que vous puissiez en bénéficier.
Je vous laisse installer ces routines dans vos bases. Si vous rencontrez des difficultés ou si j'ai omis de préciser quelque chose qui reste obscur, n'hésitez pas à m'en faire part.

VI - Remerciements

Merci à tous les relecteurs pour leurs corrections, remarques et tout ce qui va avec :

- Philippe JOCHANS (Rédacteur)

- Chtulus (Modérateur)

- Jeannot45 (Rédacteur/Modérateur)

- JPCheck (Rédacteur/Modérateur)

- Tofalu (Responsable MS Office & Access)

- Dolphy35 (Rédacteur/Modérateur)