TL;DR —
Print #etWrite #é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 parInput #. UtiliserWrite #pour un CSV lisible par un humain, voilà pourquoi le vôtre est plein de guillemets ; utilisezPrint #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 Outputvide tandis queFor Appendajoute - 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 uneMsgBox— 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#,Trueen#TRUE#, etEmptyen#NULL#. C'est un format de sérialisation, conçu pour queInput #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 :
- Mode —
For Outputréécrit le fichier depuis zéro à chaque exécution ;For Appendajoute à la fin. Un journal qui s'accumule tel queC:\Logs\run.logdoit être ouvertFor 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 produire3,5, dont la virgule entre en collision avec votre séparateur CSV et scinde un nombre en deux colonnes. Forcez un point avecFormat(x, "0.00")ouStr(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, utilisezADODB.Streamou leCreateTextFile(path, True, True)duFileSystemObject.
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 queInput #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
