VBA: guarde un archivo con UTF-8 sin BOM
excel-vba vbscript (2)
En el mejor de los mundos posibles, la lista relacionada contendría una referencia a esta pregunta que encontré como el primer éxito para "vbscript adodb.stream bom vbscript site: stackoverflow.com".
Basado en la segunda estrategia de la respuesta de boost :
Option Explicit
Const adSaveCreateNotExist = 1
Const adSaveCreateOverWrite = 2
Const adTypeBinary = 1
Const adTypeText = 2
Dim objStreamUTF8 : Set objStreamUTF8 = CreateObject("ADODB.Stream")
Dim objStreamUTF8NoBOM : Set objStreamUTF8NoBOM = CreateObject("ADODB.Stream")
With objStreamUTF8
.Charset = "UTF-8"
.Open
.WriteText "aÄö"
.Position = 0
.SaveToFile "toto.php", adSaveCreateOverWrite
.Type = adTypeText
.Position = 3
End With
With objStreamUTF8NoBOM
.Type = adTypeBinary
.Open
objStreamUTF8.CopyTo objStreamUTF8NoBOM
.SaveToFile "toto-nobom.php", adSaveCreateOverWrite
End With
objStreamUTF8.Close
objStreamUTF8NoBOM.Close
Evidencia:
chcp
Active code page: 65001
dir
...
15.07.2015 18:48 5 toto-nobom.php
15.07.2015 18:48 8 toto.php
type toto-nobom.php
aÄö
Probablemente sea algo simple, esto es lo que probé:
Set objStream = CreateObject("ADODB.Stream")
Set objStreamNoBOM = CreateObject("ADODB.Stream")
With objStream
.Open
.Charset = "UTF-8"
.WriteText "aaaaaa"
.Position = 0
End With
With objStreamNoBOM
''.Charset = "Windows-1252" '' WORK
.Charset = "UTF-8" '' DOESN''T WORK!!
.Open
.Type = 2
.WriteText objStream.ReadText
.SaveToFile "toto.php", 2
.Close
End With
objStream.Close
si el juego de caracteres es UTF-8, entonces hay ï »al comienzo del archivo.
¿Alguna idea sobre cómo guardar un archivo con UTF-8 y sin BOM?
Sabía que la secuencia del objeto del sistema de archivos de secuencias de comandos insertaba una marca de orden de bytes, pero no lo había visto con la secuencia ADODB.
O al menos, todavía no: rara vez uso el objeto de secuencia ADODB ...
Pero sí recuerdo poner este comentario en algún código hace unos años:
'' **** WHY THIS IS COMMENTED OUT **** **** **** **** **** **** **** ****
''
'' Microsoft ODBC and OLEDB database drivers cannot read the field names from
'' the header when a unicode byte order mark (&HFF & &HFE) is inserted at the
'' start of the text by Scripting.FileSystemObject ''Write'' methods. Trying to
'' work around this by writing byte arrays will fail; FSO ''Write'' detects the
'' string encoding automatically, and won''t let you hack around it by writing
'' the header as UTF-8 (or ''Narrow'' string) and appending the rest as unicode
''
'' (Yes, I tried some revolting hacks to get around it: don''t *ever* do that)
''
'' **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
''
'' With FSO.OpenTextFile(FilePath, ForWriting, True, TristateTrue)
'' .Write Join(arrTemp1, EOROW)
'' .Close
'' End With '' textstream object from objFSO.OpenTextFile
''
'' **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
Se nota que estaba teniendo un mal día.
Luego, usando los comandos PUT prehistóricos de los días previos a que el manejo de archivos surgiera del C primordial:
'' **** WHY WE ''PUT'' A BYTE ARRAY INSTEAD OF A VBA STRING VARIABLE **** ****
''
'' Put #hndFile, , StrConv(Join(arrTemp1, EOROW), vbUnicode)
'' Put #hndFile, , Join(arrTemp1, EOROW)
''
'' If you pass unicode, Wide or UTF-16 string variables to PUT, it prepends a
'' Unicode Byte Order Mark to the data which, when written to your file, will
'' render the field names illegible to Microsoft''s JET ODBC and ACE-OLEDB SQL
'' drivers (which can actually read unicode field names, if the helpful label
'' isn''t in the way). However, the ''PUT'' statements writes a Byte array as-is
''
'' **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
Entonces está el código que realmente lo hace:
Dim arrByte() As Byte
Dim strText As String
Dim hndFile As String
strText = "Y''all knew that strings are actually byte arrays?"
arrByte = strText
hndFile = FreeFile
Open FilePath For Binary As #hndFile
Put #hndFile, , arrByte
Close #hndFile
Erase arrByte
Supongo que strText es en realidad UTF-8. Quiero decir, estamos en VBA, en Microsoft Office, y sabemos absolutamente que esto siempre será UTF-8, incluso si lo usamos en un país extranjero ...
...¿Derecho?