Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft Access Новый топик    Ответить
 Импорт файлов в формате ANSI, UTF-8 и UTF-16  [new]
Joss
Member

Откуда: г. Минск
Сообщений: 5209
Продолжение поста Импорт CSV файла в Access

Вынес в отдельную ветку,

Проблема следующая.
Excel и Access работают с форматом ANSI (насколько я знаю). Для ввода в программу присылают файлы CSV (те же текстовики) в форматах ANSI, UTF-8 и UTF-16
ANSI и UTF-16 грузятся без проблем (от UTF-16 не ожидал), а вот UTF-8 нормально загрузить не могу. Использую для конвертации в ANSI стороннюю программу Recode (маленькая, работает без установки хелпа нет, так что про командный режим нет данных).
Но начальство хочет, чтобы всё решалось в одной программе и никаких лишних телодвижений (женщины-операторы).

Пробовал грузить вручную через "Внешние данные"

Вот и возникает вопрос, как программно определить формат файла и как обработать файл в формате UTF-8.

Пример файла UTF-8 прикрепляю. Если надо то и программу кину.


-------------------------------------------------------------
Мы рождены чтоб сказки сделать былью! Даже самые страшные...

К сообщению приложен файл (products_utf8.csv - 1Kb) cкачать
22 ноя 21, 18:57    [22399306]     Ответить | Цитировать Сообщить модератору
 Re: Импорт файлов в формате ANSI, UTF-8 и UTF-16  [new]
I2S
Member

Откуда:
Сообщений: 40
для UTF8:

Option Compare Database

Option Explicit

Private Declare Function MultiByteToWideChar Lib "kernel32.dll" (ByVal CodePage As Long, ByVal dwFlags As Long, ByVal lpMultiByteStr As String, ByVal cchMultiByte As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long) As Long
Private Declare Function WideCharToMultiByte Lib "kernel32.dll" (ByVal CodePage As Long, ByVal dwFlags As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long, ByVal lpMultiByteStr As Long, ByVal cchMultiByte As Long, ByVal lpDefaultChar As Long, ByVal lpUsedDefaultChar As Long) As Long

Public Function ToUTF8(ByVal sText As String) As String
Dim nRet As Long, strRet As String

strRet = String(Len(sText) * 2, vbNullChar)
nRet = WideCharToMultiByte(65001, &H0, StrPtr(sText), Len(sText), StrPtr(strRet), Len(sText) * 2, 0&, 0&)

ToUTF8 = Left(StrConv(strRet, vbUnicode), nRet)
End Function

Public Function FromUTF8(ByVal sText As Variant) As String
Dim nRet As Long, strRet As String

sText = Nz(sText, "")

strRet = String(Len(sText), vbNullChar)
nRet = MultiByteToWideChar(65001, &H0, sText, Len(sText), StrPtr(strRet), Len(strRet))

FromUTF8 = Left(strRet, nRet)
End Function

Сообщение было отредактировано: 22 ноя 21, 19:44
22 ноя 21, 19:42    [22399333]     Ответить | Цитировать Сообщить модератору
 Re: Импорт файлов в формате ANSI, UTF-8 и UTF-16  [new]
Joss
Member

Откуда: г. Минск
Сообщений: 5209
Спасибо, попробую.
22 ноя 21, 20:04    [22399348]     Ответить | Цитировать Сообщить модератору
 Re: Импорт файлов в формате ANSI, UTF-8 и UTF-16  [new]
alecko
Member

Откуда: Башкирия
Сообщений: 849
Joss, творение не мое, не тестил на примере.

К сообщению приложен файл (UTF8.bas - 4Kb) cкачать
23 ноя 21, 00:32    [22399482]     Ответить | Цитировать Сообщить модератору
 Re: Импорт файлов в формате ANSI, UTF-8 и UTF-16  [new]
Eugene-LS
Member

Откуда: РФ
Сообщений: 63
Joss
Пример файла UTF-8 прикрепляю. Если надо то и программу кину.

Примерно так можно:
Private Sub test01()
'Перекодирование файла из UTF-8 в ANSI/1251
Dim obj As Object, sVal$

    sVal = "d:\Temp\products_utf8.csv"

    Set obj = CreateObject("ADODB.Stream")
    obj.Charset = "utf-8"
    obj.Open
    obj.LoadFromFile (sVal)
    sVal = obj.ReadText()

    Debug.Print sVal
    
End Sub
23 ноя 21, 01:25    [22399485]     Ответить | Цитировать Сообщить модератору
 Re: Импорт файлов в формате ANSI, UTF-8 и UTF-16  [new]
Joss
Member

Откуда: г. Минск
Сообщений: 5209
Спасибо, попробую все предложенные варианты.

Правда в предложении Eugene-LS придётся кое-что переделать. Входной файл может достигать несколько сотен КБ, так что скорее всего придётся считывать по строкам.

Сообщение было отредактировано: 23 ноя 21, 14:14
23 ноя 21, 14:11    [22399681]     Ответить | Цитировать Сообщить модератору
 Re: Импорт файлов в формате ANSI, UTF-8 и UTF-16  [new]
Кривцов Анатолий
Member

Откуда:
Сообщений: 627
Joss
Вот и возникает вопрос, как программно определить формат файла и как обработать файл в формате UTF-8.
Для файлов в UTF кодировке предусмотрен признак кодировки (называется BOM - дополнительные первые 2-3 байта). Но он не обязательный и в вашем примере его нет. Прочитать BOM можно, открыв файл как бинарный, а если его нет, то определить, что это UTF-16 легко, а ANSI или UTF-8 - это еще те танцы с бубном, и лезть туда не советую.
Попробуйте такой код. Он читает указанный файл, автоматически определяя кодировку, и сохраняет копию в ANSI, заменяя существующий.
    Dim lobjStream As ADODB.Stream
    Dim lobjTarget As ADODB.Stream
        
    Set lobjStream = New ADODB.Stream
    Set lobjTarget = New ADODB.Stream
        
    lobjStream.Open
    lobjTarget.Open
    
    lobjStream.Charset = "_autodetect_all" 'просто немного подлый - учтите, что автоопределение работает не для всех кодировок
    lobjStream.LoadFromFile lsFileSource
    
    lobjTarget.Charset = "windows-1251"
    lobjStream.CopyTo lobjTarget
    lobjTarget.SaveToFile lsFileToCopy, adSaveCreateOverWrite
О результате сообщите, пжл.
23 ноя 21, 16:49    [22399777]     Ответить | Цитировать Сообщить модератору
 Re: Импорт файлов в формате ANSI, UTF-8 и UTF-16  [new]
galalex
Member

Откуда:
Сообщений: 6
Наиболее правильным вариантом будет читать текстовый файл с разделителями используя ADO.Recordset через через Microsoft Text ODBC Driver, подробно изложено здесь Экспорт денежного поля в формат CSV. К сожалению, драйвер не поддерживает преобразование из UTF-8. Поэтому текстовые поля в UTF-8 из ADO.Recordset следует преобразовывать функцией FromUTF8():
' CodePage constant for UTF-8
Private Const CP_UTF8 As Long = 65001
' Maps a character string to a UTF-16 (wide character) string
Private Declare Function MultiByteToWideChar Lib "kernel32.dll" ( _
    ByVal CodePage As Long, _
    ByVal dwFlags As Long, _
    ByVal lpMultiByteStr As String, _
    ByVal cchMultiByte As Long, _
    ByVal lpWideCharStr As Long, _
    ByVal cchWideChar As Long) As Long
' Maps a UTF-16 (wide character) string to a new character string
Private Declare Function WideCharToMultiByte Lib "kernel32.dll" ( _
    ByVal CodePage As Long, _
    ByVal dwFlags As Long, _
    ByVal lpWideCharStr As Long, _
    ByVal cchWideChar As Long, _
    ByVal lpMultiByteStr As Long, _
    ByVal cchMultiByte As Long, _
    ByVal lpDefaultChar As Long, _
    ByVal lpUsedDefaultChar As Long) As Long
  
Public Function ToUTF8(ByVal Value As String) As String
    Dim nRet As Long
    Dim strRet As String
    strRet = String(Len(Value) * 2, vbNullChar)
    nRet = WideCharToMultiByte(CP_UTF8, &H0, StrPtr(Value), Len(Value), StrPtr(strRet), Len(Value) * 2, 0&, 0&)
    ToUTF8 = Left$(StrConv(strRet, vbUnicode), nRet)
End Function
 
Public Function FromUTF8(ByVal Value As String) As String
    Dim nRet As Long
    Dim strRet As String
    strRet = String(Len(Value), vbNullChar)
    nRet = MultiByteToWideChar(CP_UTF8, &H0, Value, Len(Value), StrPtr(strRet), Len(strRet))
    FromUTF8 = Left$(strRet, nRet)
End Function
25 ноя 21, 08:53    [22400494]     Ответить | Цитировать Сообщить модератору
 Re: Импорт файлов в формате ANSI, UTF-8 и UTF-16  [new]
Панург
Member

Откуда: настоящему индейцу завсегда везде ништяк
Сообщений: 5361
galalex, сАвсем не читатель? Первый же ответ 22399333. Набираешь сообщения?

Сообщение было отредактировано: 25 ноя 21, 10:37
25 ноя 21, 10:36    [22400543]     Ответить | Цитировать Сообщить модератору
 Re: Импорт файлов в формате ANSI, UTF-8 и UTF-16  [new]
galalex
Member

Откуда:
Сообщений: 6
Панург,
1. Решение, предложенное I2S, решением исходной задачи не является, и даже полурешением. Это лишь начальная стадия изобретения велосипеда.
2. Если ты сегодня не понимаешь важности ясности кода - твоя проблема.
3. Насчёт "Набираешь сообщения" ))). Не поверишь, я день ржал )). Спасибо тебе за отличное настроение. В моём личном рейтинге ты соревнуешься с Рожковым за лучшую шутку ноября 21.
вчера, 21:44    [22401540]     Ответить | Цитировать Сообщить модератору
 Re: Импорт файлов в формате ANSI, UTF-8 и UTF-16  [new]
Панург
Member

Откуда: настоящему индейцу завсегда везде ништяк
Сообщений: 5361
galalex
я день ржал
конь? Продолжай в том же духе.
galalex
2. Если ты сегодня не понимаешь важности ясности кода - твоя проблема.
смотри не лопни от собственной значимости.
galalex
21.
видимо не отпустило.

Сообщение было отредактировано: вчера, 21:49
вчера, 21:46    [22401541]     Ответить | Цитировать Сообщить модератору
 Re: Импорт файлов в формате ANSI, UTF-8 и UTF-16  [new]
Панург
Member

Откуда: настоящему индейцу завсегда везде ништяк
Сообщений: 5361
galalex
1. Решение, предложенное I2S, решением исходной задачи не является, и даже полурешением. Это лишь начальная стадия изобретения велосипеда.

galalex, да, забыл сказать, это практически один в один одинаковый код с тем что ты гордо тиснул тут

Сообщение было отредактировано: вчера, 22:13
вчера, 22:12    [22401549]     Ответить | Цитировать Сообщить модератору
 Re: Импорт файлов в формате ANSI, UTF-8 и UTF-16  [new]
galalex
Member

Откуда:
Сообщений: 6
Панург, значимость это у тебя, иначе скромнее бы был. "Молодец среди овец, а против молодца сам овца". Заканчивай своей пустой болтовнёй "набирать сообщения".
вчера, 23:12    [22401569]     Ответить | Цитировать Сообщить модератору
 Re: Импорт файлов в формате ANSI, UTF-8 и UTF-16  [new]
galalex
Member

Откуда:
Сообщений: 6
Панург
galalex
1. Решение, предложенное I2S, решением исходной задачи не является, и даже полурешением. Это лишь начальная стадия изобретения велосипеда.

galalex, да, забыл сказать, это практически один в один одинаковый код с тем что ты гордо тиснул тут

Ты походу даже не врубаешься в смысл сказанных мною слов. Тебе помочь догадаться, или сам допрёшь, коль такой важный?
вчера, 23:21    [22401571]     Ответить | Цитировать Сообщить модератору
 Re: Импорт файлов в формате ANSI, UTF-8 и UTF-16  [new]
Панург
Member

Откуда: настоящему индейцу завсегда везде ништяк
Сообщений: 5361
galalex
Ты походу даже не врубаешься в смысл сказанных мною слов. Тебе помочь догадаться, или сам допрёшь, коль такой важный?
ну-ка, просвети! Что остановился?
сегодня, 08:21    [22401660]     Ответить | Цитировать Сообщить модератору
 Re: Импорт файлов в формате ANSI, UTF-8 и UTF-16  [new]
Панург
Member

Откуда: настоящему индейцу завсегда везде ништяк
Сообщений: 5361
galalex
коль такой важный

не, я не важный. Важный, по твоим словам ты.
забористые у тебя вещества

Сообщение было отредактировано: сегодня, 08:33
сегодня, 08:23    [22401661]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft Access Ответить