Après la mise à jour 2409 de Microsoft 365, vos exports PDF via VBA affichent un texte barré alors que l’écran est correct ? Voici pourquoi cela se produit et comment le corriger durablement, avec des exemples VBA, C# et PowerShell prêts à l’emploi.
Vue d’ensemble du problème
Depuis la version 2409 (16.0.18025.20160) d’Excel pour Microsoft 365, tout classeur en calcul manuel qui n’est pas recalculé avant l’export PDF via VBA (ExportAsFixedFormat
ou PrintOut
) peut produire un PDF où les valeurs issues de formules sont rendues en barré. À l’écran, rien n’indique d’erreur : l’affichage est normal. L’impression manuelle (menu Fichier › Imprimer ou Enregistrer sous › PDF) n’est généralement pas affectée.
Symptômes typiques
- PDF généré par macro : texte en barré sur des cellules qui contiennent une formule (même sans aucun style « Barré » dans Excel).
- PDF généré via l’interface graphique : rendu normal.
- Recalcul complet puis export : le problème disparaît.
- Retour à une build antérieure (ex. 2402 – 16.0.17328.20550) : plus de texte barré.
Versions concernées et contexte
Le comportement apparaît avec l’introduction de la fonctionnalité Format Stale Values (« Mettre en forme les valeurs obsolètes »). Les builds antérieures, qui ne disposent pas de cette option, ne montrent pas ce phénomène.
Cause identifiée : la mise en forme « Stale Values »
Format Stale Values ajoute une surcouche visuelle pour signaler que des valeurs issues de formules ne sont plus fraîches (non recalculées depuis une modification). Lorsque le classeur est en calcul manuel :
- Si aucun recalcul n’est effectué avant l’export via VBA, Excel considère ces valeurs comme périmées et les rend barrées dans la sortie imprimée/PDF.
- Dès qu’un recalcul (partiel, complet ou complet reconstruit) est déclenché, le barré disparaît.
Ce mécanisme est utile pour les auteurs de classeurs, mais peut surprendre lorsque l’export est automatisé côté utilisateur final.
Pourquoi l’interface graphique n’est pas touchée
Le pipeline d’impression depuis l’interface (ou l’enregistrement au format PDF via Fichier › Enregistrer sous) inclut des garde-fous qui déclenchent un recalcul ou qui n’appliquent pas la mise en forme « stale » à la sortie. En revanche, l’appel programmatique en VBA suit la logique stricte : pas de recalcul → valeurs périmées → texte barré dans le PDF.
Solutions pratiques et recommandations
Solution | Quand l’utiliser | Comment faire (extraits) | Avantages | Points d’attention |
---|---|---|---|---|
Recalculer avant l’export | Vous souhaitez conserver Format Stale Values | Application.Calculate ' ou CalculateFull/CalculateFullRebuild ActiveSheet.ExportAsFixedFormat _ Type:=xlTypePDF, Filename:="...pdf" | Simple, fidèle à l’intention de la fonctionnalité, sans changer les options des utilisateurs. | Coût de calcul potentiellement élevé sur des modèles volumineux. |
Basculer temporairement en calcul automatique | Les classeurs doivent rester en manuel le reste du temps | With Application Dim prevCalc As XlCalculation prevCalc = .Calculation .Calculation = xlCalculationAutomatic ActiveSheet.ExportAsFixedFormat xlTypePDF, "…pdf" .Calculation = prevCalc End With | Limite les modifications globales, s’auto-restaure. | Attention aux effets de bord si d’autres macros tournent en parallèle. |
Désactiver « Mettre en forme les valeurs obsolètes » (pérenne) | Le barré ne présente aucune valeur métier pour vos utilisateurs | Excel › Fichier › Options › Avancé › Affichage : décochez Mettre en forme les valeurs obsolètes. Registre (déploiement) : Windows Registry Editor Version 5.00 [HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\Excel\Options] "StaleValuesFormatting"=dword:00000000 | Résout définitivement le symptôme sans toucher au mode de calcul. | Nécessite une politique claire : fonctionnalité utile pour les auteurs de modèles. |
Revenir à une version antérieure | Correctif temporaire si recalcul/désactivation impossibles | Basculer de canal ou réinstaller la build 2402. | Solution de contournement rapide. | Non durable ; expose à d’autres régressions / manques de patchs. |
Implémentations prêtes à l’emploi (VBA)
VBA minimaliste : recalcul + export PDF
' Exporte la feuille active en PDF après un recalcul simple
Sub ExportPdf_Recalc_Minimal()
Application.Calculate
ActiveSheet.ExportAsFixedFormat _
Type:=xlTypePDF, _
Filename:=ThisWorkbook.Path & "\export.pdf", _
Quality:=xlQualityStandard, _
IncludeDocProperties:=True, _
IgnorePrintAreas:=False, _
OpenAfterPublish:=False
End Sub
VBA robuste : bascule contrôlée + restauration d’état
' Exporte en PDF sans texte barré et restaure l’environnement Excel
Sub ExportPdf_SansBarre_Robuste()
Dim prevCalc As XlCalculation
Dim prevScreen As Boolean, prevEvents As Boolean, prevAlerts As Boolean
Dim pdfPath As String
On Error GoTo CleanFail
```
pdfPath = ThisWorkbook.Path & "\export_" & Format(Now, "yyyymmdd_hhnnss") & ".pdf"
' Sauvegarde de l’état
prevCalc = Application.Calculation
prevScreen = Application.ScreenUpdating
prevEvents = Application.EnableEvents
prevAlerts = Application.DisplayAlerts
' Optimisations & recalcul garanti
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.DisplayAlerts = False
Application.Calculation = xlCalculationManual
' Recalcul complet (choisir l’un des deux selon vos besoins)
'Application.CalculateFull
Application.CalculateFullRebuild
ActiveSheet.ExportAsFixedFormat _
Type:=xlTypePDF, _
Filename:=pdfPath, _
Quality:=xlQualityStandard, _
IncludeDocProperties:=True, _
IgnorePrintAreas:=False, _
OpenAfterPublish:=False
```
CleanSuccess:
' Restauration de l’état
Application.Calculation = prevCalc
Application.ScreenUpdating = prevScreen
Application.EnableEvents = prevEvents
Application.DisplayAlerts = prevAlerts
Exit Sub
CleanFail:
' Restauration même en cas d’erreur
Resume CleanSuccess
End Sub
VBA : export sûr avec bascule temporaire en calcul automatique
Sub ExportPdf_AutoCalc_Temporaire()
Dim prevCalc As XlCalculation
prevCalc = Application.Calculation
```
On Error GoTo SafeExit
Application.Calculation = xlCalculationAutomatic
ActiveSheet.ExportAsFixedFormat xlTypePDF, _
ThisWorkbook.Path & "\export_auto.pdf", _
xlQualityStandard, True, False
```
SafeExit:
Application.Calculation = prevCalc
End Sub
VBA : désactiver/activer la mise en forme « Stale Values » via Registre
À utiliser pour un poste donné ou dans un script d’installation. Nécessite les droits d’écriture sur HKCU.
Sub StaleValues_Desactiver()
Dim wsh As Object
Set wsh = CreateObject("WScript.Shell")
On Error Resume Next
wsh.RegWrite "HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\Excel\Options\StaleValuesFormatting", 0, "REG_DWORD"
End Sub
Sub StaleValues_Activer()
Dim wsh As Object
Set wsh = CreateObject("WScript.Shell")
On Error Resume Next
wsh.RegWrite "HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\Excel\Options\StaleValuesFormatting", 1, "REG_DWORD"
End Sub
Interopérabilité : .NET (C#), PowerShell
Exemple C# (Office Interop) : recalcul puis export PDF
using System;
using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;
class PdfExport
{
static void Main(string[] args)
{
string xlsPath = args.Length > 0 ? args[0] : @"C:\Models\modele.xlsx";
string pdfPath = args.Length > 1 ? args[1] : @"C:\Models\export.pdf";
```
Excel.Application app = null;
Excel.Workbook wb = null;
Excel.Worksheet ws = null;
try
{
app = new Excel.Application { Visible = false, DisplayAlerts = false };
wb = app.Workbooks.Open(xlsPath);
ws = (Excel.Worksheet)wb.ActiveSheet;
// Option A : conserver le manuel mais forcer un recalcul
app.Calculation = Excel.XlCalculation.xlCalculationManual;
wb.Calculate(); // ou app.CalculateFullRebuild();
ws.ExportAsFixedFormat(
Excel.XlFixedFormatType.xlTypePDF,
pdfPath,
Excel.XlFixedFormatQuality.xlQualityStandard,
true, false, Type.Missing, Type.Missing, false, Type.Missing
);
}
finally
{
if (wb != null) wb.Close(false);
if (app != null) app.Quit();
if (ws != null) Marshal.FinalReleaseComObject(ws);
if (wb != null) Marshal.FinalReleaseComObject(wb);
if (app != null) Marshal.FinalReleaseComObject(app);
}
}
```
}
PowerShell (COM Excel) : bascule automatique + export
$xls = "C:\Models\modele.xlsx"
$pdf = "C:\Models\export.pdf"
$excel = New-Object -ComObject Excel.Application
$excel.Visible = $false
$excel.DisplayAlerts = $false
$wb = $excel.Workbooks.Open($xls)
$ws = $wb.ActiveSheet
# Basculer en calcul auto le temps de l'export
$prevCalc = $excel.Calculation
$excel.Calculation = -4105 # xlCalculationAutomatic
$ws.ExportAsFixedFormat(0, $pdf) # 0 = xlTypePDF
# Restauration
$excel.Calculation = $prevCalc
$wb.Close($false)
$excel.Quit()
[System.Runtime.Interopservices.Marshal]::FinalReleaseComObject($ws) | Out-Null
[System.Runtime.Interopservices.Marshal]::FinalReleaseComObject($wb) | Out-Null
[System.Runtime.Interopservices.Marshal]::FinalReleaseComObject($excel) | Out-Null
PowerShell (déploiement Registre) : désactiver « Stale Values »
New-Item -Path HKCU:\Software\Microsoft\Office\16.0\Excel\Options -Force | Out-Null
Set-ItemProperty -Path HKCU:\Software\Microsoft\Office\16.0\Excel\Options `
-Name StaleValuesFormatting -Type DWord -Value 0
Procédure de diagnostic rapide
- Vérifiez le mode de calcul (Formules › Options de calcul). Si Manuel, vous êtes potentiellement concerné.
- Déclenchez Formules › Calculer maintenant puis exportez à nouveau via votre macro. Si le barré disparaît, la cause est confirmée.
- Ouvrez Fichier › Options › Avancé › Affichage et repérez l’option Mettre en forme les valeurs obsolètes. Décochez-la pour un test.
- Si le poste exécute la build 2409 ou ultérieure et que le Registre n’a pas la clé
StaleValuesFormatting
, créez-la pour désactiver la mise en forme.
Bonnes pratiques de performance
- Recalcul ciblé :
Range("A1:Z200").Calculate
si seules ces plages sont utilisées. - Recalculez intelligemment :
CalculateFullRebuild
uniquement lorsque des dépendances ont été ajoutées/retirées. - Optimisations d’environnement : désactivez
ScreenUpdating
,EnableEvents
etDisplayAlerts
pendant l’export, restaurez ensuite. - Gestion des liens : résolvez/actualisez les liaisons externes avant export pour éviter des valeurs « stale » silencieuses.
- Préparez vos zones d’impression (
PageSetup
) pour limiter la surface recalculée/imprimée.
Cas particuliers et conseils
- Volatiles (NOW, RAND, OFFSET…) : privilégiez un snapshot (copier-coller valeurs) avant export si la reproductibilité du PDF est cruciale.
- Power Query / Pivot : rafraîchissez les requêtes et les caches (
PivotCache.Refresh
) avant le recalcul. - Macros concurrentes : encapsulez vos exports dans une procédure unique qui verrouille l’environnement, afin d’éviter des bascules de calcul conflictuelles.
- Postes partagés : pour l’uniformité, privilégiez la désactivation globale (Registre/GPO) ou un retour de version commun à tous.
- Signature visuelle : le barré n’est pas un format de cellule ; c’est un overlay à l’export. Ne perdez pas de temps à rechercher des styles inexistants.
Modèle de décision rapide
Votre export est opéré par des utilisateurs finaux et le barré n’apporte rien ? → Désactivez Stale Values (Registre/GPO).
Vous souhaitez que les auteurs de modèles visualisent les valeurs périmées → Conservez l’option activée, mais imposez un recalcul avant export.
Vous avez des contraintes de temps de calcul → Basculer temporairement en automatique pour l’export ou faites un recalcul ciblé.
FAQ
Faut-il toujours utiliser CalculateFullRebuild ?
Non. Calculate
suffit dans la majorité des cas. Utilisez CalculateFull
si vous suspectez des dépendances non recalculées et CalculateFullRebuild
seulement lorsque la hiérarchie de dépendances a changé (insertions massives de formules, renommage de noms, etc.).
Pourquoi le PDF depuis le menu Fichier est-il correct ?
Le chemin d’export depuis l’interface déclenche des vérifications qui évitent l’application du barré « stale ». Les appels VBA n’en bénéficient pas : ils supposent que votre code gère le recalcul/les options.
Peut-on détecter si des valeurs « stale » existent avant export ?
Excel n’expose pas un drapeau simple par feuille. En pratique, considérez que tout classeur en manuel peut présenter des valeurs non fraîches ; la règle fiable est : recalculer ou désactiver la mise en forme.
Et si je ne peux pas modifier les options des utilisateurs ?
Enveloppez l’export dans une routine qui force un recalcul juste avant l’appel à ExportAsFixedFormat
, puis restaure intégralement l’environnement Excel (mode de calcul, événements, UI).
Des alternatives à ExportAsFixedFormat ?
PrintOut
subit la même logique. Quel que soit l’API utilisée, la clé est d’éliminer l’état « stale » (recalcul) ou de désactiver la mise en forme « Stale Values ».
Checklist de déploiement en entreprise
- Inventorier les postes et les canaux mis à jour en 2409+.
- Choisir une stratégie : recalcul systématique via macros existantes, bascule auto temporaire, ou désactivation globale.
- Normaliser les macros d’export avec une procédure robuste (voir ci-dessus) et gestion d’erreurs.
- Déployer la clé Registre
StaleValuesFormatting=0
si la désactivation est retenue (GPO › Preferences › Windows Settings › Registry, ou script Intune/PowerShell). - Tester sur des classeurs volumineux : mesurer l’impact de
Calculate
vsCalculateFull
pour calibrer les temps d’export. - Former les équipes : expliquer l’objectif de la fonctionnalité et les choix opérés.
Exemple : module d’export unifié
Ce module propose un point d’entrée unique, avec trois stratégies : recalcul, bascule automatique ou désactivation temporaire (si vous possédez les droits Registre).
Option Explicit
Public Enum ExportStrategy
ExportWithRecalc = 1
ExportWithAutoCalc = 2
ExportDisableStale = 3
End Enum
Public Sub ExportPdf_OrienteStrategie(ByVal strat As ExportStrategy, _
Optional ByVal targetSheet As Worksheet, _
Optional ByVal outPath As String)
Dim ws As Worksheet
If targetSheet Is Nothing Then
Set ws = ActiveSheet
Else
Set ws = targetSheet
End If
```
If Len(outPath) = 0 Then
outPath = ThisWorkbook.Path & "\" & ws.Name & "_" & Format(Now, "yyyymmdd_hhnnss") & ".pdf"
End If
Select Case strat
Case ExportWithRecalc: Export_WithRecalc ws, outPath
Case ExportWithAutoCalc: Export_WithAutoCalc ws, outPath
Case ExportDisableStale: Export_DisableStale ws, outPath
Case Else: Export_WithRecalc ws, outPath
End Select
```
End Sub
Private Sub Export_WithRecalc(ws As Worksheet, outPath As String)
Dim prevCalc As XlCalculation
Dim prevScreen As Boolean, prevEvents As Boolean, prevAlerts As Boolean
On Error GoTo CleanFail
```
prevCalc = Application.Calculation
prevScreen = Application.ScreenUpdating
prevEvents = Application.EnableEvents
prevAlerts = Application.DisplayAlerts
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.DisplayAlerts = False
Application.Calculation = xlCalculationManual
Application.Calculate ' ou Application.CalculateFull / CalculateFullRebuild
ws.ExportAsFixedFormat xlTypePDF, outPath, xlQualityStandard, True, False
```
CleanSuccess:
Application.Calculation = prevCalc
Application.ScreenUpdating = prevScreen
Application.EnableEvents = prevEvents
Application.DisplayAlerts = prevAlerts
Exit Sub
CleanFail:
Resume CleanSuccess
End Sub
Private Sub Export_WithAutoCalc(ws As Worksheet, outPath As String)
Dim prevCalc As XlCalculation
prevCalc = Application.Calculation
On Error GoTo CleanExit
```
Application.Calculation = xlCalculationAutomatic
ws.ExportAsFixedFormat xlTypePDF, outPath, xlQualityStandard, True, False
```
CleanExit:
Application.Calculation = prevCalc
End Sub
Private Sub Export_DisableStale(ws As Worksheet, outPath As String)
Dim wsh As Object
Set wsh = CreateObject("WScript.Shell")
Dim changed As Boolean: changed = False
On Error GoTo AfterExport
```
' Désactiver la mise en forme "stale" puis exporter
wsh.RegWrite "HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\Excel\Options\StaleValuesFormatting", 0, "REG_DWORD"
changed = True
```
AfterExport:
ws.ExportAsFixedFormat xlTypePDF, outPath, xlQualityStandard, True, False
End Sub
Comparatif synthétique
Approche | Qualité PDF | Performance | Maintenance | Recommandation |
---|---|---|---|---|
Recalcul avant export | Excellente | Moyenne à faible (selon modèle) | Faible (une ligne de code) | Par défaut si vous conservez « Stale Values » |
AutoCalc temporaire | Excellente | Variable | Moyenne (gestion d’état) | Bon compromis si temps de calcul fluctuants |
Désactivation globale | Excellente | Élevée (pas de recalcul imposé) | Moyenne (déploiement Registre/GPO) | Idéal si le barré n’a pas d’intérêt métier |
Retour de version | Excellente | N/A | Élevée (pilotage des builds) | Dernier recours, temporaire |
Conclusion
Le texte barré dans les PDF issus d’exports VBA avec Excel 365 2409+ n’est pas un « bug » de rendu : c’est la conséquence du marquage visuel des valeurs non recalculées via Format Stale Values. Pour retrouver l’export attendu :
- Forcez un recalcul juste avant l’export, ou
- Basculer temporairement en calcul automatique, ou
- Désactivez la mise en forme « Stale Values » si elle n’apporte aucune valeur à vos utilisateurs.
Avec ces ajustements, vos PDF retrouvent un rendu fidèle, sans texte barré, tout en préservant vos performances et vos flux d’automatisation.
En bref : la solution la plus simple est de désactiver « Mettre en forme les valeurs obsolètes » ou de forcer un recalcul juste avant l’export. Les exemples ci‑dessus vous permettent d’implémenter l’une ou l’autre approche en quelques minutes.