🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

VBA Save Workbook dans Excel — Save contre SaveAs, le piège de FileFormat, et pourquoi vos macros disparaissent

|

VBA Save Workbook dans Excel — Save contre SaveAs, le piège de FileFormat, et pourquoi vos macros disparaissent

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éro FileFormat, sinon vous dépouillez le classeur de ses macros. Un .xlsm prenant en charge les macros a besoin de xlOpenXMLWorkbookMacroEnabled (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 — Save valide sur place ; SaveAs écrit un nouveau fichier et exige un FileFormat
  • Le piège qui dévore vos macros — enregistrer un .xlsm avec le numéro de format du .xlsx supprime tout le VBA
  • Pourquoi .Save sur un classeur jamais enregistré fait apparaître la boîte de dialogue Enregistrer sous et bloque une macro sans surveillance
  • Comment DisplayAlerts transforme l'invite d'écrasement en approbation anticipée, pas en bouton silence
  • Ce que wb.Saved = True fait vraiment (marquer comme propre) par rapport à ce qu'il ne fait pas (écrire le fichier)
  • Quand recourir plutôt à SaveCopyAs et ExportAsFixedFormat

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'est Ctrl+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'est Fichier > 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 intact
    
  • Le 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 un FileFormat explicite, et faites-le correspondre à l'extension : 52 pour .xlsm, 51 pour .xlsx, 6 pour .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