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 lock
La 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
Sub
V-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
Property
Cet 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
Property
Le 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;412348217708333
Ce 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
Property
Attention ! 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
Property
Le 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
Property
V-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
Property
Comme 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
Property
Pour 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
.accdb
En 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
Property
Cet 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
Sub
V-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
Sub
Cette 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
CCloud
Ensuite, 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 Dorsale
Dans 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
Function
Il 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.CreerFichier
L'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
Sub
VII. 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 barre
VII-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
Sub
VII-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
Sub
VII-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
Sub
VIII. 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
Function
VIII-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.