Возникла потребность «на лету» менять скриптом 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», буду признателен.