0. Introduction▲
Dans ce tutoriel, nous allons aborder l'utilisation d'une application Microsoft ACCESS sur un Cloud Storage.
0-A. Avertissement▲
Le Cloud Storage, du fait de son fonctionnement par synchronisation de fichiers, ne permet pas les accès concurrents.
Pour aborder ce tutoriel, vous devez avoir de sérieuses connaissances en VBA et maîtriser l'utilisation des classes. Vous devez également maîtriser les tables liées, ainsi que la gestion des conflits.
Retrouvez un excellent tutoriel pour vous former aux classes VBA https://fauconnier.developpez.com/articles/vba/general/classes/.
I. Prérequis▲
Outre la possession d'une connexion haut débit permanente, vous devrez installer une des solutions de Cloud Storage et vous documenter sur sa gestion de conflits pour adapter la classe.
La solution choisie pour illustrer ce tutoriel est Dropbox dont un lien est disponible ci-dessous. La classe est adaptée à ce produit, libre à vous de l'adapter pour un autre.
Les solutions de Cloud Storage possèdent toutes une offre gratuite mais peuvent être plus ou moins avantageuses en termes techniques (possibilités, capacité de stockage, fonctionnement, rapidité, gestion des conflits).
I-A. Skydrive de Microsoft▲
Vous ne pouvez l'installer qu'à partir de Windows Vista en version 32 ou 64 bits. Plus d'informations sur cette page :
http://windows.microsoft.com/fr-FR/skydrive/system-requirements
I-B. GDrive de Google▲
Installable à partir de XP, il dispose d'une capacité de stockage de 5 Go gratuit.
Pour l'installer, rendez-vous sur votre iGoogle. GDrive est présent dans la barre de menu.

I-C. Dropbox de Dropbox Inc.▲
Dropbox propose 2 Go d'espace de stockage extensible. J'ai choisi cette solution pour illustrer ce cours.
Vous pouvez faire l'installation dès à présent en utilisant l'adresse suivante :
http://db.tt/luWcVhHB (gagnez 500 Mo supplémentaires en utilisant ce lien de parrainage)
II. Fonctionnement▲
Ces solutions de stockage fonctionnent toutes sur le mode de la synchronisation de fichiers.
Un plug-in, petit logiciel résident, est installé sur le poste en même temps qu'un répertoire est créé. Lorsque l'utilisateur copie, crée, modifie ou supprime un fichier, le changement est automatiquement répercuté sur le Cloud. Enfin les serveurs renvoient le changement vers les autres postes abonnés.
Les postes ne sont donc pas connectés à un espace de travail sur un serveur. Il n'y a pas à proprement parler un espace de travail sur un serveur, juste un stockage sur une multitude de serveurs qui ne sont pas identifiables par l'utilisateur.
II-A. Schéma de fonctionnement du Cloud Storage▲
II-B. Installation▲
À partir du lien indiqué plus haut, vous avez installé Dropbox sur votre poste. Le plug-in est chargé au démarrage de la session et on peut le contrôler via la barre des tâches.

Lors de l'installation, le dossier est créé par défaut dans le dossier de l'utilisateur.

Un raccourci vers ce dossier est également créé sur le bureau.

Le plug-in reste en mémoire jusqu'à sa fermeture et est accessible dans la barre des tâches. C'est lui qui observe les fichiers et les synchronise.
Notez qu'une liaison internet haut débit est obligatoire pour avoir un fonctionnement optimal.
III. Le Cloud appliqué à MS ACCESS▲
Outre la gratuité, le partage de données d'une application est un avantage indéniable. Il convient cependant d'être objectif, ce n'est pas la solution miracle et ça ne remplacera pas une base de données en ligne du type Microsoft Azure, notamment pour les accès concurrents.
III-A. Inconvénient▲
Le seul inconvénient majeur et sûrement rédhibitoire pour certaines applications est de ne pas pouvoir l'appliquer à un fonctionnement multiutilisateur. En effet, comme il s'agit de synchronisation de fichiers, si plusieurs machines modifient le même fichier de données en même temps, il y aura conflit.
En cas de conflit, les fichiers ne sont pas perdus ; leur nom est complété par le nom de la machine et la date du conflit.
Voici un exemple de conflit sur deux fichiers.

III-B. Avantages▲
Outre la gestion des conflits indiquée précédemment, un avantage non négligeable est la taille des fichiers. Dropbox bénéficie d'une marge confortable avec ses 10 Go maxi par fichier, soit bien au-delà d'un fichier Microsoft Access.
Vous disposez également d'un archivage des versions sur une durée de trente jours (extensible moyennant un abonnement payant) et également la possibilité de partager des répertoires individuellement.
III-C. Précautions▲
Il convient de choisir une architecture frontale/dorsale pour éviter de synchroniser des informations inutiles, comme l'IHM.
N'hésitez pas à crypter la dorsale, Dropbox Inc. vous l'autorise.
IV. Fonctionnement de l'application▲
Avec une architecture Frontale/Dorsale, Microsoft ACCESS n'accède au fichier dorsal que lorsqu'il y a accès à l'une des tables. Si le fichier dorsal est ouvert, il sera forcément synchronisé à sa fermeture. C'est en gardant à l'esprit ce mécanisme que nous allons travailler.
Vous l'aurez compris, cette technique proscrit l'utilisation des accès concurrents. Il faut donc se prémunir contre tout risque d'accès multiples en s'assurant qu'au démarrage de l'application personne n'est connecté et ainsi éviter la génération de conflits.
IV-A. Comment ça marche▲
Dès le démarrage et avant même tout accès à une des tables de la dorsale, l'application vérifie qu'un fichier, que nous appellerons « lock », existe dans le dossier synchronisé.
- Si ce n'est pas le cas, l'application le crée. Dès lors, le plug-in Dropbox l'envoie dans le Cloud, qui le renvoie vers les postes abonnés. L'application fonctionne normalement. À la fermeture, le fichier « lock » est effacé et le plug-in répercute l'action dans le Cloud.
- Si le fichier « lock » existe, l'application affiche un message et se ferme.
IV-A-1. Schéma de fonctionnement▲
IV-B. Fichier lock vs laccdb▲
Pourquoi utiliser un fichier dit « lock » au lieu d'utiliser directement le fichier « laccdb » de la dorsale ?
La question mérite d'être posée. Le choix s'est porté sur un fichier texte pour pouvoir contrôler les homonymies de nom d'utilisateur.
V. Mise en pratique▲
Il est quand même plus facile de gérer ce genre de fonctionnalité dans une entité. Les classes feront donc pleinement l'affaire.
V-A. Table de paramètres▲
Comme nous l'avons vu dans l'installation, le chemin Dropbox local comme l'utilisateur peuvent être différents d'un poste à l'autre. Une table locale à l'application est donc nécessaire pour stocker ces deux paramètres importants.
Créez une table dans l'application suivant cette structure :
| Nom | Type | Longueur |
| Idiparametre | NuméroAuto | |
| Parametre | Texte | 25 |
| Valeur | Texte | 255 |
Parametre contiendra le nom du paramètre et Valeur sa valeur. Cette table contiendra le paramètre CheminPartage qui donne le chemin vers la Dropbox locale et Utilisateurlocal, l'utilisateur local de l'application.
Inutile de la remplir, c'est le code qui s'en chargera.
Enregistrez-la sous le nom tiParametres. Le i indique que cette table est interne à l'application (fichier Frontal), par opposition à une table de paramètres qui serait stockée dans la dorsale.
V-B. Création de la Classe CCloud▲
Créez un module de classe nommé CCloud, n'oubliez pas de le paramétrer grâce aux propriétés comme l'indique la copie d'écran suivante.

Nous sommes fin prêts pour créer les attributs et les méthodes.
V-C. Attributs et méthodes▲
Voici le diagramme de classe CCloud qui permet d'en avoir une vue d'ensemble.

V-C-1. Attributs▲
| Nom | Description |
| StationLocale | Le nom de la station locale |
| Conflit | Indique s'il y a conflit de fichier dorsal |
| UtilisateurLocal | L'identifiant CCloud de l'utilisateur local |
| Occupe | La détection de l'utilisation de l'application par un tiers |
| UtilisateurConnecte | L'identifiant CCloud de l'utilisateur connecté |
| CheminPartage | Le chemin local de la dorsale (Dossier Dropbox) |
V-C-2. Méthodes▲
| Nom | Description |
| Class_Initialize | Initialisation de la classe |
| Class_Terminate | Terminaison de la classe |
| CreerFichier | Création du fichier « lock » |
| EffacerFichier | Effacement du fichier « lock » |
V-D. En-tête de classe▲
L'en-tête est important dans une classe, car c'est là qu'on y retrouve les variables locales.
Option Compare Database
Option Explicit
Dim vStationLocale As String ' nom de la station locale
Dim vCheminPartage As String ' le chemin SkyDrive/DropBox/GDrive local
Dim vUtilisateurLocal As String ' l'utilisateur local
Const cNomFichier As String = "occupe.txt" 'nom du fichier lockLa constante cNomFichier contient le nom du fichier « Lock ». Si ce nom ne vous convient pas vous pouvez très bien le modifier ; le fonctionnement n'en souffrira pas.
V-E. Initialize/Terminate▲
La méthode d'initialisation Class_Initialize contient l'initialisation de certaines variables comme le nom de l'utilisateur local ainsi que celui de la station.
La méthode Class_Terminate, qui s'exécute à la libération de la classe, permet de déclencher la méthode d'effacement du fichier « lock » et de contrôler un éventuel conflit.
Private Sub Class_Initialize()
' démarre la classe
vStationLocale = Environ("ComputerName")
'on fixe le nom de l'utilisateur si celui-ci n'existe pas.
If vUtilisateurLocal = "" Then
UtilisateurLocal = vStationLocale & ";" & Environ("UserName")
End If
End Sub
Private Sub Class_Terminate()
'Fermeture de la classe
'à appeler sur le close du dernier formulaire ouvert ou avant un quit
' supprime le fichier lock
EffacerFichier
End SubV-F. Les attributs▲
Certains attributs n'ont pas de Setter car ils renvoient des valeurs initialisées par la classe.
V-F-1. Le nom de la station locale - StationLocale▲
Le nom de la station sera utile pour déterminer un conflit d'écriture sur la dorsale au moment de la fermeture.
Public Property Get StationLocale() As String
StationLocale = vStationLocale
End PropertyCet attribut est renseigné au moment de l'initialisation de la classe par la méthode Class_Initialize. Il renvoie le nom de la station locale.
V-F-2. L'utilisateur local - UtilisateurLocal▲
Pour cet attribut vous devez créer le Getter et le Setter.
Le Set n'est utilisé que pour un type Objet, dans le cas d'un type natif (string, long, boolean...) , il faut utiliser Let.
Public Property Let UtilisateurLocal(vLocalUser As String)
' définit l'utilisateur local à partir de
' nom d'utilisateur Windows +
On Error GoTo errSub
Dim db As DAO.Database
Dim rst As DAO.Recordset
Set db = CurrentDb
Set rst = db.OpenRecordset("tIParametres", dbOpenDynaset)
rst.FindFirst "Parametre='UtilisateurLocal'"
' le paramètre existe on le renseigne
If Not rst.NoMatch Then
rst.Edit
rst.Fields(2) = vLocalUser & "-" & Replace(CDbl(Now()), ".", "")
rst.Update
Else
' il n'existe pas on le crée
rst.AddNew
rst.Fields(1) = "UtilisateurLocal"
rst.Fields(2) = vLocalUser & "-" & Replace(CDbl(Now()), ".", "")
rst.Update
End If
rst.Close
ExitSub:
Set rst = Nothing
Set db = Nothing
On Error GoTo 0
Exit Property
errSub:
Resume Next
End PropertyLe Setter de cet attribut stocke le nom de la station et de l'utilisateur. Pour rendre sa valeur unique, nous utilisons l'astuce d'ajouter la date/heure/minute/seconde au format Double, son format natif de stockage, auquel nous enlevons le séparateur décimal.
En voici un exemple :
PC-WINDOWS7;fabrice;412348217708333Ce nouveau nom d'utilisateur unique sera inscrit dans le fichier « lock » où l'application ira le contrôler.
Le Getter est construit sur le même modèle.
Public Property Get UtilisateurLocal() As String
' renvoie l'utilisateur local si défini
On Error GoTo errSub
' renvoie la valeur de l'attribut demandé
Dim db As DAO.Database
Dim rst As DAO.Recordset
Set db = CurrentDb
Set rst = db.OpenRecordset("tIParametres", dbOpenSnapshot)
rst.FindFirst "Parametre='UtilisateurLocal'"
If Not rst.NoMatch Then
UtilisateurLocal = Nz(rst.Fields("Valeur"), "")
Else
UtilisateurLocal = ""
End If
rst.Close
ExitSub:
Set rst = Nothing
Set db = Nothing
On Error GoTo 0
Exit Property
errSub:
GoTo ExitSub
End Property
End PropertyAttention ! Dans le cas où il n'y pas d'utilisateur enregistré, ce qui ne devrait pas se produire, on utilise NZ() pour éviter une erreur de typage au retour de la valeur.
V-F-3. Le chemin local de la Dropbox - CheminPartage▲
Pour le chemin de la Dropbox, le répertoire contenant la dorsale, nous allons utiliser la même méthode que précédemment.
Public Property Let CheminPartage(vChemin As String)
' enregistre le chemin de partage
On Error GoTo errSub
Dim db As DAO.Database
Dim rst As DAO.Recordset
Set db = CurrentDb
Set rst = db.OpenRecordset("tIParametres", dbOpenDynaset)
rst.FindFirst "Parametre='CheminPartage'"
If Not rst.NoMatch Then
rst.Edit ' enregistre le chemin de partage
rst.Fields(2) = vChemin
rst.Update
Else
rst.AddNew ' crée le paramètre
rst.Fields(1) = "CheminPartage"
rst.Fields(2) = vChemin
rst.Update
End If
' stockage du chemin pour la classe
vCheminPartage = vChemin
rst.Close
ExitSub:
Set rst = Nothing
Set db = Nothing
On Error GoTo 0
Exit Property
errSub:
Resume Next
End PropertyLe Getter est similaire à la différence près que s'il est connu, on ne va pas le chercher.
Public Property Get CheminPartage() As String
' renvoie le chemin de partage si déjà défini
On Error GoTo errSub
If Len(vCheminPartage) <> 0 Then
CheminPartage = vCheminPartage
Exit Property
End If
Dim db As DAO.Database
Dim rst As DAO.Recordset
Set db = CurrentDb
Set rst = db.OpenRecordset("tIParametres", dbOpenSnapshot)
rst.FindFirst "Parametre='CheminPartage'"
If Not rst.NoMatch Then
CheminPartage = Nz(rst.Fields("Valeur"), "")
Else
CheminPartage = ""
End If
rst.Close
ExitSub:
Set rst = Nothing
Set db = Nothing
On Error GoTo 0
Exit Property
errSub:
GoTo ExitSub
End PropertyV-F-4. L'utilisateur connecté - UtilisateurConnecte▲
Il est inutile de stocker l'utilisateur connecté. Un Getter suffira largement pour cet attribut.
Pour le connaître, on ouvre le fichier « lock » et on lit la seule ligne présente.
Public Property Get UtilisateurConnecte() As String
' retourne l'utilisateur qui est connecté actuellement
' celui-ci n'est pas forcément l'utilisateur local
On Error Resume Next ' une erreur peut se produire si le fichier lock
' est fermé dans l'intervalle
Dim vFile As Long
Dim strLigne As String
Dim strUtilisateur() As String
If Dir(vCheminPartage & cNomFichier, vbNormal) <> "" Then
vFile = FreeFile
Open vCheminPartage & cNomFichier For Input As vFile
Line Input #vFile, strLigne
Close #vFile ' Ferme le fichier.
End If
strUtilisateur = Split(strLigne, ";")
UtilisateurConnecte = strUtilisateur(0) & ";" & strUtilisateur(1)
End PropertyComme l'utilisateur local, le connecté est composé du nom de la station, du nom de l'utilisateurWindows et du numéro date/heure/minute/seconde sans caractère décimal.
Nous ne prenons que les deux premiers paramètres soit le nom de la station et de l'utilisateur. Notez que vous pouvez aller plus loin en testant la durée de la connexion. Cela peut vous renseigner sur un éventuel problème de libération de l'application.
V-F-5. La détection de l'utilisation de l'application par un tiers - Occupe▲
Cet attribut ne possède qu'un Getter. En effet, il n'y pas de stockage possible puisque c'est la photographie à un instant T de l'état de l'application.
Public Property Get Occupe() As Boolean
' Renvoie vrai si le fichier de lock existe
' et que l'utilisateur n'est pas le local
Dim vOccupe As Boolean
vOccupe = Dir(vCheminPartage & cNomFichier, vbNormal) <> ""
If vOccupe Then
If UtilisateurConnecte = UtilisateurLocal Then
vOccupe = False ' c'est la même connexion
End If
End If
Occupe = vOccupe
End PropertyPour déterminer si l'application est occupée, on teste l'existence du fichier « lock » et si l'utilisateur connecté est différent de l'utilisateur local.
V-F-6. La détection des conflits - Conflit▲
Pour détecter un conflit, il faut tester l'existence d'une copie de la base effectuée par le serveur Dropbox.
La copie se nommera ainsi :

Nom de la dorsale (copie de Nom de la station en conflit Date au format anglo-saxon).accdb
Un Dir donnera ceci :
Dir *Pc-windows7 en conflit 2012-11-21.accdbEn voici l'équivalent avec l'attribut de la classe.
Public Property Get Conflit() As Boolean
On Error GoTo errSub
Conflit = Dir(CDropb.CheminPartage & "*" & CDropb.StationLocale & " en conflit " & Format(Date, "yyyy-mm-dd") & ").accdb") <> ""
ExitSub:
On Error GoTo 0
Exit Property
errSub:
GoTo ExitSub
End PropertyCet attribut est appelé depuis un formulaire muni d'un timer.
V-G. Les méthodes▲
Il n'y a que deux méthodes à mettre en place pour parfaire la classe.
- Création du fichier « lock ».
- Effacement du fichier « lock ».
Rien ne vous empêche de l'étoffer suivant vos besoins personnels.
V-G-1. Création du fichier - CreerFichier▲
On crée le fichier « lock » simplement à partir d'un Open. On y stocke l'utilisateur local et la date/heure de connexion.
Public Sub CreerFichier()
' création du fichier de lock
' composé de l'utilisateur local + date heure de connexion
Dim vFile As Long
Dim strLigne As String
vFile = FreeFile
strLigne = UtilisateurLocal & ";" & Format(Now(), "dddd dd mmmm yyyy hh:mm:ss")
Open vCheminPartage & cNomFichier For Append As vFile
Print #vFile, strLigne
Close #vFile ' Ferme le fichier.
End SubV-G-2. Effacement du fichier Lock - EffacerFichier▲
L'effacement comporte une condition. Les utilisateurs, le local et le connecté doivent être les mêmes pour pouvoir supprimer le fichier.
Private Sub EffacerFichier()
' efface le fichier (lors de la libération)
' uniquement si l'utilisateur actuel est l'utilisateur local
If UtilisateurConnecte = UtilisateurLocal Then
Kill vCheminPartage & cNomFichier
End If
End SubCette méthode est appelée lorsque la classe est déchargée.
VI. Mise en œuvre de la classe CCloud▲
Tout d'abord il faut la déclarer dans l'en-tête de module pour qu'elle vive tout le temps de l'activité de l'application.
Option Compare Database
Option Explicit
Public CDropb As New CCloudEnsuite, dans une procédure appelée au démarrage, on lance la procédure d'attachement automatique qui retourne le chemin.
CDropb.CheminPartage = pGestionTables.fgAttache ' attache les tables et renvoie le chemin de la DorsaleDans la procédure d'attachement, les variables globales sont :
- strLstTable contient la liste des tables à attacher ;
- strFichierData contient le nom de la dorsale ;
- strPassWordBD contient le mot de passe pour l'attache.
Global Const strlstTable As String = "tTable1;tTable2;tTable3"
' nom du fichier de base de données à attacher
Global Const strFichierData As String = "AgaData01.accdb"
Global Const strPassWordBD As String = "monmotdepasse"
Function fgAttache() As String
'--------------------------------------------------------------------------------
' Procedure : pgAttache
' Author : Fabrice CONSTANS (MVP)
' Date : 18 / 07 / 2012
' Purpose : Procédure standard d'attachement des tables
' Vérifie l'attachement ou le refait
' Parametres: Utilise strlstTable qui contient les tables
' strFichierData qui contient le fichier des tables
' Return : chemin de la dorsale
'----------------------------------------------------------------------------------
'
On Error GoTo err_demarrage
Dim db As DAO.Database
Dim rst As Recordset ' pour le test d'attache
Dim lstTable() As String ' contient les tables
Dim i As Integer ' the Compteur
Dim tbl As TableDef
Dim strChemin As String
' utilise le chemin de la table des paramètres
strChemin = CDropb.CheminPartage & strFichierData
' si le fichier Dorsal n'existe pas on le demande
If Not FichierExiste(strChemin) Then
strChemin = fIndiqueFichier(strChemin)
Else
strChemin = strChemin
End If
' sauve le chemin dans la table des paramètres internes
CDropb.CheminPartage = fFichierExt(strChemin, eChemin)
' si user local n'est pas user courant
If CDropb.Occupe Then
MsgBox "La base est actuellement utilisée par : " & CDropb.UtilisateurConnecte & vbCrLf & "Faites une tentative ultérieurement.", vbExclamation + vbOKOnly, fVersionProduit()
' libération de la classe
Set CDropb = Nothing
DoCmd.Quit 'quitte l'application
End If
' Création du fichier, réservation de l'application
CDropb.CreerFichier
' à partir de là on commence les procédures d'attachement sur la dorsale
lstTable = Split(strlstTable, ";") ' la liste des tables à traiter
Set db = DBEngine(0)(0)
For i = 0 To UBound(lstTable) ' liste les tables et tente l'ouverture
Set rst = db.OpenRecordset(lstTable(i), dbOpenSnapshot)
rst.Close
Set rst = Nothing
Next
db.TableDefs.Refresh
If strChemin = "" Then
strChemin = db.TableDefs(lstTable(0)).Connect
strChemin = Right(strChemin, Len(strChemin) - InStr(1, strChemin, ";DATABASE=") - 9)
End If
fgAttache = fFichierExt(strChemin, eChemin)
Exit Function
err_demarrage:
If Err.Number = 3078 Then ' ne trouve pas la table
Set tbl = db.CreateTableDef(lstTable(i))
tbl.Connect = "MS Access;PWD=" & strPassWordBD & ";DATABASE=" & strChemin 'Me.CheminBD '";DATABASE=" &
tbl.SourceTableName = lstTable(i)
db.TableDefs.Append tbl
db.TableDefs(tbl.Name).RefreshLink
Resume
End If
For Each tbl In db.TableDefs
If tbl.Attributes = dbAttachedTable Then
tbl.Connect = "MS Access;PWD=" & strPassWordBD & ";DATABASE=" & strChemin
db.TableDefs(tbl.Name).RefreshLink
End If
Next
Resume
End FunctionIl y a plusieurs lignes faisant référence à notre classe.
- Récupération du chemin de la Dropbox et du nom de la dorsale.
strChemin = CDropb.CheminPartage & strFichierData- Si l'application est utilisée par un tiers. On affiche le message d'avertissement, on libère la classe et on quitte l'application.
If CDropb.Occupe Then
MsgBox "La base est actuellement utilisée par : " & CDropb.UtilisateurConnecte & vbCrLf & "Faites une tentative ultérieurement.", vbExclamation + vbOKOnly, fVersionProduit()
' libération de la classe
Set CDropb = Nothing
DoCmd.Quit 'quitte l'application
End If- On crée le fichier « lock ».
CDropb.CreerFichierL'application peut poursuivre son activité.
VI-A. Procédure à la fermeture de l'application▲
À la fermeture de l'application, il faut libérer l'application en supprimant le fichier « lock ».
VI-A-1. Événement Sur Fermeture▲
Sur cet événement, on ouvre un formulaire d'attente et de contrôle des conflits. Le mode acDialog stoppe l'exécution jusqu'à la fermeture du formulaire.
Private Sub Form_Close()
DoCmd.OpenForm "fAttente", , , , , acDialog
Set CDropb = Nothing
Doevents
DoCmd.Quit
End SubVII. Formulaire fAttente▲
Le formulaire fAttente permet de faire patienter l'utilisateur pendant que l'application vérifie, à intervalles réguliers, les conflits matérialisés par la présence d'une copie du fichier dorsal.
J'ai choisi cette représentation, libre à vous de faire la vôtre !
VII-A. Les contrôles▲
Ce formulaire est composé des contrôles suivants :
- une cadre qui fait office de barre de progression ;
- une zone de titre ;
- une zone de message ;
- un bouton de commande.
| Nom | Visible | Contenu | Type |
| Barre | oui | Couleur | Cadre |
| TxtMsg | non | Vide | Étiquette |
| btnFermer | non | Quitter | Bouton de commande |
| EtiqTitre | oui | Vérification des conflits éventuels | Étiquette |
VII-B. Le code▲
Nous avons besoin d'une variable locale pour ce module. Elle est donc déclarée dans l'en-tête du module. Cette variable permettra de faire évoluer la barre de progression.
Option Compare Database
Option Explicit
Dim i As Long 'stocke le pas de progression pour la barreVII-B-1. Sur Ouverture▲
Sur l'événement d'ouverture, nous initialisons la variable à 500 qui est la valeur du pas de progression de la barre.
Private Sub Form_Open(Cancel As Integer)
i = 500 'pas de progression
End SubVII-B-2. Le bouton Fermer▲
Il s'agit du bouton qui permettra de fermer le formulaire en cas de détection de conflit et d'affichage du message.
Private Sub btnFermer_Click()
DoCmd.Close
End SubVII-B-3. Le Timer▲
C'est le cœur du formulaire. C'est cet événement qui, déclenché à intervalles réguliers, testera s'il y a conflit et affichera le message.
Private Sub Form_Timer()
If Me.Barre.Width > i Then ' si la barre n'a pas atteint son dernier pas
If Not CDropb.Conflit Then ' si pas de conflit
Me.Barre.Width = Me.Barre.Width - i 'progression de la barre
Else
' si conflit
Me.TxtMsg.Caption = "Vous avez créé un conflit d'écriture avec un autre utilisateur."
Me.btnFermer.Visible = True 'on affiche le bouton
Me.TxtMsg.Visible = True ' on affiche le message
Me.Barre.Visible = False ' on cache la barre pour
Me.TimerInterval = 0 ' on arrête le timer
End If
Else
DoCmd.Close ' on ferme automatiquement le formulaire si la progression est finie
End If
End SubVIII. Annexe▲
Dans ce chapitre, sont recensées les fonctions et procédures qui sont utilisées accessoirement dans la solution.
VIII-A. Fonction fHasBackSlash▲
Cette fonction renvoie la valeur passée avec un \ de terminaison.
Function fHasBackSlash(vlChemin As Variant) As String
'---------------------------------------------------------------------------------
' Procedure : fHasBackSlash
' Author : Fabrice CONSTANS
' Date : 01 / 06 / 2012
' Purpose : s'il n'y a pas de backslash à la fin d'un chemin passé en référence, l'ajoute
' Parametres:
' - vlchemin = le chemin à modifier
'--------------------------------------------------------------------------------
On Error GoTo ExcfHasBackSlash
' teste si le caractère de la fin est un \
If Right(Trim(vlChemin), 1) <> "\" Then
' l'ajoute
fHasBackSlash = Trim(vlChemin) & "\"
Else
' renvoie sans espace
fHasBackSlash = Trim(vlChemin)
End If
On Error GoTo 0
Exit Function
ExcfHasBackSlash:
If Err.Number = 94 Then
fHasBackSlash = "c:\"
Exit Function
End If
errSub:
fHasBackSlash = False ' une erreur quelconque se produit
End FunctionVIII-B. Stockage documentaire▲
Vous pouvez indiquer le chemin de la Dropbox pour y stocker des documents liés à l'application.
vgStrRepertoireDocument = fHasBackSlash(CDropb.CheminPartage) & "Documents Amap\"La fonction fHasBackSlash() teste et ajoute l'antislash en fin de chaîne. Elle est présente dans l'annexe en fin du tutoriel.
IX. Conclusion▲
Comme vous l'avez constaté dans ce tutoriel, le Cloud Storage, malgré sa puissance, n'est pas adapté au fonctionnement des fichiers de données de Microsoft ACCESS lors d'accès concurrents. Ce que l'on économise financièrement, en faisant l'impasse sur une véritable solution de base de données hébergée, se paye en rigidité de fonctionnement et en développement de techniques de prévention.
Si vous souhaitez une vraie solution de base de données partagée, tournez-vous plutôt vers SQL Azure. Ce service est payant mais vous n'aurez pas les inconvénients du Cloud Storage.
XI. Remerciement▲
Je remercie Pierre Fauconnier et f-leb pour leurs conseils durant la rédaction de ce tutoriel, Claude Leloup et Zoom61 pour leurs corrections orthographiques.









