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 :

  1. Ajoutez un module standard à votre base de données.
  2. Recopiez ceci en début du module :

La fonction de sauvegarde

A la suite de votre module, ajoutez tout ça :

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 :

  1. Le chemin complet du fichier à sauvegarder. Le fichier n’est pas forcément un MDB, ça peut être en fait n’importe quoi !
  2. 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.
  3. 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 :

  1. Ouvrez la fenêtre Exécution (CTRL + G).
  2. 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 :

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’à…

  1. Créer un bouton, sur un formulaire.
  2. Nommer ce bouton proprement.
  3. Définir l’événement Sur clic du bouton de cette manière :

Vous aimerez aussi...

36 réponses

  1. ES dit :

    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

    • Hervé Inisan dit :

      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 ?

  2. bobe dit :

    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

  3. Epijacq dit :

    Merci Hervé ; il me manquait ton nouvel article qui m’a bien dépanné. Maintenant ça marche.
    Merci à toi pour ton site.

  4. Hervé Inisan dit :

    Epijacq > Il s’agit d’un problème sur le nom du module : ce nouvel article devrait dépanner.

  5. Epijacq dit :

    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 ?

  6. Hervé Inisan dit :

    Paselo > Pas de problème ! 🙂

  7. paselo dit :

    Oh la honte j’vais pas lu tous les posts… donc ce sujet est traité!!!
    Vraiment désolé

  8. Paselo dit :

    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

  9. Hervé Inisan dit :

    rodger > C’est effectivement possible (pas facile à donner dans un commentaire, mais ça pourra faire l’objet d’un article).

  10. Hervé Inisan dit :

    Jane > L’article sur la suppression automatique des anciennes sauvegardes est en ligne. C’est par ici. Bonne lecture !

  11. rodger dit :

    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

  12. Hervé Inisan dit :

    rodger > Est-ce que tu as bien tous les éléments ? A savoir :

    • Tout le code de cet article (les déclarations du début, la fonction BackupFile() et la procédure BackupDB).
    • Les fonctions de fichiers
    • La fonction AddBackslash()
    • La fonction 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 :

    1. Vérifie que tu as bien tous les bouts de code. Dans le doute, repars d’une base vide.
    2. Vérifie que tu les a intégrés correctement (un Sub / End Sub ne doit pas être copié à l’intérieur d’un autre Sub / End Sub, par exemple).
    3. Attention parfois au Copier/Coller du Web : quand une ligne se termine par la séquence «  _ » (espace puis souligné), il faut la conserver. L’affichage peut être trompeur selon ton affichage écran.
  13. rodger dit :

    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

  14. Hervé Inisan dit :

    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.

  15. Hervé Inisan dit :

    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…

    • donnerait des listings très longs, sur chaque article du blog, et ne permettrait pas de se concentrer sur un point précis ;
    • ne serait pas cohérent avec une approche modulaire de la programmation (il faut réutiliser les éléments, pas les dupliquer ; un projet VBA est justement une accumulation de bouts de code qui servent de base à d’autres programmes) ;
    • et surtout ne ferait pas se poser les bonnes questions. En ayant une approche active, on voit mieux comment les choses s’imbriquent. C’est le principe du proverbe « Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours. »

    Ouala ! 🙂

  16. rodger dit :

    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

  17. Jane dit :

    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 !

  18. Hervé Inisan dit :

    lesnox > A quel endroit cela casse-t-il exactement ? Est-ce que les fonctions StringFormat() et DateUS() sont bien disponibles dans la base Access ?

  19. Guillaume dit :

    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

  20. Guillaume dit :

    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

  21. lesnox dit :

    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

  22. marimad dit :

    Merci beaucoup merci merci

  23. Hervé Inisan dit :

    Djeli > Parfait ! 😎

  24. Djeli dit :

    Oui effectivement car après correction cela fonctionne parfaitement
    Ouala!
    Merci

  25. Hervé Inisan dit :

    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-dossier Backup doit exister. Le problème doit venir de là…

  26. Djeli dit :

    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

  27. Djeli dit :

    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

  28. Hervé Inisan dit :

    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).

  29. Hervé Inisan dit :

    Djeli > Le principe est le même, il suffit d’alimenter le deuxième paramètre (strTargetDir) de la fonction BackupFile. 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.

  30. Djeli dit :

    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

  31. Hervé Inisan dit :

    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.

  32. Hervé Inisan dit :

    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.

  33. pgdz dit :

    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

  34. Chantal dit :

    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

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *