Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Sauvegarde d'une base

15 réponses
Avatar
Francis
Bonjour,

Je reviens sur une question déjà posée (15/03/08), et que je n'avais
pas réussi à résoudre. J'ai à nouveau tenté le coup d'appliquer la
méthode de Jessy
http://access.fr.free.fr/download.php?lng=fr&pg=120
et ça ne marche toujours pas: la procédure bloque sur l'instruction:
DBEngine.CompactDataBase strDbFile, strDbFileOld
Par contre, avec l'exemple téléchargé db1.mdb, ça marche au poil.
Si je remplace les variables strDbFile et StrDbFileOld par les chemins
et noms de mon fichier, j'ai alors un message d'erreur d'exécution 3356
qui me dit que j'ai essayé d'ouvrir une base de données déjà ouverte en
mode exclusif etc...

Alors, si qqun pouvait me dire ce qui ne va pas dans ma démarche, ça me
rendrait bien service,
Merci et @+

Francis

--
Francis
fhgc@wanadoudou.fr
THEOREME de la loi de MURPHY
Tout corps plongé dans une baignoire...déclenche systématiquement la
sonnerie du téléphone !

5 réponses

1 2
Avatar
Francis
> Pour moi, ce n'est pas possible de compacter une base qui CONTIENT le
code destiné à compacter la base donc le code de jessy ferme la base
qu'il va compacter et donc vu que la base est fermée; pour que le code
puisse continuer à tourner il est forcément ailleurs.



Re,
Tu as tout à fait raison et, si j'interprète correctement le code de
Jessie, il tient bien compte de cette nécessité.
Revoici le code:

Function CompactEXE() As Boolean

Dim strDbFile As String

strDbFile = CurrentDb.Name & ".tmp"
' Sachant que ma base se nomme E:Mes DocumentsAncreAncre_xx.mdb,
alors: strDbFile = E:Ancre_xx.mdb.tmp, et je retrouve bien ce
fichier dans le répertoire de ma base initiale.

If Dir(strDbFile) <> "" Then Kill strDbFile

' On supprime un fichier .tmp pré-existant. OK?

DBEngine.CreateDatabase strDbFile, dbLangGeneral

' On recrée un fichier .tmp et on y met mcrCompact et
modCompactCurrentDb

DoCmd.CopyObject strDbFile, , acMacro, "mcrCompact"
DoCmd.CopyObject strDbFile, , acModule, "modCompactCurrentDb"

Shell "MSACCESS.EXE """ & strDbFile & """ /x mcrCompact", _
vbMinimizedNoFocus

' Je ne sais pas trop ce que fait cette instruction Shell etc... mais
elle est en rapport avec la macro mcrCompact, qui lance la fonction
Compact() ci-dessous.
Si je ne me fous pas dedans, à ce stade ma base initiale est toujours
ouverte et la macro est exécutée depuis elle, ce qui, d'après toi, est
la cause du problème rencontré. OK ???

End Function

Jusque là, tout se passe comme prévu: CompactEXE() me crée bien le
fichier ANCRE_xx.mdb.tmp, dans lequel je ne trouve que la macro
"mcrCompact" et le module "modcompactCurrentDb", dans lequel se trouve
le code destiné à compacter ma base.


Public Function Compact()
Dim acApp As Access.Application
Dim strDbPath As String, strDbFile As String
Dim strDbFileOld As String

strDbPath = CurrentDb.Name
strDbFile = Left(strDbPath, Len(strDbPath) - 4)
strDbFileOld = Left(strDbFile, Len(strDbFile) - 4) & ".old"

Les 3 instructions ci-dessus n'ont un sens que si CurrentDbName =
E:ANCRE.mdb.tmp. On a alors:
strDbPath = E:ANCRE.mdb.tmp
strDbFile = E:ANCRE.mdb
strDbFileOld = E:ANCRE.mdb.old

Set acApp = GetObject(strDbFile)
Ça voudrait dire qu'on ouvre bien le fichier ex .tmp dans lequel on n'a
que le code pour compacter.
Sauf si mon hypothèse ci-dessus n'est pas vérifiée, et qu'on aurait, à
la place, CurrentDbName = E:ANCRE.mdb, ce qui donnerait
strDbPath = E:ANCRE.mdb
strDbFile = E:ANCRE
strDbFileOld = E:ANCRE.old
Mais, si c'était le cas, comment access réagirait-il???

With acApp
.SysCmd acSysCmdSetStatus, "Compactage en cours..."
.CloseCurrentDatabase
On ferme ANCRE_xx.mdb
DBEngine.CompactDatabase strDbFile, strDbFileOld
Kill strDbFile
On supprime ANCRE_xx.mdb
Name strDbFileOld As strDbFile
.OpenCurrentDatabase strDbFile
On renomme .old en .mdb et on ré-ouvre la base de travail.
.SysCmd acSysCmdClearStatus
End With
Application.Quit
End Function

Bref, si mon analyse entre les diverses instruction est bonne, ça
devrait, "en principe", marcher... Mais, en réalité, c'est pas le cas
:/

Alors, je compte sur vous, les cracks, pour y voir plus clair que moi
et dire où ça cloche..

@+

Francis

--
Francis

LOI DE TATA JACQUELINE
C'est celui qui ronfle qui s'endort toujours le premier.
Avatar
Michel_D
Francis a écrit :
Pour moi, ce n'est pas possible de compacter une base qui CONTIENT le
code destiné à compacter la base donc le code de jessy ferme la base
qu'il va compacter et donc vu que la base est fermée; pour que le code
puisse continuer à tourner il est forcément ailleurs.



Re,
Tu as tout à fait raison et, si j'interprète correctement le code de
Jessie, il tient bien compte de cette nécessité.
Revoici le code:

Function CompactEXE() As Boolean

Dim strDbFile As String

strDbFile = CurrentDb.Name & ".tmp"
' Sachant que ma base se nomme E:Mes DocumentsAncreAncre_xx.mdb,
alors: strDbFile = E:Ancre_xx.mdb.tmp, et je retrouve bien ce fichier
dans le répertoire de ma base initiale.

If Dir(strDbFile) <> "" Then Kill strDbFile

' On supprime un fichier .tmp pré-existant. OK?

DBEngine.CreateDatabase strDbFile, dbLangGeneral

' On recrée un fichier .tmp et on y met mcrCompact et modCompactCurrentDb

DoCmd.CopyObject strDbFile, , acMacro, "mcrCompact"
DoCmd.CopyObject strDbFile, , acModule, "modCompactCurrentDb"

Shell "MSACCESS.EXE """ & strDbFile & """ /x mcrCompact", _
vbMinimizedNoFocus

' Je ne sais pas trop ce que fait cette instruction Shell etc... mais
elle est en rapport avec la macro mcrCompact, qui lance la fonction
Compact() ci-dessous.
Si je ne me fous pas dedans, à ce stade ma base initiale est toujours
ouverte et la macro est exécutée depuis elle, ce qui, d'après toi, est
la cause du problème rencontré. OK ???

End Function

Jusque là, tout se passe comme prévu: CompactEXE() me crée bien le
fichier ANCRE_xx.mdb.tmp, dans lequel je ne trouve que la macro
"mcrCompact" et le module "modcompactCurrentDb", dans lequel se trouve
le code destiné à compacter ma base.


Public Function Compact()
Dim acApp As Access.Application
Dim strDbPath As String, strDbFile As String
Dim strDbFileOld As String

strDbPath = CurrentDb.Name
strDbFile = Left(strDbPath, Len(strDbPath) - 4)
strDbFileOld = Left(strDbFile, Len(strDbFile) - 4) & ".old"

Les 3 instructions ci-dessus n'ont un sens que si CurrentDbName =
E:ANCRE.mdb.tmp. On a alors:
strDbPath = E:ANCRE.mdb.tmp
strDbFile = E:ANCRE.mdb
strDbFileOld = E:ANCRE.mdb.old

Set acApp = GetObject(strDbFile)
Ça voudrait dire qu'on ouvre bien le fichier ex .tmp dans lequel on n'a
que le code pour compacter.
Sauf si mon hypothèse ci-dessus n'est pas vérifiée, et qu'on aurait, à
la place, CurrentDbName = E:ANCRE.mdb, ce qui donnerait
strDbPath = E:ANCRE.mdb
strDbFile = E:ANCRE
strDbFileOld = E:ANCRE.old
Mais, si c'était le cas, comment access réagirait-il???

With acApp
.SysCmd acSysCmdSetStatus, "Compactage en cours..."
.CloseCurrentDatabase
On ferme ANCRE_xx.mdb
DBEngine.CompactDatabase strDbFile, strDbFileOld
Kill strDbFile
On supprime ANCRE_xx.mdb
Name strDbFileOld As strDbFile
.OpenCurrentDatabase strDbFile
On renomme .old en .mdb et on ré-ouvre la base de travail.
.SysCmd acSysCmdClearStatus
End With
Application.Quit
End Function

Bref, si mon analyse entre les diverses instruction est bonne, ça
devrait, "en principe", marcher... Mais, en réalité, c'est pas le cas :/

Alors, je compte sur vous, les cracks, pour y voir plus clair que moi et
dire où ça cloche..



Alors d'abord la ligne que tu ne comprends pas à savoir la ligne :
Shell "MSACCESS.EXE """ & strDbFile & """ /x mcrCompact", _
vbMinimizedNoFocus
C'est elle qui effectue le compactage de la base à partir du code situé
dans la nouvelle base qui a été créée.

Ensuite j'ai testé le code de Jessy et apparemment il n'appécie pas
la nom de la 2ème fonction que j'ai donc renommer en "Compactage",
J'ai ensuite créé une macro "mcrCompact" qui ExecuteCode et choisi
la fonction "Compactage()" puis une 2ème macro qui ExecuteCode et
choisi "CompactEXE()" qui lançe le compactage et aucun problème
cela a bien fonctionné.

Rappel des fonctions :

Function CompactEXE() As Boolean
Dim strDbFile As String

strDbFile = CurrentDb.Name & ".tmp"
If Dir(strDbFile) <> "" Then Kill strDbFile
DBEngine.CreateDatabase strDbFile, dbLangGeneral
DoCmd.CopyObject strDbFile, , acMacro, "mcrCompact"
' Ici faire attention au nom du module
DoCmd.CopyObject strDbFile, , acModule, "modCompactCurrentDb"

Shell "MSACCESS.EXE """ & strDbFile & """ /x mcrCompact", _
vbMinimizedNoFocus
End Function

Public Function Compactage()
Dim acApp As Access.Application
Dim strDbPath As String, strDbFile As String
Dim strDbFileOld As String

strDbPath = CurrentDb.Name
strDbFile = Left(strDbPath, Len(strDbPath) - 4)
strDbFileOld = Left(strDbFile, Len(strDbFile) - 4) & ".old"

Set acApp = GetObject(strDbFile)

With acApp
.SysCmd acSysCmdSetStatus, "Compactage en cours..."
.CloseCurrentDatabase
DBEngine.CompactDatabase strDbFile, strDbFileOld
Kill strDbFile
Name strDbFileOld As strDbFile
.OpenCurrentDatabase strDbFile
.SysCmd acSysCmdClearStatus
End With
Application.Quit
End Function
Avatar
Francis
Michel_D a présenté l'énoncé suivant :
Francis a écrit :
Pour moi, ce n'est pas possible de compacter une base qui CONTIENT le
code destiné à compacter la base donc le code de jessy ferme la base
qu'il va compacter et donc vu que la base est fermée; pour que le code
puisse continuer à tourner il est forcément ailleurs.



Re,
Tu as tout à fait raison et, si j'interprète correctement le code de
Jessie, il tient bien compte de cette nécessité.
Revoici le code:

Function CompactEXE() As Boolean

Dim strDbFile As String

strDbFile = CurrentDb.Name & ".tmp"
' Sachant que ma base se nomme E:Mes DocumentsAncreAncre_xx.mdb, alors:
strDbFile = E:Ancre_xx.mdb.tmp, et je retrouve bien ce fichier dans le
répertoire de ma base initiale.

If Dir(strDbFile) <> "" Then Kill strDbFile

' On supprime un fichier .tmp pré-existant. OK?

DBEngine.CreateDatabase strDbFile, dbLangGeneral

' On recrée un fichier .tmp et on y met mcrCompact et modCompactCurrentDb

DoCmd.CopyObject strDbFile, , acMacro, "mcrCompact"
DoCmd.CopyObject strDbFile, , acModule, "modCompactCurrentDb"

Shell "MSACCESS.EXE """ & strDbFile & """ /x mcrCompact", _
vbMinimizedNoFocus

' Je ne sais pas trop ce que fait cette instruction Shell etc... mais elle
est en rapport avec la macro mcrCompact, qui lance la fonction Compact()
ci-dessous.
Si je ne me fous pas dedans, à ce stade ma base initiale est toujours
ouverte et la macro est exécutée depuis elle, ce qui, d'après toi, est la
cause du problème rencontré. OK ???

End Function

Jusque là, tout se passe comme prévu: CompactEXE() me crée bien le fichier
ANCRE_xx.mdb.tmp, dans lequel je ne trouve que la macro "mcrCompact" et le
module "modcompactCurrentDb", dans lequel se trouve le code destiné à
compacter ma base.


Public Function Compact()
Dim acApp As Access.Application
Dim strDbPath As String, strDbFile As String
Dim strDbFileOld As String

strDbPath = CurrentDb.Name
strDbFile = Left(strDbPath, Len(strDbPath) - 4)
strDbFileOld = Left(strDbFile, Len(strDbFile) - 4) & ".old"

Les 3 instructions ci-dessus n'ont un sens que si CurrentDbName =
E:ANCRE.mdb.tmp. On a alors:
strDbPath = E:ANCRE.mdb.tmp
strDbFile = E:ANCRE.mdb
strDbFileOld = E:ANCRE.mdb.old

Set acApp = GetObject(strDbFile)
Ça voudrait dire qu'on ouvre bien le fichier ex .tmp dans lequel on n'a que
le code pour compacter.
Sauf si mon hypothèse ci-dessus n'est pas vérifiée, et qu'on aurait, à la
place, CurrentDbName = E:ANCRE.mdb, ce qui donnerait
strDbPath = E:ANCRE.mdb
strDbFile = E:ANCRE
strDbFileOld = E:ANCRE.old
Mais, si c'était le cas, comment access réagirait-il???

With acApp
.SysCmd acSysCmdSetStatus, "Compactage en cours..."
.CloseCurrentDatabase
On ferme ANCRE_xx.mdb
DBEngine.CompactDatabase strDbFile, strDbFileOld
Kill strDbFile
On supprime ANCRE_xx.mdb
Name strDbFileOld As strDbFile
.OpenCurrentDatabase strDbFile
On renomme .old en .mdb et on ré-ouvre la base de travail.
.SysCmd acSysCmdClearStatus
End With
Application.Quit
End Function

Bref, si mon analyse entre les diverses instruction est bonne, ça devrait,
"en principe", marcher... Mais, en réalité, c'est pas le cas :/

Alors, je compte sur vous, les cracks, pour y voir plus clair que moi et
dire où ça cloche..



Alors d'abord la ligne que tu ne comprends pas à savoir la ligne :
Shell "MSACCESS.EXE """ & strDbFile & """ /x mcrCompact", _
vbMinimizedNoFocus
C'est elle qui effectue le compactage de la base à partir du code situé
dans la nouvelle base qui a été créée.

Ensuite j'ai testé le code de Jessy et apparemment il n'appécie pas
la nom de la 2ème fonction que j'ai donc renommer en "Compactage",
J'ai ensuite créé une macro "mcrCompact" qui ExecuteCode et choisi
la fonction "Compactage()" puis une 2ème macro qui ExecuteCode et
choisi "CompactEXE()" qui lançe le compactage et aucun problème
cela a bien fonctionné.

Rappel des fonctions :

Function CompactEXE() As Boolean
Dim strDbFile As String

strDbFile = CurrentDb.Name & ".tmp"
If Dir(strDbFile) <> "" Then Kill strDbFile
DBEngine.CreateDatabase strDbFile, dbLangGeneral
DoCmd.CopyObject strDbFile, , acMacro, "mcrCompact"
' Ici faire attention au nom du module
DoCmd.CopyObject strDbFile, , acModule, "modCompactCurrentDb"

Shell "MSACCESS.EXE """ & strDbFile & """ /x mcrCompact", _
vbMinimizedNoFocus
End Function

Public Function Compactage()
Dim acApp As Access.Application
Dim strDbPath As String, strDbFile As String
Dim strDbFileOld As String

strDbPath = CurrentDb.Name
strDbFile = Left(strDbPath, Len(strDbPath) - 4)
strDbFileOld = Left(strDbFile, Len(strDbFile) - 4) & ".old"

Set acApp = GetObject(strDbFile)

With acApp
.SysCmd acSysCmdSetStatus, "Compactage en cours..."
.CloseCurrentDatabase
DBEngine.CompactDatabase strDbFile, strDbFileOld
Kill strDbFile
Name strDbFileOld As strDbFile
.OpenCurrentDatabase strDbFile
.SysCmd acSysCmdClearStatus
End With
Application.Quit
End Function



Bonsoir Michel,

Effectivement, ça marche au poil, et j'en suis tout ébahi. C'est un
vrai tour de passe-passe car tu n'as vraiment pas changé grand chose au
code de Jessy.
Reste quand même un mystère pour moi, au niveau de la différence qu'il
y a entre lancer une macro qui lance CompactEXE() et lancer
directement CompactEXE() par une instruction VBA... Au niveau du
résultat final, il est flagrant que ça n'est pas la même chose :/
Quoi qu'il en soit, bravo et merci beaucoup pour ton coup de main. :-)
Bonne soirée,
Francis

--
Francis

THEOREME de la loi de MURPHY
Tout corps plongé dans une baignoire...déclenche systématiquement la
sonnerie du téléphone !
Avatar
Francis
Bonjour TLM,

Juste pour conclure...
Ma préoccupation initiale était de faire une sauvegarde de mon fichier,
au moment de quitter l'application. Or, le code de Jessy ne répond pas
tout au besoin, puisqu'il ne produit qu'une version compactée de la
base. En fait, on passe par une sauvegarde compactée, qui remplace
ensuite le fichier .mdb initial.
Donc, pour une sauvegarde, voici le code qui marche, à mettre dans un
module :

Option Compare Database
Option Explicit

Function CompactEXE() As Boolean
Dim strDbFile As String

strDbFile = CurrentDb.Name & ".tmp"
If Dir(strDbFile) <> "" Then Kill strDbFile
DBEngine.CreateDatabase strDbFile, dbLangGeneral
DoCmd.CopyObject strDbFile, , acMacro, "mcrCompact"
' Ici faire attention au nom du module
DoCmd.CopyObject strDbFile, , acModule, "modCompactCurrentDb"

Shell "MSACCESS.EXE """ & strDbFile & """ /x mcrCompact", _
vbMinimizedNoFocus
End Function

Public Function Compactage()
Dim acApp As Access.Application
Dim strDbPath As String, strDbFile As String
Dim strDbFileOld As String

strDbPath = CurrentDb.Name
strDbFile = Left(strDbPath, Len(strDbPath) - 4)
strDbFileOld = Left(strDbFile, Len(strDbFile) - 4) & ".old"
If Dir(strDbFileOld) <> "" Then Kill strDbFileOld

Set acApp = GetObject(strDbFile)

With acApp
.SysCmd acSysCmdSetStatus, "Compactage en cours..."
.CloseCurrentDatabase
.Quit
DBEngine.CompactDatabase strDbFile, strDbFileOld
End With
Application.Quit
DoCmd.Quit
End Function

Ce code doit être complété par 2 macros:
- "mcrCompact" qui ExecuteCode et choisit la fonction "Compactage()"
- "mmbrApplication" qui ExecuteCode et choisit "CompactEXE()"

Dand mon application, mon bouton "Quitter" lance la maco
"mmbrApplication" (DoCmd.RunMacro "mmbrApplication")

A partir du code ci-dessus, il n'est pas compliqué de broder un peu
pour faire une sauvegarde à plusieurs niveaux, et/ou à d'autres
endroits que dans le répertoire de la base de travail.

Et merci encore à Jessy et Michel pour leurs contributions

Bonne journée

Francis

--
Francis

RÈGLE DE FLUGG
Plus est urgent le motif pour lequel tu es dans la file d'attente,
plus sera lent l'employé du guichet.
Avatar
Michel_D
Bonjour,

"Francis" a écrit dans le message de news:
Michel_D a présenté l'énoncé suivant :
>
> Alors d'abord la ligne que tu ne comprends pas à savoir la ligne :
> Shell "MSACCESS.EXE """ & strDbFile & """ /x mcrCompact", _
> vbMinimizedNoFocus
> C'est elle qui effectue le compactage de la base à partir du code situé
> dans la nouvelle base qui a été créée.
>
> Ensuite j'ai testé le code de Jessy et apparemment il n'appécie pas
> la nom de la 2ème fonction que j'ai donc renommer en "Compactage",
> J'ai ensuite créé une macro "mcrCompact" qui ExecuteCode et choisi
> la fonction "Compactage()" puis une 2ème macro qui ExecuteCode et
> choisi "CompactEXE()" qui lançe le compactage et aucun problème
> cela a bien fonctionné.
>
> Rappel des fonctions :
>
> Function CompactEXE() As Boolean
> Dim strDbFile As String
>
> strDbFile = CurrentDb.Name & ".tmp"
> If Dir(strDbFile) <> "" Then Kill strDbFile
> DBEngine.CreateDatabase strDbFile, dbLangGeneral
> DoCmd.CopyObject strDbFile, , acMacro, "mcrCompact"
> ' Ici faire attention au nom du module
> DoCmd.CopyObject strDbFile, , acModule, "modCompactCurrentDb"
>
> Shell "MSACCESS.EXE """ & strDbFile & """ /x mcrCompact", _
> vbMinimizedNoFocus
> End Function
>
> Public Function Compactage()
> Dim acApp As Access.Application
> Dim strDbPath As String, strDbFile As String
> Dim strDbFileOld As String
>
> strDbPath = CurrentDb.Name
> strDbFile = Left(strDbPath, Len(strDbPath) - 4)
> strDbFileOld = Left(strDbFile, Len(strDbFile) - 4) & ".old"
>
> Set acApp = GetObject(strDbFile)
>
> With acApp
> .SysCmd acSysCmdSetStatus, "Compactage en cours..."
> .CloseCurrentDatabase
> DBEngine.CompactDatabase strDbFile, strDbFileOld
> Kill strDbFile
> Name strDbFileOld As strDbFile
> .OpenCurrentDatabase strDbFile
> .SysCmd acSysCmdClearStatus
> End With
> Application.Quit
> End Function

Bonsoir Michel,

Effectivement, ça marche au poil, et j'en suis tout ébahi. C'est un
vrai tour de passe-passe car tu n'as vraiment pas changé grand chose au
code de Jessy.
Reste quand même un mystère pour moi, au niveau de la différence qu'il
y a entre lancer une macro qui lance CompactEXE() et lancer
directement CompactEXE() par une instruction VBA... Au niveau du
résultat final, il est flagrant que ça n'est pas la même chose :/
Quoi qu'il en soit, bravo et merci beaucoup pour ton coup de main. :-)
Bonne soirée,
Francis



Pour info j'ai testé sur l'évenement OnClose d'un formulaire et sur
l'évenement OnClick d'un contrôle bouton et cela a bien fonctionné.
1 2