Как изменить кодировку текстового файла с CP866 на Windows-1251 с помощью VBScript
Возникла потребность «на лету» менять скриптом VBScript кодировку текстовой строки с cp866 на Windows-1251.
Поиск в Google выдал несколько вариантов. Наиболее универсальным решением на первый взгляд показалось функция с ADODB.Stream:
1 2 3 4 5 6 7 8 9 10 11 | Function StrConv(Text,SourceCharset,DestCharset) Set Stream = CreateObject("ADODB.Stream") Stream.Type = 2 Stream.Mode = 3 Stream.Open Stream.Charset = SourceCharset Stream.WriteText Text Stream.Position = 0 Stream.Charset = DestCharset StrConv = Stream.ReadText End Function |
где в исходном примере:
1 2 | SourceCharset = "KOI8-R" DestCharset = "Windows-1251" |
а в моём случае:
1 2 | SourceCharset = "cp866" DestCharset = "Windows-1251" |
Формально, данная функция позволяет конвертировать строку из любой кодировки в любую. Перечень кодировок доступен в реестре Windows в ветке
1 | [HKEY_CLASSES_ROOT\MIME\Database\Charset] |
На практике хер возвращается строка с мусором вместо русскоязычного текста. Чтение подробного мануала по ADO Stream Object с последующей проверкой кода и копирование через буфер обмена названий кодировок из редактора реестра результата не принесли. Из KOI8-R в Windows-1251 перекодировка успешна. Из cp866 — не хочет.
Ещё нашел вариант скрипта с использование объекта Microsoft Word:
1 2 3 4 | Set objWord = WScript.CreateObject("word.Application") objWord.Documents.Open "c:\1\1.txt", , , , , , , , , , 20866 objWord.ActiveDocument.SaveAs "c:\1\2.txt",2, , , , , , , , , , 1251 objWord.Quit |
Результат примерно такой же, как и в первом варианте. т.е., то же мусор, но преобладающие символы отличаются.
В результате воспользовался, на первый взгляд, уродливым но за то рабочим вариантом кода:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | Function DosToWin(s) ss="" For i=1 To Len(s) ' Цикл по всем символам в строке k = Asc(Mid(s,i,1)) ' Определяем ANSI-код i-го символа ' Изменяем код k на код соответствующего символа в ' Windows-кодировке If (128 < = k) And (k <= 175) Then k=k+64 ElseIf (224 <= k) And (k <= 239) Then k=k+16 ElseIf k = 240 Then ' Символ Ё k=168 ElseIf k = 241 Then ' Символ ё k=184 ElseIf k = 252 Then ' Символ № k=185 End If ss=ss+Chr(k) ' Возвращаем преобразованную строку Next DosToWin=ss End Function |
Сразу же пришлось добавить в обработку символ №, т.к. распространённый в Интернете вариант почему-то не содержит данное исключение. Если кто найдёт другие некорректно обрабатываемые символы, то может по аналогии самостоятельно внести поправку, используя таблицу кодов ASCII для кодировок CP866 и Windows-1251:
Если читатель поделится рабочим решением для универсальной перекодировки текстов на кириллице с помощью сценариев VBScript без использования сторонних программ, например с помощью того же «ADODB.Stream», буду признателен.
2 Комментариев
Май 28th, 2014
Блин огромное спасибо за вашу функцию!
Февраль 5th, 2018
Спасибо.
Работает.
Только в седьмой строке, «меньше или равно» надо слитно писать.
В куске…If (128 < = k) And… убрать пробел
Добавить комментарий