TL;DR —
.Saveécrase le fichier que vous avez déjà..SaveAsécrit un nouveau fichier ou type, et vous devez lui donner le bon numéroFileFormat, sinon vous dépouillez le classeur de ses macros. Un.xlsmprenant en charge les macros a besoin dexlOpenXMLWorkbookMacroEnabled(52), pas du format.xlsx(51) :
Sub SaveAsMacroWorkbook()
Application.DisplayAlerts = False ' pre-approuver l'invite d'ecrasement
ThisWorkbook.SaveAs _
Filename:="C:\Reports\Q1.xlsm", _
FileFormat:=xlOpenXMLWorkbookMacroEnabled ' 52 = .xlsm, conserve le VBA
Application.DisplayAlerts = True ' retablir aussitot
End Sub
Enregistrer paraît être la chose la plus simple qu'une macro puisse faire, et cela cache le piège de perte
de données le plus tranchant de tout le modèle objet des classeurs : le mauvais FileFormat supprime
votre code sans le moindre avertissement. Ce guide repose sur la seule distinction qui l'évite — Save
conserve le fichier que vous avez, SaveAs en crée un nouveau, et le nouveau n'est correct que si le format
correspond à l'extension.
Ce que vous allez apprendre
- Le modèle mental —
Savevalide sur place ;SaveAsécrit un nouveau fichier et exige unFileFormat - Le piège qui dévore vos macros — enregistrer un
.xlsmavec le numéro de format du.xlsxsupprime tout le VBA - Pourquoi
.Savesur un classeur jamais enregistré fait apparaître la boîte de dialogue Enregistrer sous et bloque une macro sans surveillance - Comment
DisplayAlertstransforme l'invite d'écrasement en approbation anticipée, pas en bouton silence - Ce que
wb.Saved = Truefait vraiment (marquer comme propre) par rapport à ce qu'il ne fait pas (écrire le fichier) - Quand recourir plutôt à
SaveCopyAsetExportAsFixedFormat
Le modèle mental : Save valide, SaveAs crée
Deux verbes, deux rôles :
.Saveécrase le fichier existant du classeur, sur place, en silence. Aucune boîte de dialogue, aucun nouveau nom. C'estCtrl+S. Il ne fonctionne que si le classeur possède déjà un fichier sur le disque..SaveAsécrit le classeur vers un nouveau chemin ou un nouveau type de fichier. C'estFichier > Enregistrer sous. Comme il crée un fichier, il a besoin de connaître le format — et c'est là que se niche le piège.
ThisWorkbook.Save ' ecraser le fichier actuel
ThisWorkbook.SaveAs "C:\Reports\Copy.xlsx", xlOpenXMLWorkbook ' ecrire un nouveau .xlsx
Tout ce qui suit découle de cette seule scission.
Le piège qui dévore vos macros : FileFormat doit correspondre à l'extension
C'est l'échec qui fait croire aux gens qu'Excel a « perdu » leur code. Vous enregistrez un classeur contenant des macros, mais avec le numéro de format du classeur ordinaire :
ThisWorkbook.SaveAs "C:\Reports\Q1.xlsm", xlOpenXMLWorkbook ' 51 = .xlsx = AUCUNE macro
xlOpenXMLWorkbook (51) est le format .xlsx, et le .xlsx ne peut pas contenir de VBA. Excel écrit
le fichier et abandonne en silence chaque module et chaque macro — même si vous avez nommé le fichier
.xlsm. Désormais l'extension dit « prend en charge les macros » et le contenu dit « aucune macro », si
bien qu'Excel avertit ou refuse de l'ouvrir proprement, et votre code a disparu.
La règle est simple : le numéro FileFormat doit s'accorder avec l'extension. Les quatre que vous
utilisez réellement :
' Constantes FileFormat (et leurs valeurs numeriques) :
' xlOpenXMLWorkbook = 51 .xlsx (aucune macro)
' xlOpenXMLWorkbookMacroEnabled = 52 .xlsm (conserve les macros)
' xlExcel8 = 56 .xls (ancien 97-2003)
' xlCSV = 6 .csv (une feuille, valeurs uniquement)
Si le classeur contient du code, ce doit être un .xlsm avec 52. Dans le doute, utilisez la constante
nommée, pas le nombre brut — xlOpenXMLWorkbookMacroEnabled ne peut pas être mal saisi comme 52 peut
l'être.
Save sur un classeur jamais enregistré fait apparaître une boîte de dialogue
.Save écrase le fichier existant — mais un classeur créé avec Workbooks.Add n'a pas encore de fichier.
Appeler .Save dessus ne peut pas savoir où écrire, donc Excel se rabat sur la boîte de dialogue
Enregistrer sous — ce qui bloque toute macro s'exécutant sans surveillance. La première fois que vous
écrivez un nouveau classeur, utilisez toujours .SaveAs avec un chemin et un format explicites :
Dim wb As Workbook
Set wb = Workbooks.Add
' wb.Save ' FAUX sur un nouveau classeur - ouvre la boite Enregistrer sous
wb.SaveAs "C:\Reports\New.xlsx", xlOpenXMLWorkbook ' correct - donnez-lui un chemin la premiere fois
wb.Save ' maintenant .Save fonctionne - le fichier existe
L'invite d'écrasement est une approbation anticipée, pas un bouton silence
Un SaveAs vers un chemin qui existe déjà lève l'invite modale « Un fichier existe déjà — le remplacer ? ».
Pour une exécution sans surveillance, vous la supprimez :
Application.DisplayAlerts = False
wb.SaveAs "C:\Reports\Q1.xlsm", xlOpenXMLWorkbookMacroEnabled
Application.DisplayAlerts = True
Lisez cela honnêtement : mettre DisplayAlerts = False ne fait pas taire la question, il y répond avec
la valeur par défaut — oui, remplacer. Vous avez approuvé à l'avance l'écrasement de ce qui se trouvait
déjà à ce chemin. C'est exactement le propos de VBA DisplayAlerts : vous ne
cachez pas un avertissement, vous consentez à l'avance à la valeur par défaut destructrice. Rétablissez
DisplayAlerts = True à la ligne juste après, pour que l'invite suivante ne soit pas, elle aussi, validée
automatiquement en silence.
Saved = True marque comme propre ; il n'enregistre pas
wb.Saved est l'indicateur « modifié » — False signifie « il y a des modifications non enregistrées ».
Vous verrez cette astuce pour supprimer l'invite de fermeture :
wb.Saved = True ' dire a Excel "aucune modification non enregistree" - n'ECRIT PAS le fichier
wb.Close ' ferme sans l'invite "enregistrer les modifications ?"
C'est utile, mais sachez exactement ce que ça fait : cela ment à Excel sur l'état modifié pour que
l'invite de fermeture n'apparaisse pas. Il n'écrit rien sur le disque. Si vous vouliez réellement
conserver les modifications, wb.Saved = True les jette. Marquer comme propre et enregistrer sont deux
opérations différentes — ne les confondez pas.
SaveCopyAs et PDF : les deux sosies de SaveAs
Deux tâches ressemblent à SaveAs sans en être :
SaveCopyAsécrit une copie de sauvegarde sur le disque sans changer le chemin propre du classeur ni son état modifié. C'est le bon outil pour « prendre un instantané du fichier avant de le modifier », car le classeur actif garde son nom d'origine et reste ouvert :ThisWorkbook.SaveCopyAs "C:\Backups\before-run.xlsm" ' copie a part ; l'original intactLe PDF n'est pas un format
SaveAs. Il n'existe pas de « SaveAs PDF » — exporter en PDF est une méthode différente,ExportAsFixedFormat:ThisWorkbook.ExportAsFixedFormat Type:=xlTypePDF, Filename:="C:\Reports\Q1.pdf"
Le verdict honnête : quel enregistrement utiliser
.Save— valider les modifications d'un classeur qui possède déjà un fichier. Le cas quotidien..SaveAs path, FileFormat— écrire un nouveau fichier ou convertir le type. Passez toujours unFileFormatexplicite, et faites-le correspondre à l'extension :52pour.xlsm,51pour.xlsx,6pour.csv..SaveCopyAs— un instantané de sauvegarde qui laisse le classeur actif tranquille.ExportAsFixedFormat— sortie PDF/XPS, pas un format d'enregistrement.
Le point non négociable : si le classeur contient du code, c'est un .xlsm avec
xlOpenXMLWorkbookMacroEnabled. Chaque ticket « où sont passées mes macros ? » est ce numéro qui est faux.
Et tout SaveAs dans une exécution automatisée a besoin d'un DisplayAlerts = False autour de lui — avec
un rétablissement immédiat — pour que l'invite d'écrasement ne bloque pas la tâche ou, pire, ne reçoive pas
une réponse automatique silencieuse pour le fichier suivant lui aussi.
Comment ExcelMaster aide
L'étape de l'enregistrement est celle où une macro qui fonctionne détruit discrètement du travail : le
mauvais FileFormat supprime le VBA, .Save sur un nouveau classeur se bloque sur une boîte de dialogue,
un DisplayAlerts non rétabli valide automatiquement l'invite suivante, et Saved = True jette des
modifications que vous vouliez conserver. Chacun est un petit détail ; chacun fait perdre des données.
ExcelMaster réussit
l'enregistrement par construction. Demandez-lui d'« enregistrer la feuille de chaque région dans son propre
classeur prenant en charge les macros » et il écrit .SaveAs avec xlOpenXMLWorkbookMacroEnabled, encadre
l'écrasement d'une paire DisplayAlerts désactivé/réactivé, utilise SaveCopyAs quand vous voulez une
sauvegarde plutôt qu'un renommage, et .Save uniquement sur les classeurs qui possèdent déjà un chemin.
Vous décrivez le fichier voulu ; il choisit le format qui conserve votre code et vos données.
Questions fréquentes
Quelle est la différence entre Save et SaveAs en VBA ?
.Save écrase le fichier existant du classeur sur place, en silence, sans boîte de dialogue — l'équivalent
de Ctrl+S. .SaveAs écrit le classeur vers un nouveau chemin ou un nouveau type de fichier et exige un
argument FileFormat. Utilisez .Save pour valider les modifications d'un fichier qui existe déjà, et
.SaveAs pour créer un nouveau fichier ou convertir le format.
Pourquoi VBA a-t-il supprimé mes macros quand j'ai enregistré le classeur ?
Vous avez enregistré un classeur à macros avec le numéro de format du .xlsx, xlOpenXMLWorkbook (51). Le
format .xlsx ne peut pas stocker de VBA, donc Excel abandonne en silence chaque module même si le fichier
est nommé .xlsm. Enregistrez les classeurs prenant en charge les macros avec
xlOpenXMLWorkbookMacroEnabled (52) pour que le code soit conservé.
Comment enregistrer un classeur en VBA sans l'invite d'écrasement ?
Mettez Application.DisplayAlerts = False avant le SaveAs, puis rétablissez-le à True juste après. Cela
répond à l'invite « le fichier existe déjà, le remplacer ? » avec sa valeur par défaut (oui, remplacer), si
bien qu'elle n'apparaît pas. Rappelez-vous que vous avez approuvé à l'avance l'écrasement du fichier
existant, alors assurez-vous que c'est bien ce que vous voulez.
Que fait wb.Saved = True en VBA ?
Cela met l'indicateur « modifié » du classeur à « aucune modification non enregistrée » pour qu'Excel
n'affiche pas l'invite « enregistrer les modifications ? » à la fermeture. Il n'écrit rien sur le
disque. S'il y avait réellement des modifications non enregistrées, mettre Saved = True les abandonne.
Pour conserver les modifications, appelez .Save ou fermez avec SaveChanges:=True.
Comment enregistrer un classeur en PDF en VBA ?
Le PDF n'est pas un format SaveAs. Utilisez ExportAsFixedFormat :
ThisWorkbook.ExportAsFixedFormat Type:=xlTypePDF, Filename:="C:\Reports\Q1.pdf". Pour écrire une simple
copie de sauvegarde du classeur lui-même sans changer son nom, utilisez plutôt SaveCopyAs.
Testé dans
Testé dans : Excel 365 (Windows 11), VBA 7.1 — vérifié le 20/08/2026.
Guides associés : VBA Open Workbook · VBA Close Workbook · VBA DisplayAlerts · VBA Workbook_BeforeSave Event · VBA ScreenUpdating
