TL;DR —
FileCopy source, destinationcopie un fichier en une ligne, n'exige aucune référence, et écrase en silence ce qui se trouve déjà à la destination. Le piège qui attrape tout le monde : il ne peut pas copier un fichier ouvert — y compris le classeur depuis lequel vous exécutez la macro. Les deux chemins doivent être complets, nom de fichier compris, et le dossier de destination doit déjà exister :
Sub BackupReport()
' Les deux arguments sont des chemins COMPLETS, nom de fichier inclus de chaque cote
FileCopy "C:\Reports\March.xlsx", "C:\Backup\March.xlsx" ' ecrase Backup en silence
End Sub
Une fois qu'une macro a trouvé les fichiers sur lesquels travailler, la chose suivante qu'elle fait
d'ordinaire, c'est d'agir sur eux — et la plus douce de ces actions est d'en copier un quelque part de
sûr avant que quoi que ce soit d'autre n'y touche. C'est aussi là que les débutants heurtent leur premier
mur : FileCopy fonctionne parfaitement sur un fichier fermé, puis échoue avec error 70 à l'instant où
vous le pointez sur un classeur ouvert. Comprenez pourquoi, et vous choisirez toujours le bon des trois
outils de copie.
Ce que vous allez apprendre
- Le modèle mental — quel outil de copie vous faut-il dépend de savoir si le fichier est ouvert
- Pourquoi
FileCopyécrase sans avertissement — l'inverse de l'instructionName - Pourquoi
FileCopyéchoue avecerror 70sur un classeur ouvert, et quoi utiliser à la place - Pourquoi les deux arguments doivent être des chemins complets et le dossier de destination doit déjà exister
- Quand passer à
FileSystemObject.CopyFilepour les caractères génériques et un indicateur d'écrasement explicite - Comment copier le classeur actuellement ouvert avec
SaveCopyAs, et comment copier-puis-Killdevient un déplacement
Le modèle mental : trois outils de copie pour trois situations
Il n'y a pas de commande unique « copier un fichier » en VBA — il y en a trois, et elles ne sont pas interchangeables. La question qui désigne la bonne est toujours la même : le fichier est-il ouvert, et avez-vous besoin de caractères génériques ?
FileCopy source, destination— l'instruction intégrée. Aucune référence, aucun objet. Copie un fichier fermé, écrase la destination en silence. C'est votre choix par défaut pour les fichiers posés sur le disque.FileSystemObject.CopyFile source, destination[, overwrite]— la version modèle objet. Même tâche, mais elle accepte les caractères génériques (*.xlsx), prend un indicateur d'écrasement explicite, et possède un frèreCopyFolderpour des arborescences entières.workbook.SaveCopyAs path— la seule façon correcte de copier un classeur actuellement ouvert. Elle écrit un instantané sur le disque sans perturber le fichier vivant.
Tout ce qui suit découle de ces trois outils et des situations auxquelles ils appartiennent. Choisissez en demandant d'abord « est-il ouvert ? », puis « me faut-il un motif ? ».
FileCopy écrase en silence — l'inverse de Name
FileCopy ne demande jamais rien. Si quelque chose existe déjà à la destination, c'est remplacé sans
invite et sans erreur. Cela compte parce que l'instruction sœur pour le disque, Name,
fait exactement l'inverse — elle refuse d'écraser et lève une erreur. Deux instructions intégrées, deux
réponses contradictoires à « et si la destination existe ? » :
FileCopy "C:\Reports\March.xlsx", "C:\Backup\March.xlsx" ' remplace Backup\March.xlsx, sans avertissement
Si un écrasement silencieux est ce que vous voulez (rafraîchir une sauvegarde), c'est commode. Si ce n'est
pas le cas — si cette sauvegarde était l'unique copie d'hier — vous devez protéger la destination vous-même
avant d'appeler FileCopy :
If Dir("C:\Backup\March.xlsx") = "" Then ' ne copier que si rien ne s'y trouve
FileCopy "C:\Reports\March.xlsx", "C:\Backup\March.xlsx"
End If
Ce test d'existence d'une ligne fait l'objet de la vérification de l'existence d'un fichier ; ici, il fait la différence entre une sauvegarde sûre et une sauvegarde détruite.
Le piège de l'erreur 70 : FileCopy ne peut pas copier un fichier ouvert
C'est le bug FileCopy numéro un. L'instruction demande à Windows un accès en lecture exclusif sur la
source et un accès en écriture exclusif sur la destination. Un classeur ouvert est verrouillé par Excel,
donc :
FileCopy ThisWorkbook.FullName, "C:\Backup\live.xlsx" ' error 70 - "Permission denied"
échoue immédiatement — et le fichier que vous voulez le plus sauvegarder (celui dans lequel vous
travaillez) est précisément celui qui est ouvert. Le même error 70 apparaît si la destination est
ouverte, en lecture seule, ou si vous n'avez pas les droits sur le dossier. Il y a deux issues correctes :
- Si c'est votre classeur, utilisez
SaveCopyAs— il copie le fichier vivant sans le fermer (section suivante). - Si c'est un autre classeur que vous avez ouvert par code,
Close-le d'abord, puisFileCopyle fichier sur le disque.
Ne « corrigez » jamais un error 70 avec On Error Resume Next — cela masque un fichier verrouillé comme
une non-copie silencieuse, et votre sauvegarde n'a tout simplement jamais lieu.
Les deux arguments sont des chemins complets — et le dossier doit exister
Deux règles structurelles piègent les gens à répétition :
La destination est un chemin complet, pas un dossier. FileCopy ne déduit pas le nom de fichier à
partir de la source.
FileCopy "C:\Reports\March.xlsx", "C:\Backup\" ' error 75 - erreur d'acces chemin/fichier
FileCopy "C:\Reports\March.xlsx", "C:\Backup\March.xlsx" ' correct - nommez-le explicitement
Le dossier de destination doit déjà exister. FileCopy ne créera pas C:\Backup\ pour vous. Si le
dossier risque d'être absent, créez-le d'abord avec MkDir — et rappelez-vous que MkDir lui-même lève une
erreur si le dossier existe déjà, alors protégez-le :
If Dir("C:\Backup", vbDirectory) = "" Then MkDir "C:\Backup"
FileCopy "C:\Reports\March.xlsx", "C:\Backup\March.xlsx"
FileSystemObject.CopyFile : caractères génériques et un indicateur d'écrasement explicite
Quand vous devez copier beaucoup de fichiers d'un coup, ou que vous voulez que l'écrasement soit une
décision plutôt qu'un défaut silencieux, passez au FileSystemObject :
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject") ' liaison tardive - tourne sur toute machine
fso.CopyFile "C:\Reports\*.xlsx", "C:\Backup\" ' caracteres generiques : tous les .xlsx d'un coup
fso.CopyFile "C:\Reports\March.xlsx", "C:\Backup\March.xlsx", False ' Overwrite:=False -> erreur si le fichier existe
Trois choses que FileCopy ne sait pas faire et que CopyFile sait faire : correspondre à un motif de
caractères génériques, prendre un indicateur d'écrasement pour qu'un fichier existant lève error 58
au lieu de disparaître en silence, et — avec CopyFolder — copier une arborescence de dossiers entière.
Notez que la forme dossier-de-destination est permise ici (un \ final signifie « dans ce dossier »), ce
qui explique pourquoi CopyFile s'associe naturellement à une source à caractères génériques. Il ne peut
toujours pas copier un fichier ouvert, cependant — cette limite appartient à Windows, pas à l'outil.
Copier le classeur ouvert avec SaveCopyAs — et copier-puis-Kill est un déplacement
Pour le classeur vivant, la réponse n'est pas du tout une copie de système de fichiers — c'est une méthode de classeur :
ThisWorkbook.SaveCopyAs "C:\Backup\March-" & Format(Now, "yyyymmdd-hhnnss") & ".xlsx"
SaveCopyAs écrit une copie sur le disque et laisse l'original ouvert et intact — pas de error 70, pas
de fermeture, aucun changement au chemin propre du classeur. C'est l'appel de sauvegarde correct au sein de
toute longue macro, et il est traité aux côtés de Save et SaveAs dans le
guide de sauvegarde d'un classeur.
Enfin, une identité utile : un déplacement est une copie suivie d'une suppression. Quand vous ne pouvez
pas utiliser Name — par exemple pour déplacer un fichier vers un lecteur
différent, ce que Name refuse — vous vous rabattez sur copier-puis-supprimer :
FileCopy "C:\Reports\March.xlsx", "D:\Archive\March.xlsx" ' copier vers l'autre lecteur
Kill "C:\Reports\March.xlsx" ' puis supprimer l'original
Ce Kill est définitif et n'a aucune annulation, alors faites-le seulement
après avoir confirmé que la copie est bien arrivée.
Le verdict honnête : choisissez selon « est-il ouvert ? » puis « me faut-il un motif ? »
Copier un fichier est trivial jusqu'à ce que le fichier soit ouvert ou que la destination compte déjà. Quatre règles gardent la chose correcte :
- Fichier fermé, copie unique →
FileCopy— le plus court, aucune installation, mais il écrase en silence, alors protégez la destination quand le fichier existant compte. - Beaucoup de fichiers ou une vraie décision d'écrasement →
fso.CopyFileavec un caractère générique et l'indicateurOverwrite. - Le classeur ouvert →
SaveCopyAs, jamaisFileCopy— c'est toute la réponse àerror 70. - Chemins complets, dossier existant → nommez explicitement le fichier de destination et faites
MkDirdu dossier d'abord.
À l'instant où FileCopy vous donne un error 70, cessez de vous tourner vers On Error et posez la vraie
question : ce fichier est-il ouvert ? S'il est à vous, SaveCopyAs ; si c'en est un autre, fermez-le
d'abord.
Comment ExcelMaster aide
Choisir entre FileCopy, fso.CopyFile et SaveCopyAs — et se souvenir que seul le dernier peut toucher un
classeur ouvert, que la destination a besoin d'un chemin complet, et que le dossier doit exister au préalable
— représente beaucoup de cérémonie pour « juste faire une copie », et le mauvais choix échoue avec un error 70 cryptique à l'exécution.
ExcelMaster écrit la bonne copie pour
la situation. Décrivez la tâche — « sauvegarde ce classeur avec un horodatage avant que j'écrase quoi que ce
soit », ou « copie chaque .xlsx de ce dossier dans une archive » — et il produit l'appel correct :
SaveCopyAs pour le fichier vivant, fso.CopyFile avec un caractère générique pour un lot, la protection
MkDir pour un dossier manquant, et un copier-puis-Kill quand vous vouliez
vraiment un déplacement inter-lecteurs. Vous décrivez le résultat ; il choisit l'outil qui ne lèvera pas
error 70.
Questions fréquentes
Comment copier un fichier en VBA ?
Utilisez l'instruction intégrée FileCopy source, destination, où les deux arguments sont des chemins
complets incluant le nom de fichier — par exemple FileCopy "C:\Reports\March.xlsx", "C:\Backup\March.xlsx".
Elle n'exige aucune référence et copie un fichier fermé, mais elle écrase la destination en silence et le
dossier de destination doit déjà exister. Pour copier beaucoup de fichiers d'un coup, utilisez
FileSystemObject.CopyFile avec une source à caractères génériques.
Pourquoi VBA FileCopy donne-t-il l'erreur 70 Permission denied ?
Parce que le fichier source ou destination est ouvert ou verrouillé. FileCopy a besoin d'un accès
exclusif, et Excel verrouille tout classeur ouvert — copier le classeur depuis lequel vous exécutez échoue
donc toujours avec error 70. Pour copier le classeur actuellement ouvert, utilisez plutôt
ThisWorkbook.SaveCopyAs path ; pour copier un autre classeur que vous avez ouvert par code, Close-le
d'abord, puis FileCopy le fichier sur le disque.
Comment copier un fichier vers un autre dossier en VBA ?
Donnez à FileCopy une destination dans ce dossier, sous forme de chemin complet avec le nom de fichier :
FileCopy "C:\In\a.xlsx", "C:\Out\a.xlsx". Le dossier de destination doit déjà exister — FileCopy ne le
créera pas, alors protégez avec If Dir("C:\Out", vbDirectory) = "" Then MkDir "C:\Out" d'abord. Pour une
destination sous forme de dossier seul comme "C:\Out\", utilisez fso.CopyFile plutôt que FileCopy.
VBA FileCopy écrase-t-il un fichier existant ?
Oui — en silence, sans invite et sans erreur. C'est l'inverse de l'instruction
Name, qui refuse d'écraser. Si vous ne voulez pas remplacer un fichier
existant, testez-le d'abord avec Dir(path) = "" ou fso.FileExists(path), ou utilisez
fso.CopyFile source, destination, False pour qu'une destination existante lève error 58 au lieu de
disparaître.
Comment copier le classeur ouvert actuel en VBA ?
Utilisez ThisWorkbook.SaveCopyAs "C:\Backup\copy.xlsx". SaveCopyAs écrit un instantané sur le disque tout
en laissant l'original ouvert et inchangé, si bien qu'il évite le error 70 que FileCopy donne sur un
fichier ouvert. C'est la façon standard de prendre une sauvegarde horodatée au sein d'une longue macro, et il
ne modifie pas le chemin enregistré propre du classeur.
Testé dans
Testé dans : Excel 365 (Windows 11), VBA 7.1 — vérifié le 22/08/2026.
Guides associés : VBA Delete File · VBA Rename File · VBA Dir · VBA FileSystemObject · VBA Save Workbook
