Application MS ACCESS dans le Cloud Storage

Comment utiliser une solution de Cloud Storage avec Microsoft ACCESS ? Quels sont les avantages, les inconvénients et surtout comment les mettre en œuvre ?

Fabrice CONSTANS

Commentez cet article : Commentez

- Titre : Application MS ACCESS dans le Cloud Storage

- Auteur : Fabrice CONSTANS

- Parution : 15 décembre 2012

- Mise à jour : 15 décembre 2012

- Licence : Copyright ® 2012 Loufab. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- 0. Introduction

- 0-A. Avertissement

- I. Prérequis

- I-A. Skydrive de Microsoft

- I-B. GDrive de Google

- I-C. Dropbox de Dropbox Inc.

- II. Fonctionnement

- II-A. Schéma de fonctionnement du Cloud Storage

- II-B. Installation

- III. Le Cloud appliqué à MS ACCESS

- III-A. Inconvénient

- III-B. Avantages

- III-C. Précautions

- IV. Fonctionnement de l'application

- IV-A. Comment ça marche

- IV-A-1. Schéma de fonctionnement

- IV-B. Fichier lock vs laccdb

- V. Mise en pratique

- V-A. Table de paramètres

- V-B. Création de la Classe CCloud

- V-C. Attributs et méthodes

- V-C-1. Attributs

- V-C-2. Méthodes

- V-D. En-tête de classe

- V-E. Initialize/Terminate

- V-F. Les attributs

- V-F-1. Le nom de la station locale - StationLocale

- V-F-2. L'utilisateur local - UtilisateurLocal

- V-F-3. Le chemin local de la Dropbox - CheminPartage

- V-F-4. L'utilisateur connecté - UtilisateurConnecte

- V-F-5. La détection de l'utilisation de l'application par un tiers - Occupe

- V-F-6. La détection des conflits - Conflit

- V-G. Les méthodes

- V-G-1. Création du fichier - CreerFichier

- V-G-2. Effacement du fichier Lock - EffacerFichier

- VI. Mise en œuvre de la classe CCloud

- VI-A. Procédure à la fermeture de l'application

- VI-A-1. Événement Sur Fermeture

- VII. Formulaire fAttente

- VII-A. Les contrôles

- VII-B. Le code

- VII-B-1. Sur Ouverture

- VII-B-2. Le bouton Fermer

- VII-B-3. Le Timer

- VIII. Annexe

- VIII-A. Fonction fHasBackSlash

- VIII-B. Stockage documentaire

- IX. Conclusion

- XI. Remerciement

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

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

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.

Schéma de classe

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.