1 (изменено: Евген, 2013-11-12 17:41:46)

Тема: VBS: Перекодировка текста из UTF-8

Коллеги, приветствую !
Столкнулся со следующей проблемой, в процессе выполнения SQL запроса к Firebird'овской базе получаю следующий ответ, содержащий русские символы в виде кракозябров:

"CZE Р_Р_Р_Р°С?Р° IND 1-5"
"CZE Р'С<Р_Р°С?Р° РўР_"
"SPA Р'С<Р_Р°С?Р° РўР_"
"CZE Р_Р_Р_Р°С?Р° IND 1-5"

Сохранил его в текстовый файл и открыл в Notepad++, чтобы узнать кодировку, выдало "UTF-8 without BOM"
пробовал перекодировать полученный текст в читаемый вид следующим кодом:


Set cn = CreateObject ("ADODB.Connection")
cn.Open "Provider=LCPI.IBProvider.3;Data Source=C:\VS2010\firebird\AKIS_newDB\akisdb.fdb;User Id=SYSDBA;password=masterkey;ctype=none;auto_commit=true"
Set rs = cn.execute("select Q_MENU.MNU_NAME from Q_FIFO , Q_MENU where Q_FIFO.FHI_CLINR is null and Q_FIFO.FHI_QNR=Q_MENU.MNU_QNR")


do while not rs.EOF
       wscript.echo converter(rs.fields(0).Value)
rs.MoveNext
loop

rs.close
cn.close

function converter(strinput)
    adReadAll = -1
    adTypeText = 2
Set objStream = CreateObject("ADODB.Stream")    
    objStream.Open()
    objStream.Type = adTypeText
    objStream.Charset = "utf-8"
    objStream.WriteText(strinput)
    objStream.Flush()
    objStream.Position = 0
    objStream.Charset = "windows-1251"
    converter = objStream.ReadText(adReadAll)
    objStream.Close()
end function

Не помогает - кракозябры
А должно получиться следующее

"CZE Подача IND 1-5"
"CZE Выдача ТА"
"SPA Выдача ТА"
"CZE Подача IND 1-5"

Need help !!!

Времени не хватает... :-(

2

Re: VBS: Перекодировка текста из UTF-8

Не знаю как правильно переписать на VB, а на JS будет примерно так:


function decode(utftext) 
{
   var str = [], toS = String.fromCharCode;

   for(var i = 0, il = utftext.length, c = 0; i<il;) 
      if ((c = utftext.charCodeAt(i)) < 128) 
      {
         str.push(toS(c));
         ++i;
      }
      else if((c > 191) && (c < 224)) 
      {
         str.push(toS(((c & 31) << 6) | (utftext.charCodeAt(i+1) & 63)));
         i += 2;
      }
      else 
      {
         str.push(toS(((c & 15) << 12) | ((utftext.charCodeAt(i+1) & 63) << 6) | (utftext.charCodeAt(i+2) & 63)));
         i += 3;
      }
      
   return str.join("");
};

3

Re: VBS: Перекодировка текста из UTF-8

Коллеги, может кто перевести решение с JS на VBS ?

Времени не хватает... :-(

4

Re: VBS: Перекодировка текста из UTF-8

Дык, в VBS есть замечательная функция Asc! Вот ей в цикле строку посимвольно и преобразовать.

5

Re: VBS: Перекодировка текста из UTF-8

Дык как бы не вопрос, тока расскажите алгоритм, который описан на JS, я как бы догадываюсь о чём он, но некоторые условия боюсь неправильно истолковать... (не дружу с JS)

else if((c > 191) && (c < 224))

здесь знак

&&

на VBS будет значить OR ?

str.push(toS(((c & 15) << 12) | ((utftext.charCodeAt(i+1) & 63) << 6) | (utftext.charCodeAt(i+2) & 63)));

Вот это вообще не понимаю

Времени не хватает... :-(

6 (изменено: max7, 2013-11-13 08:20:47)

Re: VBS: Перекодировка текста из UTF-8

Не помогает - кракозябры

Кракозябры в студию.

Попробуй так:


function converter(strinput)
    Set objStream = CreateObject("ADODB.Stream")    
    objStream.Mode = 3 
    objStream.Type = 2
    objStream.Charset = "cp866"
    objStream.Open()
    objStream.WriteText(strinput)
    objStream.Position = 0
    objStream.Charset = "UTF-8"
    converter = objStream.ReadText()
    objStream.Close()
end function

7

Re: VBS: Перекодировка текста из UTF-8

Думаю, надо просто кодировки местами поменять:

function converter(strinput)
    adReadAll = -1
    adTypeText = 2
Set objStream = CreateObject("ADODB.Stream")    
    objStream.Open()
    objStream.Type = adTypeText
    objStream.Charset = "windows-1251"
    objStream.WriteText(strinput)
    objStream.Flush()
    objStream.Position = 0
    objStream.Charset = "utf-8"
    converter = objStream.ReadText(adReadAll)
    objStream.Close()
end function

А кракозябры здесь на форуме нормально не отображаются, т.к. он с Юникодом не дружит.

8 (изменено: Евген, 2013-11-13 10:14:37)

Re: VBS: Перекодировка текста из UTF-8

2 YMP & max7 - не помогают оба варианта
Кракозябры выглядят вот так
http://korosteleff.narod.ru/zzz.jpg

Времени не хватает... :-(

9

Re: VBS: Перекодировка текста из UTF-8

Тогда вместо "windows-1251" попробуйте "windows-1252".

10 (изменено: Евген, 2013-11-13 10:46:45)

Re: VBS: Перекодировка текста из UTF-8

Не взлетело, щас ещё и значки масти "буби" появились

Времени не хватает... :-(

11

Re: VBS: Перекодировка текста из UTF-8

Для экспериментов нужны-таки кракозябры. Со скриншота проблемно скопировать.
Кстати, а эти кракозябры, собственно, откуда? Уже после функции? Надо бы исходные, до пропуска через неё.

12

Re: VBS: Перекодировка текста из UTF-8

Евген пишет:

Не взлетело, щас ещё и значки масти "буби" появились

Q: Я могу работать с базой в UTF8 через WIN1251?

A: Разумеется, для этого достаточно указать чарсет соединения WIN1251. Данные будут идти на сервер в 1251, и автоматически перекодироваться в UTF8 при сохранении (при чтении - перекодироваться обратно в win1251). Это самый легкий вариант начала работы с юникодом.

источник

Попробуйте указать в ConnectionString кодировку - ctype=win1251(правда для ADO.NET приводится другой параметр - Charset). Если я правильно понял FAQ, необходимость в перекодировке внутри VBS отпадёт.

13

Re: VBS: Перекодировка текста из UTF-8

2 BeS Yara

Set cn = CreateObject ("ADODB.Connection")
cn.Open "Provider=LCPI.IBProvider.3;Data Source=C:\VS2010\firebird\AKIS_newDB\akisdb.fdb;User Id=SYSDBA;password=masterkey;Charset=UTF-8; auto_commit=true"
Set rs = cn.execute("select Q_MENU.MNU_NAME from Q_FIFO , Q_MENU where Q_FIFO.FHI_CLINR is null and Q_FIFO.FHI_QNR=Q_MENU.MNU_QNR")


do while not rs.EOF
       strResult=strResult & rs.fields(0).Value & vblf
rs.MoveNext
loop
    Msgbox strResult
rs.close
cn.close

Не взлетело, кракозябры те же самые
http://korosteleff.narod.ru/zzz.jpg

Времени не хватает... :-(

14

Re: VBS: Перекодировка текста из UTF-8

Евген пишет:

Не взлетело, кракозябры те же самые

Не-не-не. В настройке соединения не юникод указать, а ASCII(win1251). Если интернет не обманывает, сервер будет принимать и отдавать запросы/данные в кодировке указанной при подключении, автоматически конвертируя между ней и кодировкой БД. Т.о. в vbscript ничего дополнительно перекодировать не потребуется. Теоретически .

Charset | ctype - придётся попробовать каждый, не знаю который из них будет работать. Но скорее всего ctype.

15 (изменено: Евген, 2013-11-13 12:31:05)

Re: VBS: Перекодировка текста из UTF-8

и при charset и при ctype равном win1251 или ascii выдаёт одну и ту же ошибку
http://korosteleff.narod.ru/charset.jpg
Не может перевести символы между кодировками

Времени не хватает... :-(

16 (изменено: Serge Yolkin, 2013-11-13 12:36:40)

Re: VBS: Перекодировка текста из UTF-8

Евген пишет:

Дык как бы не вопрос, тока расскажите алгоритм

Да не нужен тот алгоритм на VBS, всё проще:

Function FC(E)
  FC = ""
  For i = 1 to Len(E)
    FC = FC & Chr(Asc(mid(E,i,1)))
  Next
End Function

Это на js извращаться приходится, в нём Asc нету.

17 (изменено: Евген, 2013-11-13 12:43:30)

Re: VBS: Перекодировка текста из UTF-8

2 Serge Yolkin
это я нонял, я не понял логические условия описанные в JS

Времени не хватает... :-(

18 (изменено: Serge Yolkin, 2013-11-13 13:28:48)

Re: VBS: Перекодировка текста из UTF-8

Э-э-э... Простыми русскими словами излагать алгоритм - долго и муторно, на Васик перевести не смогу (не дружу с VBS), лучше спросить автора...
&& и || прямого аналога на васике, вероятно, не имеют: это то же, что и And (в js - &) или Or (|), но, если символов два, то второе условие не проверяется, если первое однозначно определило результат (false для &, true для |).

Вообще там пересчитываются коды символов по диапазонам: для первых 127, для русских и т.д., поскольку соответствие порядков символов несколько кривоватое. Asc использует виндовый метод перекодирования через NLS таблицы, по крайней мере я так понял.

А что, приведённая мной функция чем-то не устраивает?

19

Re: VBS: Перекодировка текста из UTF-8

Serge Yolkin пишет:

А что, приведённая мной функция чем-то не устраивает?

Дык она ничего не перекодирует, как есть, так и выводит, она ведь не смещает коды символов в зависимости от их значения, нужно ведь знать в каком диапазоне куда надо смещать...

Времени не хватает... :-(

20

Re: VBS: Перекодировка текста из UTF-8

Евген пишет:

и при charset и при ctype равном win1251 или ascii выдаёт одну и ту же ошибку

Не может перевести символы между кодировками

С этого момента уже сложнее - Firebird я поставил(на сколько же всё проще в MSSQL... или просто привык?), а вот проприетарный и не особо дешёвый провайдер ставить не хотелось бы. Хотя не исключено что ошибка именно его(провайдера). Надо будет попробовать ODBC для сравнения.

Хотелось бы уточнить ещё пару моментов:
1. версия СУБД
2. кодировка базы(UTF-8/UNICODE_FSS/WIN1251...)

Если средствами СУБД/провайдера победить не получится, то для разборок с кодировкой лучше приложить файл с примером выводя запроса.

21

Re: VBS: Перекодировка текста из UTF-8

Евген, если выводит как есть, то у Вас строка не юникодовая, а вполне себе ансишная. Тогда да, тогда надо символы парсить тем самым способом. Или попытаться передать в скрипт юникодовую строку как есть.

22 (изменено: Евген, 2013-11-13 14:55:27)

Re: VBS: Перекодировка текста из UTF-8

BeS Yara пишет:

Если средствами СУБД/провайдера победить не получится, то для разборок с кодировкой лучше приложить файл с примером выводя запроса.

ссылка на базу
Спасибо большое, что всё ещё пытаетесь мне помочь )))

Firebird 2.1.5
Кодировка базы мне не известна и IBExpert её тоже не выдаёт   (по ходу дела - default)

Времени не хватает... :-(

23

Re: VBS: Перекодировка текста из UTF-8

Евген, ещё раз перечитал начало темы, так и не понял, что именно надо перекодировать. Т.е. откуда берутся данные (строка), которые надо перевести на человеческий? Если Вы сохраняете кракозябры в файл, то как и образец файла. Если передаёте строку в скрипт иначе - как именно?

24

Re: VBS: Перекодировка текста из UTF-8

По крайней мере в базе точно есть русский текст в UTF-8. Вопрос в том, в каком виде он попадает в переменную VBS. Содержимое переменной (до функции converter) хорошо бы сохранить в файл (юникодный) и здесь выложить.

25

Re: VBS: Перекодировка текста из UTF-8

2 YMP А как ты его увидел русским ? - у меня его видно русским только в приложении разработчика, в IBExpert - тоже кракозябры

Времени не хватает... :-(

26

Re: VBS: Перекодировка текста из UTF-8

Открыл базу в хекс-редакторе, нашёл место, где много букв P, скопировал в AkelPad и там перекодировал. Эти буквы P — характерный признак UTF-8 открытой как 1251. Так что мой вариант функции должен по идее работать. Чтобы выяснить, почему не работает, мне и нужно увидеть, что у вас в переменной, которую вы передаёте функции.

27 (изменено: badik, 2013-11-13 16:34:01)

Re: VBS: Перекодировка текста из UTF-8

Наверное был прав в своем сообщении  YMP  13.11.13  11:22:11

Set f=CreateObject("Scripting.FileSystemObject")
a= f.OpenTextFile("a",1).Readall()
Wscript.Echo(a)
Wscript.Echo(converter(a))
function converter(strinput)
    adReadAll = -1
    adTypeText = 2
Set objStream = CreateObject("ADODB.Stream")    
    objStream.Open()
    objStream.Type = adTypeText
    objStream.Charset = "windows-1251"
    objStream.WriteText(strinput)
    objStream.Flush()
    objStream.Position = 0
    objStream.Charset = "utf-8"
    converter = objStream.ReadText(adReadAll)
    objStream.Close()
end function

примечание:файл с форума выгружается коряво но 7zip его читает

Post's attachments

utf8.zip 987 b, 12 downloads since 2013-11-13 

You don't have the permssions to download the attachments of this post.

28 (изменено: Евген, 2013-11-14 12:30:34)

Re: VBS: Перекодировка текста из UTF-8

Коллеги, у кого есть возможность, можно Вас попросить, запустить на выполнение следующий код:


Set cn = CreateObject ("ADODB.Connection")
cn.Open "Provider=LCPI.IBProvider.3;Data Source=C:\VS2010\firebird\AKIS_newDB\akisdb.fdb;User Id=SYSDBA;password=masterkey;Ctype=none;auto_commit=true"
Set rs = cn.execute("select Q_MENU.MNU_NAME from Q_FIFO , Q_MENU where Q_FIFO.FHI_CLINR is null and Q_FIFO.FHI_QNR=Q_MENU.MNU_QNR")


do while not rs.EOF
       msgbox converter(rs.fields(0).Value)
rs.MoveNext
loop
rs.close
cn.close


function converter(strinput)
    adReadAll = -1
    adTypeText = 2
Set objStream = CreateObject("ADODB.Stream")    
    objStream.Open()
    objStream.Type = adTypeText
    objStream.Charset = "windows-1251"
    objStream.WriteText(strinput)
    objStream.Flush()
    objStream.Position = 0
    objStream.Charset = "utf-8"
    converter = objStream.ReadText(adReadAll)
    objStream.Close()
end function

я получаю следующую ошибку
http://korosteleff.narod.ru/err.jpg

Что ещё не так ? В чём грабли ?

25 строчка

converter = objStream.ReadText(adReadAll)

Ссылка на базу

Времени не хватает... :-(

29

Re: VBS: Перекодировка текста из UTF-8

Вообщем сделал запрос через FBExport


FBExport.exe -F C:\VS2010\firebird\exporter.csv -Sc -H 192.168.104.210 -D C:\AKIS\Database\AKISDB.FDB -U sysdba -P masterkey  -Q "select count(Q_QUEUES.QUE_NAME),Q_QUEUES.QUE_NAME from Q_FIFO , Q_QUEUES where Q_FIFO.FHI_GETTIME is null and Q_FIFO.FHI_QNR=Q_QUEUES.QUE_NR group by Q_QUEUES.QUE_NAME order by count(Q_QUEUES.QUE_NAME) DESC"

Он выдаёт данные в CSV файл, тот нормально перекодируется из UTF-8 в WIN1251, и уже разобрал тот файл и получил что надо...

КОСТЫЛИ-КОСТЫЛИКИ )))

Времени не хватает... :-(