Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - VBA

Страница: 1 | 2 |

 

  Вопрос: Кодировка Unicode в VBA Добавлено: 18.02.09 19:41  

Автор вопроса:  Jktu | ICQ: 381648295 
Проблема в следующем:
Не могу вставить в контрол текст в кодировке Unicode

Код должен переносить слова из файла source.txt в Listbox.
Если я сохраняю txt в кодировке ANSII, то всё нормально, а в Unicode - никак.
Текст должен быть в Unicode, поскольку в нём содержатся буквы ä, ö. Чтобы узнать, код или контрол не видит этих символов, я вставил в код строку
Debug.Prnt Temp
в окне Immediate
(Temp - переменная, которой присваивается строковое значение).
Так вот. Он мне пишет вместо этих букв козябры. То есть код не распознаёт. Ну, и соответственно, в Listbox он вставляет всё те же козябры.
Вот пример интерпретации бейсиком выражения Hyvää päivää:
яюHyvдд pдivдд
(Причём буквы яю в начале присутствуют при любом раскладе).

Пробовал ввести с клавиатуры буквы ä, ö в Textbox. Вводятся а, о.

При этом, когда похожий код пишешь в Excele, то работает всё прекрасно (только код берёт слова с листа excel).

Поискал я по форуму, здесь похожие вопросы уже не раз поднимались. Там советовали подключить библиотеку FM20.dll, и всё, якобы должно получиться.
Подключил.
Без изменений.

Неужели нельзя обойти как-нибудь данную проблему???

Ответить

  Ответы Всего ответов: 21  

Номер ответа: 1
Автор ответа:
 Jktu



ICQ: 381648295 

Вопросов: 8
Ответов: 32
 Профиль | | #1 Добавлено: 18.02.09 19:41
Блин.
Здесь тоже юникод не отображается.

Ответить

Номер ответа: 2
Автор ответа:
 el-paso



Вопросов: 3
Ответов: 164
 Профиль | | #2 Добавлено: 18.02.09 19:45
Почему нельзя? Можно...
Вручную конвертировать все строковые переменные в Unicode и обратно (функция StrConv).

Ответить

Номер ответа: 3
Автор ответа:
 Jktu



ICQ: 381648295 

Вопросов: 8
Ответов: 32
 Профиль | | #3 Добавлено: 19.02.09 17:24
Позвольте, я, наверное, что-то не понимаю...

Объясню ещё раз.

1. Код открывает текстовый файл, сохранённый в Unicode и берёт оттуда набор символов (слово):

  1. F = FreeFile
  2. Open App.Path & "\source.txt" For Input As #F
  3. Do Until EOF(F)


2. Присваивает переменной Temp значение этого слова:

  1.     Input #F, Temp


3. Вставляет его (слово) в Listbox:

  1.     List1.AddItem Temp


4. Вставляются козябры...

После выполнения 2-го пункта в памяти кода вместо слова уже содержатся козябры, как я и писал.

el-paso пишет:
Вручную конвертировать все строковые переменные в Unicode и обратно (функция StrConv).


На каком этапе я должен конвертировать это слово в Unicode (или обратно)?

Ответить

Номер ответа: 4
Автор ответа:
 Jktu



ICQ: 381648295 

Вопросов: 8
Ответов: 32
 Профиль | | #4 Добавлено: 19.02.09 17:28
Вот здесь описывается, кажется, решение этой проблемы.

http://www.cyberactivex.com/UnicodeTutorialVb.htm

Я в английском не силён, если у кого есть время, может быть, посмотрите?

Ответить

Номер ответа: 5
Автор ответа:
 Jasmin



Вопросов: 23
Ответов: 417
 Профиль | | #5 Добавлено: 19.02.09 18:09
Сорри, что влезаю. :-) Просто предложение. Может нужно
  1. Input #F, StrConv(Temp, vbFromUnicode)
? Может поможет ? :-)

Ответить

Номер ответа: 6
Автор ответа:
 el-paso



Вопросов: 3
Ответов: 164
 Профиль | | #6 Добавлено: 19.02.09 22:17
Процедура работы с уникодом в VB и VBA - довольно своеобразна.
Для обработки уникодовского файла его нужно прочитать в байтовый массив, а потом этот массив с помощью StrConv сконвертировать в обычный текст.

Я уже как-то давал на этом форуме примерчик работы с StrConv.
Поищите. Если не получится, я завтра накидаю примерчик.

Ответить

Номер ответа: 7
Автор ответа:
 Jktu



ICQ: 381648295 

Вопросов: 8
Ответов: 32
 Профиль | | #7 Добавлено: 19.02.09 22:32
To Jasmin:

Что Вы, какое сорри, я Вас очень ждал.
Вы мне как-то очень помогли.
А так, как Вы предлагаете (прямо-таки дословно), я уже пробовал (по совету уважаемого el-paso).
Пишет ошибку "Compile error: Variable required - can't assign to this expression".

To el-paso:

Спасибо Вам, попробую поискать, и буду ждать от Вас примерчик.

Ответить

Номер ответа: 8
Автор ответа:
 mc-black



ICQ: 308-534-060 

Вопросов: 20
Ответов: 1860
 Web-сайт: mc-black.narod.ru/dzp.htm
 Профиль | | #8
Добавлено: 20.02.09 09:32
Вчера дома накидал что-то с учетом StrConv, вывод Unicode из файла в ListBox у меня получился, но первый символ вставился левый, вероятно это первые два байта, которые при других условиях выдают "яю", т.е. мой пример надо еще немного дорабатывать. Файл я открывал не как текстовый, а как бинарный и читал N байт в байтовый массив. Кстати, Jktu, ты куда-то не туда пытался считать, что за переменная Temp, какого она типа и т.д.? Результат считывания возвращает сама функция как результат, а не по ссылке в параметр. В общем, пока код у меня не отлаженный нет смысла его выкладывать. Кстати, а почему бы не задать Unicode строки не из файла, а сразу байтовым массивом в приложении? И это.. зачем постим тему по VB6 в раздел по VBA? путаница же получается! А насчет туториала по Unicode в VB6 - спасибо, есть в чем поразбираться, когда Unicode понадобится. Удачи!

Ответить

Номер ответа: 9
Автор ответа:
 mc-black



ICQ: 308-534-060 

Вопросов: 20
Ответов: 1860
 Web-сайт: mc-black.narod.ru/dzp.htm
 Профиль | | #9
Добавлено: 20.02.09 10:41
Если в файле только одна строка, то вывести ее у меня получилось так:
  1. Private Sub UserForm_Initialize()
  2.     Dim sUnicode As String
  3.     Open ThisWorkbook.Path & "\source.txt" For Binary Access Read As #1
  4.     sUnicode = Mid(StrConv(Input(LOF(1), #1), vbFromUnicode), 2)
  5.     ListBox1.AddItem sUnicode
  6.     Close #1
  7. End Sub

Ответить

Номер ответа: 10
Автор ответа:
 mc-black



ICQ: 308-534-060 

Вопросов: 20
Ответов: 1860
 Web-сайт: mc-black.narod.ru/dzp.htm
 Профиль | | #10
Добавлено: 20.02.09 10:50
Получилось наконец-то! Наполняем список построчно из входного файла в Unicode:
  1. Option Explicit
  2.  
  3. Private Sub UserForm_Initialize()
  4.     Dim sUnicode() As String
  5.     Dim i As Long
  6.     
  7.     Open ThisWorkbook.Path & "\source.txt" For Binary Access Read As #1
  8.     sUnicode = Split(Mid(StrConv(Input(LOF(1), #1), vbFromUnicode), 2), vbCrLf)
  9.     Close #1
  10.     
  11.     For i = LBound(sUnicode) To UBound(sUnicode)
  12.         Debug.Print sUnicode(i)
  13.         ListBox1.AddItem sUnicode(i)
  14.     Next i
  15. End Sub

Ответить

Номер ответа: 11
Автор ответа:
 Jktu



ICQ: 381648295 

Вопросов: 8
Ответов: 32
 Профиль | | #11 Добавлено: 20.02.09 20:13
mc-black, дорогой, ничего не получается.

Пишет "type mismatch" в этой строке:
sUnicode = Split(Mid(StrConv(Input(LOF(1), #1), vbFromUnicode), 2), vbCrLf),
а именно в этом месте:
Input(LOF(1), #1)

Я уже и номер файла менял по-всякому и переменные...

В экселе - работает, не пойму почему.

А подскажи мне, пожалуйста - как это:

mc-black пишет:
 задать Unicode строки не из файла, а сразу байтовым массивом в приложении
?

Ответить

Номер ответа: 12
Автор ответа:
 el-paso



Вопросов: 3
Ответов: 164
 Профиль | | #12 Добавлено: 20.02.09 23:07
  1.  
  2.  
  3. Public Function LoadUnicodeFile(FileName As String, Optional LocaleID As Long = 1049) As String
  4.     '
  5.     Dim s As String
  6.     Dim f As Integer: f = FreeFile
  7.     '
  8.     Open FileName For Binary Access Read As f
  9.     s = Space(LOF(f) - 2)
  10.     Seek #f, 3
  11.     Get #f, , s
  12.     Close #f
  13.     '
  14.     UnicodeFileContents = StrConv(s, vbFromUnicode, LocaleID)
  15.     '
  16. End Function
  17.  
  18. Public Sub SaveUnicodeFile(FileName As String, Text As String, Optional LocaleID As Long = 1049)
  19.     '
  20.     Dim s As String: s = Text
  21.     Dim f As Integer: f = FreeFile
  22.     '
  23.     s = Chr(255) & Chr(254) & StrConv(s, vbUnicode, LocaleID)
  24.     '
  25.     Open FileName For Binary As #f
  26.     Put #f, , s
  27.     Close #f
  28.     '
  29. End Sub
  30.  



Текст, загруженный первой функцией нормально выводится на контролы в формах VBA.

Есть еще там один необязательный "волшебный" параметр - LocaleID... Это идентификатор локали - той самой что зависит от региональных настроек Windows. Я по умолчанию поставил русскую локаль (1049). Вы можете ставить свою - список можно найти в нете.
В большинстве случаев он вам не понадобится - просто у меня на работе используются две штуки :)

Ответить

Номер ответа: 13
Автор ответа:
 el-paso



Вопросов: 3
Ответов: 164
 Профиль | | #13 Добавлено: 20.02.09 23:33
UnicodeFileContents = StrConv(s, vbFromUnicode, LocaleID)


Чуток промахнулся... Правильно будет:
LoadUnicodeFile = StrConv(s, vbFromUnicode, LocaleID)

Ответить

Номер ответа: 14
Автор ответа:
 Jktu



ICQ: 381648295 

Вопросов: 8
Ответов: 32
 Профиль | | #14 Добавлено: 21.02.09 20:42
el-paso, спасибо Вам огромное. Вроде бы код всё читает правильно. Сохраняет в текстовый файл Вашей процедурой SaveUnicodeFile тоже замечательно.

Теперь я уверен, что в памяти VB хранятся символы в юникоде.

Но часть проблемы осталась.

Написал я такой код (с Вашей помощью), чтобы проверить, что он (VB), собственно, хранит в памяти:
  1.  
  2. Dim S As String
  3. Dim F As Integer
  4.  
  5. Private Sub Form_Load()
  6.  
  7. S = LoadUnicodeFile(App.Path & "\source_unicode.txt", 1035)
  8. Text1.Text = S
  9. MsgBox AscW(Mid(Text1.Text, 1, 1))
  10. MsgBox AscW(Mid(S, 1, 1))
  11.  
  12. End Sub
  13.  
  14. Public Function LoadUnicodeFile(FileName As String, Optional LocaleID As Long = 1035) As String
  15.     
  16. F = FreeFile
  17. Open FileName For Binary Access Read As F
  18. S = Space(LOF(F) - 2)
  19. Seek #F, 3
  20. Get #F, , S
  21. Close #F
  22. LoadUnicodeFile = StrConv(S, vbFromUnicode, LocaleID)
  23.     
  24. End Function


Поставил в файле source_unicode.txt первым символом "а" с умляутом;
Первый Msgbox мне выдал "97" ("а";), а второй - "228" ("а" с умляутом)

То есть в памяти VB хранит как и надо, в Юникоде, а вот в Textbox вставляет простые буквы a и o, без умляутов.

Ну, что скажете?

Ответить

Номер ответа: 15
Автор ответа:
 Jktu



ICQ: 381648295 

Вопросов: 8
Ответов: 32
 Профиль | | #15 Добавлено: 21.02.09 20:44
Блин, откуда смайлик взялся?

Ответить

Страница: 1 | 2 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам