Sauvegardes datées
Je souhaiterais automatiser la sauvegarde de ma base de données, en dupliquant le fichier MDB de temps en temps. Pour différencier les sauvegardes, l’idéal serait de dater chaque copie. Comment faire ?
Quelques pré-requis
Le code VBA qui suit utilise plusieurs fonctions qui ont déjà été traitées sur le blog. Commencez par les collecter dans un module standard, si ce n’est pas déjà le cas ! Voici la liste de ces fonctions :
Quelques structures utiles
Pour son fonctionnement, la fonction BackupFile()
donnée plus bas a aussi besoin d’une énumération et d’un type de données personnalisé. Du coup :
- Ajoutez un module standard à votre base de données.
- Recopiez ceci en début du module :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
' --- ' RESULTAT DE BACKUP ' --- ' Public Enum BackupResult BackupOk = 0 SourceNotFound = 1 TargetDirNotFound = 2 TargetAlreadyExists = 3 Unknown = 4 End Enum ' --- ' INFORMATION DE BACKUP ' --- Public Type BackupInfo ResultCode As BackupResult TargetPath As String End Type |
La fonction de sauvegarde
A la suite de votre module, ajoutez tout ça :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
' --- ' SAUVEGARDE DATEE D'UN FICHIER ' --- ' Function BackupFile( _ ByVal strSourcePath As String, _ Optional ByVal strTargetDir As String = "", _ Optional ByVal blnForceReplace As Boolean = False) _ As BackupInfo ' Quelques variables... Dim strTargetPath As String Dim fso As Object ' Quelques vérifications On Error GoTo BackupFileErr If Dir(strSourcePath) = "" Then BackupFile.ResultCode = SourceNotFound Exit Function End If ' Chemin de destination strTargetDir = IIf(strTargetDir = "", _ FilePath(strSourcePath), _ AddBackslash(strTargetDir)) If Dir(strTargetDir, vbDirectory) = "" Then BackupFile.ResultCode = TargetDirNotFound Exit Function End If ' Fichier de destination strTargetPath = StringFormat("{0}BACKUP {1} {2}.{3}", _ strTargetDir, _ Format(Now(), "yyyymmdd-hhnnss"), _ FilenameWithoutExt(strSourcePath), _ FileExt(strSourcePath)) BackupFile.TargetPath = strTargetPath ' Est-ce le fichier de destination existe déjà ? If (Dir(strTargetPath) <> "") And (Not blnForceReplace) Then BackupFile.ResultCode = TargetAlreadyExists Exit Function End If ' Copie du fichier via FSO Set fso = CreateObject("Scripting.FileSystemObject") fso.CopyFile strSourcePath, strTargetPath Set fso = Nothing ' Résultat final BackupFile.ResultCode = BackupOk Exit Function BackupFileErr: BackupFile.ResultCode = Unknown Exit Function End Function |
La fonction prend en charge la copie d’un fichier, et date la copie automatiquement. Un fichier test.mdb
sera dupliqué sous le nom BACKUP 20101225-153017 test.mdb
, si la copie a été lancée le 25/12/2010 à 15:30:17. Le fait de descendre au niveau des secondes permet de générer autant de sauvegardes que nécessaire. Vous pouvez aménager le format si ça fait trop !
La création du chemin de la copie est également un peu détaillée, mais ça permettra un peu de souplesse si vous voulez une extension personnalistée (.bak
au lieu de .mdb
, par exemple).
La fonction reçoit 3 paramètres, seul le premier est obligatoire :
- Le chemin complet du fichier à sauvegarder. Le fichier n’est pas forcément un MDB, ça peut être en fait n’importe quoi !
- Le chemin du dossier de destination. Si ce chemin n’est pas donné, la copie se fera dans le même dossier que l’original.
- Une valeur booléenne qui faut
True
s’il faut écraser le fichier de copie (lorsqu’il existe déjà). Devrait servir rarement…
Test #1
Pour tester la fonction directement :
- Ouvrez la fenêtre Exécution (
CTRL
+G
). - Tapez dedans :
? BackupFile(CurrentProject.FullName).ResultCode
Vous devez obtenir un résultat de 0
, qui dit que tout s’est bien passé. Et bien sûr, une copie datée de votre base de données devrait se trouver dans le même dossier.
Test #2
La fonction BackupFile()
n’affiche volontairement aucun message. Elle gère juste le « bas niveau » et renvoie un code de résultat. Vous pouvez utiliser ceci pour afficher des messages clairs à l’utilisateur :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
' --- ' SAUVEGARDE DATEE DE LA BASE DE DONNEES ' --- Sub BackupDB() Dim bi As BackupInfo ' Dupliquer la base dans un sous-dossier Backup ' et récupérer le code de résultat bi = BackupFile(CurrentProject.FullName, _ CurrentProject.Path & "Backup") ' Afficher un message en fonction du résultat Select Case bi.ResultCode ' OK Case BackupResult.BackupOk: MsgBox "Opération terminée." _ & vbCrLf & vbCrLf & "La sauvegarde est disponible à cet emplacement :" _ & vbCrLf & bi.TargetPath, vbInformation ' Fichier source introuvable Case BackupResult.SourceNotFound: MsgBox "Fichier source introuvable !", vbExclamation ' Dossier destination introuvable Case BackupResult.TargetDirNotFound: MsgBox "Dossier destination introuvable !", vbExclamation ' Fichier destination déjà existant Case BackupResult.TargetAlreadyExists: MsgBox "Le fichier de destination existe déjà !", vbExclamation ' Erreur indéterminée Case BackupResult.Unknown MsgBox "Une erreur non identifiée s'est produite.", vbExclamation End Select End Sub |
Dans cet exemple, je suppose que les sauvegardes doivent être faites dans un sous-dossier Backup
, placé au même emplacement que la base MDB.
Pour finir…
Il ne reste plus qu’à…
- Créer un bouton, sur un formulaire.
- Nommer ce bouton proprement.
- Définir l’événement
Sur clic
du bouton de cette manière :
1 2 3 |
Private Sub btnBackup_Click() BackupDB End Sub |
Bonjour,
j’ai un problème sur la seconde ligne avec une nouvelle base de données.:
—————————————————————————————————-
Set fso = CreateObject(« Scripting.FileSystemObject »)
fso.CopyFile strSourcePath, strTargetPath <<<<<< Erreur non identifiée c'est produite
Set fso = Nothing
' Résultat final
BackupFile.ResultCode = BackupOk
Exit Function
BackupFileErr:
BackupFile.ResultCode = Unknown
—————————————————————————————————
Le contenu des deux chaines est bon, la syntaxe du dossier "backup" aussi. La référence a "Microsoft Scripting Runtime" est cochée.
Le module est importé d'une autre base avec laquelle ça fonctionne.
Je ne comprends plus.
Merci.
ES
Est-ce qu’il s’agit de la même version d’Access, sur la base qui fonctionne ?
(quelle version sur la base qui ne marche pas ?)
Est-ce qu’il peut y avoir un problème de droits d’accès sur un dossier ?
bon jour Herve
est qu’en peut faire une bouton dans un formulaire pour sauvegardez la base de donnée faire l’operation de sauvegarde comme le menu access gerer qui trouve dans le bouton office access 2007 par exemple
Tu souhaites un bouton de formulaire, ou un bouton sur le ruban ? Les deux approches sont différentes.
En fin d’article, il y a déjà un exemple pour un bouton de formulaire.
Merci Hervé ; il me manquait ton nouvel article qui m’a bien dépanné. Maintenant ça marche.
Merci à toi pour ton site.
Epijacq > Il s’agit d’un problème sur le nom du module : ce nouvel article devrait dépanner.
Super, ce code. Mais lorsque je clique sur le bouton pour faire la sauvegarde, access me dit « erreur de compilation. Variable ou procédure attendue et non un module ». Et pourtant j’ai défini le bouton comme tu le précises… Y a-t-il une procédure d’appel particulière du module ?
Paselo > Pas de problème ! 🙂
Oh la honte j’vais pas lu tous les posts… donc ce sujet est traité!!!
Vraiment désolé
Bonjour et merci pour toutes ces infos!
J’utilise la fonction de sauvegarde et cela marche super bien mais le problème est que j’ai bcp de fichier de sauvegarde car j’uilise le le format hhmm et ça ne m’arrange pas d’utiliser que les heures… mais j’aimerais lorsqu’il sauvegarde ne conserve chaque fois que les 3 dernières sauvegardes…
ex:
J’ai des fichiers (21 janvier 2014 à 10:56) 210120141056.bak
210120141123.bak
210120141125.bak
Lorsque j’enregistre le suivant, j’aimerais qu’il efface le 210120141056.bak et comme ça je me retrouve qu’avec les 3 derniers!!! Mais il se peut qu’il n’y ai pas de sauvegardes pendant plusieurs jours comme il peut y avoir plusieurs sauvegardes en 10 minutes…
D’avance merci
rodger > C’est effectivement possible (pas facile à donner dans un commentaire, mais ça pourra faire l’objet d’un article).
Jane > L’article sur la suppression automatique des anciennes sauvegardes est en ligne. C’est par ici. Bonne lecture !
Bonsoir,
Maintenant ça fonctionne ouff !!!!
Pour aider les autres, pour résoudre mon problème je suis reparti d’une page blanche, puis copier collé tout les bouts de codes nécessaires et là ça fonctionne.
Désolé Inisian, mais ces codes VBA deviennent trop compliqués pour moi…d’ou mon ignorance lol.
Pour les besoins de ma BdeD access je m’y suis mis car pas le choix du coup les fonctions de base ça roule a peu près mais pour les long codes comme cet exemple ça devient chaud.
En tout cas merci à toi 😉
Autre question, peut on ajouter une fenêtre d’avertissement qui s’ouvre automatiquement disant « attention vous n’avez pas sauvegardé depuis 6mois!! »
Ou à la place peut on créer des sauvegardes automatiques toutes les semaines par exemple en plus des sauvegardes manuelles?
Merci
rodger > Est-ce que tu as bien tous les éléments ? A savoir :
BackupFile()
et la procédureBackupDB
).AddBackslash()
StringFormat()
Si tu as tout repris correctement, et que tu fais Débogage / Compiler dans VBE, il ne devrait pas y avoir d’erreur. Si ça ne compile pas, c’est qu’il manque quelque chose, ou que la syntaxe n’est pas bonne (ce qui serait une erreur de copie, le code d’origine fonctionne).
Ensuite, on peut s’occuper de voir ce que ça va donner à l’exécution.
Si ça ne marche pas :
Sub / End Sub
ne doit pas être copié à l’intérieur d’un autreSub / End Sub
, par exemple)._
» (espace puis souligné), il faut la conserver. L’affichage peut être trompeur selon ton affichage écran.Merci pour votre aide mais ça fonctionne toujours pas!!
Je pige pas, j’ai fait exactement ce qui est écris dans cette page, j’ai encore et toujours des erreurs :-(.
Erreur: »Sub ou fonction non définie »
« Stringformat » surligné en bleu
Et ceci surligné en jaune :
‘ —
‘ SAUVEGARDE DATEE D’UN FICHIER
‘ —
‘
Function BackupFile( _
ByVal strSourcePath As String, _
Optional ByVal strTargetDir As String = « », _
Optional ByVal blnForceReplace As Boolean = False) _
As BackupInfo
Jane > Je ne réponds pas directement ici, parce que ça nécessite un peu de code supplémentaire. Mais ça fera l’objet d’un prochain article.
Je poste ici quand l’article est en ligne.
rodger > Pour
StringFormat()
, il te faut seulement la fonction fournie à cette adresse. La fonction est le premier bloc de code VBA de la page. Je crois comprendre que tu as aussi recopié les exemples plus bas dans l’article en question, et c’est ce qui pose un problème.La fonction
StringFormat()
permet de simplifier le code, en évitant d’écrire des concaténations illisibles, donc difficiles à maintenir. Je l’utilise ici pour construire le nom du fichier (strTargetPath
).Je comprends que ce ne soit pas facile de récupérer des bouts de code par-ci par-là, mais le fait de donner un listing complet en Copier/Coller…
Ouala ! 🙂
Salut!
J’ai copié le code donné des liens:
-Fonctions de dossiers, fichiers et extensions.
-Fonction AddBackslash.
-Fonction StringFormat.
dans un module nommé « module1 ».
Ensuite j’ai copié le code de cette page dans un autre module nommé « save ».
J’ai créé mon bouton dans mon menu, j’essai et là j’ai: erreur de compilation, instruction incorrecte… sur la ligne sql = « DELETE * FROM [la table] WHERE [champ1] = » & valeur1 _
Perso je pige pas le rapport entre la sauvegarde datée et le fait de concaténer des valeurs dans un champ d’une de mes tables???
Si j’enlève le code concernant cette erreur, je me retrouve avec une autre erreur sur « StringFormat »
Vous auriez du mettre tout le code nécessaire pour la sauvegarde sur la même page en expliquant peu être mieux quel code va dans quel module, et comment l’adapter a nos besoins.
On s’y perd avec tout ces bout de code éparpillés dans plusieurs liens.
Merci
Bonjour,
Merci pour votre code que j’utilise depuis plusieurs mois et qui fonctionne à merveille.
Aujourd’hui je poursuis le développement de mes bases et je souhaiterais ajouter une fonctionnalité : ne conserver que 3 ou 4 sauvegardes, qui s’écraseraient au fur et à mesure, sans forcément garder l’horodatage.
Je cherche désespérément un code et je ne le trouve pas !
Merci de votre aide !
lesnox > A quel endroit cela casse-t-il exactement ? Est-ce que les fonctions
StringFormat()
etDateUS()
sont bien disponibles dans la base Access ?Problème résolu 🙂
Désolé pour le dérangement.
Ma variable npm_base ne contenait que le nom de la base sur le serveur et nom le chemin complet de la base + son nom.
Merci pour ce tuto très utile
Bonjour,
Merci pour cet article.
J’arrive bien à réaliser une copie de sauvegarde de ma base quand elle contient les formulaires ainsi que les tables.
Seulement voilà je l’ai scindée en deux et ai déposé uniquement les tables sur un serveur.
Savez-vous comment à partir de mes formulaires réaliser une copie de la base Tables qui est situé sur mon serveur ?
J’ai essayé de changer le nom du chemin et de la base sans succès :
Dim bi As BackupInfo
Dim mylen As Integer
Dim nom_base As String
‘ Dupliquer la base dans un sous-dossier Backup
‘ et récupérer le code de résultat
mylen = Len(CurrentProject.Name) – 6
nom_base = Left(CurrentProject.Name, mylen)
nom_base = nom_base & « _be.accdb »
bi = BackupFile(nom_base, _
« \bnf-fsprtDTGestion _Mto_LDCBackup »)
Il me dit que le fichier source est introuvable pourtant mon chemin a l’air correct.
Par avance merci de votre aide
Cordialement
Guillaume
Bonjour, j’ai un bug sur ma fonction StringFormat :
Dim sql As String
sql = « DELETE * FROM [la table] WHERE [champ1] = {0} AND [champ2] = ‘{1}’ AND [champ3] = {2}; »
sql = StringFormat(sql, valeur1, valeur2, DateUS(valeur3));
il me dit que la 1er séquence est fausse?… avez vous une idée ?
merci d’avance.
Julien
Merci beaucoup merci merci
Djeli > Parfait ! 😎
Oui effectivement car après correction cela fonctionne parfaitement
Ouala!
Merci
Djeli > Si le dossier de destination est sélectionné par l’utilisateur, il n’est peut-être pas utile de rajouter
Backup
derrière. D’autant que, dans ce cas, le sous-dossierBackup
doit exister. Le problème doit venir de là…c’est ce que je pense avoir fait:
voici la modification que j’ai porté à la fonction BackupFile:
bi = BackupFile(Me.CheminBase, Me.CheminDestin & « Backup »)
Me.cheminBase représente le fichier à sauvegarder (obtenu garce à votre code sélection de fichier)
Me.CheminDestin représente le dossier ou doit être sauvegarder le fichier (obtenu grâce à votre code sélection de dossier)
quand je lance la procédure de sauvegarde, j’ai le résultat svt:
Dossier destination introuvable
Bonjour,
Si je suis la logique de la fonction BackupFile le paramètre (strtargetDir) est dans l’exemple « CurrentProjet.Path » de la fonction et non le dossier de ma clef USB.
Quand je suis votre exemple j’ai une erreur:
Run-time error ’13’
Type mismatch
quand je remplace le paramètre « strtargetDir »(CurrentProject.Path) par le nom de mon dossier j’ai le message d’erreur :
Dossier destination introuvable
pour info, je suis passé à Access 2007 et ma version est anglaise
merci
Djeli > Si la clef USB a par exemple la lettre
F:
, et qu’un dossier «Backup
» se trouve à sa racine, on doit pouvoir écrire quelque chose comme :Ou, pour avoir le résultat de la sauvegarde :
Le « Type incompatible » (Type mismatch) signifie qu’une valeur fournie n’est pas dans le type attendu (par exemple : une chaîne à la place d’un numérique, ou l’inverse).
Djeli > Le principe est le même, il suffit d’alimenter le deuxième paramètre (
strTargetDir
) de la fonctionBackupFile
. Ce paramètre doit pointer sur un dossier de la clef USB. Par exemple :Le problème à prendre en compte est que la lettre attribuée à la clef ou au disque externe peut changer. Elle peut être forcée dans la gestion des disques de Windows.
Bonjour,
Désolé de relancer le débat cher Hervé, mais je voulais juste savoir comment faire si on souhaite sauvegarder sur un lecteur amovible (clè USB par exemple).
Merci
pdgz > Même remarque que pour Chantal. Tu as dû oublier de recopier le code de la fonction
StringFormat
dans ta base de données.Chantal > Le code de la sauvegarde datée dépend d’autres fonctions VBA (dont
FilePath
) qu’il faut aussi intégrer à ta base de données. Tu as la liste des articles liés dans le paragraphe « Quelques pré-requis« . Suis les 3 liens, et recopie les bouts de code VBA fournis dans chaque article. La sauvegarde marchera ensuite.Bonjour,
J’ai copié votre code, installé comme expliquer, mais ca bug sur StringFormat:
strTargetPath = stringformat(« {0} BACKUP {1} {2}.{3} », _
strTargetDir, Format(Now(), « yyyymmdd-hhnnss »), _
FilenameWithoutExt(strSourcePath), _
FileExt(strSourcePath))
Je suis débutant et je n’arrive pas à trouver le bug.
Faut-il ajouter un complément, manque-t-il quelque chose, ou un paramètre?
Meilleures salutations
P-A
bonjour,je suis infirmiere et j’ai fait une base de données sans pretention sous access2000. je voudrais sauvegarder ma base et je pensais utiliser ce petit programme, mais au niveau du test1 j’ai un message d’erreur du style « sub ou fonction non définie ». J’ai cette partie en jaune
Function BackupFile( _
ByVal strSourcePath As String, _
Optional ByVal strTargetDir As String = « », _
Optional ByVal blnForceReplace As Boolean = False) _
As BackupInfo
et le terme « FilePath » surligné en bleu.
Je dois surement oublier quelque chose.
Amicalement