ms access - todos - ¿Escapando caracteres que no son ASCII(o cómo eliminar la lista de materiales?)
consulta de eliminacion access 2007 (2)
Necesito crear un archivo de texto ANSI desde un conjunto de registros de Access que se envía a JSON y YAML. Puedo escribir el archivo, pero la salida está saliendo con los caracteres originales, y necesito escapar de ellos. Por ejemplo, una diéresis-O (ö) debe ser "/ u00f6".
Pensé que codificar el archivo como UTF-8 funcionaría, pero no es así. Sin embargo, después de haber revisado nuevamente la codificación del archivo, si escribe "UTF-8 sin BOM", entonces todo funciona.
¿Alguien sabe cómo hacerlo?
a) Escribir texto como UTF-8 sin BOM, o b) Escribir en ANSI pero escapando de los caracteres que no son ASCII?
Public Sub testoutput()
Set db = CurrentDb()
str_filename = "anothertest.json"
MyFile = CurrentProject.Path & "/" & str_filename
str_temp = "Hello world here is an ö"
fnum = FreeFile
Open MyFile For Output As fnum
Print #fnum, str_temp
Close #fnum
End Sub
... vale ... encontré un código de ejemplo sobre cómo eliminar la lista de materiales. Pensé que sería posible hacerlo de forma más elegante al escribir el texto en primer lugar. No importa. El siguiente código elimina la lista de materiales.
(Esto fue publicado originalmente por Simon Pedersen en http://www.imagemagick.org/discourse-server/viewtopic.php?f=8&t=12705 )
'' Removes the Byte Order Mark - BOM from a text file with UTF-8 encoding
'' The BOM defines that the file was stored with an UTF-8 encoding.
Public Function RemoveBOM(filePath)
'' Create a reader and a writer
Dim writer, reader, fileSize
Set writer = CreateObject("Adodb.Stream")
Set reader = CreateObject("Adodb.Stream")
'' Load from the text file we just wrote
reader.Open
reader.LoadFromFile filePath
'' Copy all data from reader to writer, except the BOM
writer.Mode = 3
writer.Type = 1
writer.Open
reader.Position = 5
reader.CopyTo writer, -1
'' Overwrite file
writer.SaveToFile filePath, 2
'' Return file name
RemoveBOM = filePath
'' Kill objects
Set writer = Nothing
Set reader = Nothing
End Function
Puede ser útil para otra persona.
Tarde en el juego aquí, pero no puedo ser el único programador que se cansó de que mis importaciones de SQL fueran interrumpidas por archivos de texto con un marcador de orden de bytes. Hay muy pocas preguntas de Stack que tocan el problema, este es uno de los más cercanos, así que estoy publicando una respuesta que se superpone aquí.
Digo ''superposición'' porque el código siguiente está resolviendo un problema ligeramente diferente al suyo: el objetivo principal es escribir un archivo de esquema para una carpeta con una colección heterogénea de archivos, pero el segmento de manejo de lista de materiales está claramente marcado.
La funcionalidad clave es que iteramos a través de todos los archivos ''.csv'' en una carpeta, y probamos cada archivo con un mordisco rápido de los primeros cuatro bytes: y solo eliminamos el marcador de orden de bytes si vemos uno.
Después de eso, estamos trabajando en un código de manejo de archivos de bajo nivel desde la C primordial. Tenemos que llegar hasta el uso de matrices de bytes, porque todo lo demás que haga en VBA depositará los Marcadores de Orden de Byte incrustados en el estructura de una variable de cadena .
Entonces, sin más adodb, aquí está el código:
Código BOM-Disposal para archivos de texto en un archivo schema.ini:
Public Sub SetSchema(strFolder As String)
On Error Resume Next
'' Write a Schema.ini file to the data folder.
'' This is necessary if we do not have the registry privileges to set the
'' correct ''ImportMixedTypes=Text'' registry value, which overrides IMEX=1
'' The code also checks for ANSI or UTF-8 and UTF-16 files, and applies a
'' usable setting for CharacterSet ( UNICODE|ANSI ) with a horrible hack.
'' OEM codepage-defined text is not supported: further coding is required
'' ...And we strip out Byte Order Markers, if we see them - the OLEDB SQL
'' provider for textfiles can''t deal with a BOM in a UTF-16 or UTF-8 file
'' Not implemented: handling tab-delimited files or other delimiters. The
'' code assumes a header row with columns, specifies ''scan all rows'', and
'' imposes ''read the column as text'' if the data types are mixed.
Dim strSchema As String
Dim strFile As String
Dim hndFile As Long
Dim arrFile() As Byte
Dim arrBytes(0 To 4) As Byte
If Right(strFolder, 1) <> "/" Then strFolder = strFolder & "/"
'' Dir() is an iterator function when you call it with a wildcard:
strFile = VBA.FileSystem.Dir(strFolder & "*.csv")
Do While Len(strFile) > 0
hndFile = FreeFile
Open strFolder & strFile For Binary As #hndFile
Get #hndFile, , arrBytes
Close #hndFile
strSchema = strSchema & "[" & strFile & "]" & vbCrLf
strSchema = strSchema & "Format=CSVDelimited" & vbCrLf
strSchema = strSchema & "ImportMixedTypes=Text" & vbCrLf
strSchema = strSchema & "MaxScanRows=0" & vbCrLf
If arrBytes(2) = 0 Or arrBytes(3) = 0 Then '' this is a hack
strSchema = strSchema & "CharacterSet=UNICODE" & vbCrLf
Else
strSchema = strSchema & "CharacterSet=ANSI" & vbCrLf
End If
strSchema = strSchema & "ColNameHeader = True" & vbCrLf
strSchema = strSchema & vbCrLf
'' BOM disposal - Byte order marks confuse OLEDB text drivers:
If arrBytes(0) = &HFE And arrBytes(1) = &HFF _
Or arrBytes(0) = &HFF And arrBytes(1) = &HFE Then
hndFile = FreeFile
Open strFolder & strFile For Binary As #hndFile
ReDim arrFile(0 To LOF(hndFile) - 1)
Get #hndFile, , arrFile
Close #hndFile
BigReplace arrFile, arrBytes(0) & arrBytes(1), ""
hndFile = FreeFile
Open strFolder & strFile For Binary As #hndFile
Put #hndFile, , arrFile
Close #hndFile
Erase arrFile
ElseIf arrBytes(0) = &HEF And arrBytes(1) = &HBB And arrBytes(2) = &HBF Then
hndFile = FreeFile
Open strFolder & strFile For Binary As #hndFile
ReDim arrFile(0 To LOF(hndFile) - 1)
Get #hndFile, , arrFile
Close #hndFile
BigReplace arrFile, arrBytes(0) & arrBytes(1) & arrBytes(2), ""
hndFile = FreeFile
Open strFolder & strFile For Binary As #hndFile
Put #hndFile, , arrFile
Close #hndFile
Erase arrFile
End If
strFile = ""
strFile = Dir
Loop
If Len(strSchema) > 0 Then
strFile = strFolder & "Schema.ini"
hndFile = FreeFile
Open strFile For Binary As #hndFile
Put #hndFile, , strSchema
Close #hndFile
End If
End Sub
Public Sub BigReplace(ByRef arrBytes() As Byte, ByRef SearchFor As String, ByRef ReplaceWith As String)
On Error Resume Next
Dim varSplit As Variant
varSplit = Split(arrBytes, SearchFor)
arrBytes = Join$(varSplit, ReplaceWith)
Erase varSplit
End Sub
El código es más fácil de entender si sabes que una matriz de bytes se puede asignar a una VBA.String, y viceversa. La función BigReplace () es un truco que esquiva parte del ineficiente manejo de cadenas de VBA, especialmente la asignación: encontrará que los archivos grandes causan problemas serios de memoria y rendimiento si lo hace de otra manera.