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

VBA Print # vs Write # dans Excel — écrire un fichier texte ou un CSV (et pourquoi le vôtre a des guillemets partout)

|

VBA Print # vs Write # dans Excel — écrire un fichier texte ou un CSV (et pourquoi le vôtre a des guillemets partout)

TL;DRPrint # et Write # écrivent dans un fichier selon des styles opposés. Print # écrit le texte exactement tel qu'il apparaît — pas de guillemets, pas de virgules, c'est vous qui insérez les séparateurs. Write # écrit un format machine — chaque chaîne entre guillemets, des virgules entre les valeurs, les dates en #...# — fait pour être relu par Input #. Utiliser Write # pour un CSV lisible par un humain, voilà pourquoi le vôtre est plein de guillemets ; utilisez Print # et construisez la ligne vous-même.

' Write # - format machine, guillemets autour de chaque chaine :
Write #n, "Ann", "Rome", 42      ' le fichier obtient :  "Ann","Rome",42

' Print # - vous controlez la mise en forme, pas de guillemets :
Print #n, "Ann" & "," & "Rome" & "," & 42   ' le fichier obtient :  Ann,Rome,42

Dès qu'une macro peut ouvrir un canal, la décision suivante est de savoir à quoi les octets devraient ressembler sur le disque — et VBA vous donne deux instructions qui répondent à cette question de façons complètement opposées. Print # écrit ce que vous voyez ; Write # écrit ce qu'un programme peut réanalyser. Choisissez la mauvaise et le fichier est techniquement valide mais inutile pour celui qui l'ouvre ensuite : un CSV noyé sous les guillemets, ou un « CSV » dont toutes les colonnes tiennent dans une seule cellule. Savoir quelle instruction produit quels octets, c'est tout le métier.

Ce que vous allez apprendre

  • Le modèle mental — Print # écrit ce que vous voyez, Write # écrit ce qu'un programme relit
  • Pourquoi Write # met des guillemets autour de chaque chaîne (et quand c'est exactement ce qu'il faut)
  • Pourquoi une virgule dans une liste Print # insère des zones d'impression, pas des virgules CSV
  • Comment construire une ligne CSV propre avec Print # et vos propres séparateurs
  • Pourquoi For Output vide tandis que For Append ajoute
  • Le piège de la virgule décimale liée à la locale, et pourquoi l'écriture intégrée est en ANSI, pas en UTF-8

Le modèle mental : format d'affichage vs format machine

L'idée qui règle presque toute question « pourquoi mon fichier a-t-il cette tête » : Print # et Write # servent deux lecteurs différents.

  • Print # écrit le format d'affichage. Il pose le texte sur le disque exactement comme il apparaîtrait dans une cellule ou une MsgBox — pas de guillemets, pas de séparateurs automatiques, pas de marqueurs de type. C'est vous qui décidez la mise en forme.
  • Write # écrit le format machine. Il entoure chaque chaîne de guillemets, sépare les valeurs par des virgules, écrit les dates en #2026-01-31#, True en #TRUE#, et Empty en #NULL#. C'est un format de sérialisation, conçu pour que Input # puisse relire exactement les mêmes valeurs.

Le choix n'est donc jamais une affaire de goût — il s'agit de savoir qui lit le fichier ensuite. Un programme qui le réanalysera avec Input # veut Write #. Un humain, Excel, ou tout autre outil veut Print #.

Pourquoi Write # remplit votre CSV de guillemets

C'est la plainte numéro un, et ce n'est pas un bug — c'est Write # qui fait son travail :

Write #n, "Ann", "Rome", 42
' fichier :  "Ann","Rome",42

Ces guillemets sont délibérés : ils permettent à Input # de distinguer une chaîne contenant une virgule ("Rome, Italy") de deux champs séparés. Parfait pour un aller-retour VBA-vers-VBA ; faux pour un rapport qu'une personne ouvre. Quand quelqu'un demande « pourquoi mon CSV exporté est-il plein de guillemets », la réponse est toujours la même — le code a utilisé Write # alors qu'il voulait Print #.

Write # est le bon outil dans exactement une situation : vous avez écrit le fichier avec Write # et vous le relirez avec Input #, entièrement à l'intérieur de VBA. Pour tout ce qu'un humain ou Excel ouvre, tournez-vous vers Print #.

Pourquoi une virgule dans Print # n'est pas une virgule CSV

Le correctif évident — « il suffit d'utiliser Print # avec des virgules » — a son propre piège, parce que la virgule signifie autre chose dans une liste Print # :

Print #n, "Ann", "Rome", 42     ' PAS Ann,Rome,42

Une virgule entre les éléments d'une liste Print # insère une zone d'impression — une tabulation tous les 14 caractères environ, un vestige de l'impression console. La ligne ci-dessus ressort donc avec de larges espaces, pas des virgules, et votre « CSV » s'ouvre en une seule colonne massacrée. Le correctif est d'empêcher Print # d'insérer des séparateurs et de construire toute la ligne vous-même :

Print #n, "Ann" & "," & "Rome" & "," & 42   ' Ann,Rome,42  - une seule chaine que vous controlez

Concaténez les champs avec le séparateur littéral que vous voulez, passez à Print # une seule chaîne, et vous obtenez exactement ces octets. Un point-virgule final (Print #n, s;) supprime le saut de ligne quand vous devez assembler une ligne par morceaux.

Construire une vraie ligne CSV avec Print

En réunissant le tout, le motif fiable « écrire un CSV » joint chaque ligne en une seule chaîne et laisse Print # l'émettre telle quelle :

Sub ExportRange(ByVal rng As Range, ByVal path As String)
    Dim n As Integer, r As Range, cell As Range, line As String
    n = FreeFile
    Open path For Output As #n              ' vide ; utilisez Append pour ajouter
    For Each r In rng.Rows
        line = ""
        For Each cell In r.Cells
            line = line & cell.Value & ","  ' votre delimiteur, vos regles
        Next cell
        If Len(line) > 0 Then line = Left(line, Len(line) - 1)  ' supprime la virgule finale
        Print #n, line                      ' une ligne complete, exactement telle que construite
    Next r
    Close #n
End Sub

C'est la forme que prend presque tout export CSV de production, car c'est la seule façon de contrôler précisément les guillemets et les séparateurs. Si un champ peut lui-même contenir une virgule, entourez ce champ de guillemets vous-même — c'est une décision que Print # vous laisse, ce qui est bien l'intérêt.

Output vide, Append ajoute — et les pièges de la locale et de l'encodage

Deux détails de plus décident si le fichier est correct :

  • ModeFor Output réécrit le fichier depuis zéro à chaque exécution ; For Append ajoute à la fin. Un journal qui s'accumule tel que C:\Logs\run.log doit être ouvert For Append, sinon chaque exécution efface la précédente.
  • Virgule décimale — sur un système allemand, français ou espagnol, CStr(3.5) peut produire 3,5, dont la virgule entre en collision avec votre séparateur CSV et scinde un nombre en deux colonnes. Forcez un point avec Format(x, "0.00") ou Str(x) (qui utilise toujours .), ou entourez les champs numériques de guillemets.
  • Encodage — le Print # intégré écrit en ANSI, pas en UTF-8. Un texte accentué ou non latin (é, ü, 日本語) est écrit dans la page de code système et se corrompt quand le fichier est ouvert en UTF-8. Pour une sortie Unicode, utilisez ADODB.Stream ou le CreateTextFile(path, True, True) du FileSystemObject.

Le verdict honnête : choisissez selon qui lit le fichier

Print # et Write # ne sont pas interchangeables, et toute la décision se ramène à une seule question :

  • Write # seulement pour les allers-retours VBA-vers-VBA → ses guillemets, ses virgules et ses marqueurs #...# existent pour que Input # puisse reconstruire les valeurs exactes. Un humain ne devrait jamais les voir.
  • Print # pour tous les autres → construisez chaque ligne vous-même avec les séparateurs que vous voulez ; une virgule dans une liste Print # est une zone d'impression, pas un séparateur.
  • Append pour accumuler, Output pour réécrire → le mode décide si l'historique survit.
  • Forcez . et passez à l'UTF-8 pour un vrai CSV → parez le piège de la virgule décimale liée à la locale et le piège de l'encodage ANSI avant que le fichier ne quitte votre machine.

Le signal le plus clair que vous avez choisi la mauvaise instruction, ce sont des guillemets que vous n'avez pas demandés. S'ils apparaissent, vous avez écrit avec Write # ; passez à Print # et prenez la mise en forme en main.

Comment ExcelMaster aide

Exporter des données propres, c'est savoir que Write # entoure tout de guillemets pour Input #, qu'une virgule dans Print # est une zone d'impression plutôt qu'un séparateur, que For Output vide le fichier tandis que For Append le fait grossir, et qu'une virgule décimale ou un encodage ANSI peut corrompre silencieusement un CSV — beaucoup de jugement pour « écrire un fichier ».

ExcelMaster écrit l'export qui s'ouvre proprement. Décrivez la tâche — « enregistre cette plage en CSV », ou « ajoute une ligne à un journal à chaque exécution » — et il produit le constructeur de ligne Print # avec les bons séparateurs, le mode correct, et un formatage de nombre sûr vis-à-vis de la locale, ancré à ThisWorkbook.Path. Vous décrivez le fichier qu'une personne ou un programme doit lire ; il écrit le code qui produit exactement ces octets.

Questions fréquentes

Quelle est la différence entre Print # et Write # en VBA ?

Print # écrit le texte exactement tel qu'il apparaît — pas de guillemets et pas de séparateurs, c'est donc vous qui contrôlez la mise en forme. Write # écrit un format lisible par une machine — chaque chaîne entourée de guillemets, des virgules entre les valeurs, et les dates en #...# — conçu pour être relu par Input #. Utilisez Print # pour tout ce qu'un humain ou Excel ouvre, et Write # uniquement pour les fichiers que vous relirez en VBA avec Input #.

Pourquoi mon CSV VBA est-il plein de guillemets ?

Parce que le code a utilisé Write #, qui entoure délibérément chaque chaîne de guillemets pour que Input # puisse la réanalyser. C'est correct pour un aller-retour VBA-vers-VBA mais faux pour un rapport. Passez à Print # et construisez chaque ligne vous-même — Print #n, a & "," & b — pour obtenir un CSV propre sans guillemets superflus.

Pourquoi Print # ne sépare-t-il pas mes valeurs par des virgules ?

Une virgule entre les éléments d'une liste Print # insère une zone d'impression (une tabulation tous les 14 caractères environ), pas une virgule CSV, si bien que les champs ressortent avec de larges espaces dans une seule colonne. Passez plutôt à Print # une seule chaîne concaténée — Print #n, a & "," & b & "," & c — pour que les séparateurs soient exactement ceux que vous avez écrits.

Comment écrire un fichier texte sans l'écraser en VBA ?

Ouvrez-le For Append plutôt que For Output. For Output vide le fichier avant d'écrire, si bien que chaque exécution efface le contenu précédent ; For Append crée le fichier s'il est absent et sinon ajoute à la fin. Prenez le numéro de canal de FreeFile et fermez-le avec Close #n quand vous avez terminé.

Comment écrire de l'UTF-8 ou des caractères accentués dans un fichier en VBA ?

Le Print # et le Write # intégrés écrivent en ANSI dans la page de code système, si bien qu'un texte accentué ou non latin se corrompt quand le fichier est lu en UTF-8. Pour une sortie Unicode, utilisez ADODB.Stream, ou le CreateTextFile(path, True, True) du FileSystemObject, où le dernier argument demande l'Unicode. Forcez aussi un point décimal avec Format(x, "0.00") pour qu'une virgule décimale liée à la locale ne casse pas vos séparateurs.

Testé dans

Testé dans : Excel 365 (Windows 11), VBA 7.1 — vérifié le 25/08/2026.

Guides associés : VBA FreeFile & Open · VBA Read Text File · VBA FileSystemObject · VBA Save Workbook · VBA CurDir