Имя: Пароль:
1C
 
Перекодировка UTF из строки -> строку 1С не используя файлы
,
0 Light Integrator
 
20.09.08
12:24
Про наличие перекодировки через файл средствами платформы знаю, знаю и:
Книга знаний: Перекодировщик из UTF-8 в Windows-1251 и обратно

Всем известно что Flash диски живут N циклов. Перезаписи N в лучшем случае ~100000.

Если записей для перекодирования ~3500 (по десятку килобайт), и работа на Flash то лучше, наверное, использовать перекодирование не через файл. Как?
1 Defender aka LINN
 
20.09.08
12:36
(0) Использовать каталог на HDD религия воспрещает?
2 Fragster
 
гуру
20.09.08
13:13
(1) +1, а вообще cygwin+iconv - умеют и потоки кодировать...
3 Light Integrator
 
20.09.08
13:14
Это ноут без HDD :) Предложение не принято.
4 Light Integrator
 
20.09.08
13:15
cygwin + 1С 8?
5 H A D G E H O G s
 
20.09.08
13:22
(0) Там в статье Смахабр ниже все написал. Пользуйтесь.
6 H A D G E H O G s
 
20.09.08
13:23
(5) Хотя, миль пардон, он тоже в файл пишет
7 Armando
 
20.09.08
13:24
Функция UTF8(Ст)
   НоваяСт = "";
   Для i=1 по СтрДлина(Ст) Цикл
       Символ = Сред(Ст,i,1);
       КодСимвола = КодСимв(Символ);
       Если (КодСимвола > 191) и (КодСимвола < 224) Тогда // А - Я
           НоваяСт = НоваяСт + Симв(208)+Симв(КодСимвола-48);
       ИначеЕсли (КодСимвола > 223) и (КодСимвола < 240) Тогда // а - п
           НоваяСт = НоваяСт + Симв(208)+Симв(КодСимвола-48);
       ИначеЕсли (КодСимвола > 239) и (КодСимвола < 256) Тогда // р - я
           НоваяСт = НоваяСт + Симв(209)+Симв(КодСимвола-112);
       ИначеЕсли (Символ = "ё") или (Символ = "Ё") Тогда
           НоваяСт = НоваяСт + Симв(208)+Симв(КодСимвола-39);
       ИначеЕсли (Символ = "№") Тогда
           НоваяСт = НоваяСт + Симв(226)+Симв(132)+Симв(150);
       Иначе
           НоваяСт = НоваяСт + Символ;
       КонецЕсли;
   КонецЦикла;
   Возврат НоваяСт;
КонецФункции

это для кодировки в UTF.
8 Медвед1Сник
 
20.09.08
13:24
"Это ноут без HDD"

А что бывают и такие?...
9 Light Integrator
 
20.09.08
14:03
(8) Например, ноутбуки http://market.yandex.ru/model.xml?hid=91013&modelid=2438887
(тут - Asus eee pc 70x)

(7) Нужен был в противположную сторону. Пока говорил тут - написал на основе сведений Wikipedia:
Функция Кодировка__UTF8_Биты(Число1,НачБит,КонБит)
   ОстатокЧисла = Число1;
   РезБайт = 0;
   РезБит = 0.5;
   Для НомБита = 0 По КонБит Цикл
       Если НомБита >= НачБит Тогда
           РезБит = РезБит * 2;
           РезДеления = ОстатокЧисла - Цел(ОстатокЧисла / 2) * 2;
           РезБайт = РезБайт + ?(Резделения,РезБит,0);
       КонецЕсли;
       ОстатокЧисла = Цел(ОстатокЧисла / 2);
   КонецЦикла;
   Возврат РезБайт;
КонецФункции
Функция Кодировка_UTF8_символ_в_UTF8(Символ)
   НомерСимвола = КодСимвола(Символ);
   Если НомерСимвола < 128 Тогда
       Возврат Символ;
   ИначеЕсли НомерСимвола < 2048 Тогда
       Возврат Символ(128 + 64 + Кодировка__UTF8_Биты(НомерСимвола,6,10)) + Символ(128 + Кодировка__UTF8_Биты(НомерСимвола,0,6));
   ИначеЕсли НомерСимвола < 65536 Тогда
       Возврат Символ(128 + 64 + Кодировка__UTF8_Биты(НомерСимвола,13,16)) + Символ(128 + Кодировка__UTF8_Биты(НомерСимвола,7,12)) + Символ(128 + Кодировка__UTF8_Биты(НомерСимвола,0,6));
   КонецЕсли;
КонецФункции
Функция Кодировка_UTF8_в_Строку(Знач Текст) Экспорт
   СоответствиеПерекодирования = Новый Соответствие;
   Для НомерСимвола = КодСимвола("а") По КодСимвола("я") Цикл
       Симв1 = Символ(НомерСимвола);
       СоответствиеПерекодирования.Вставить(Кодировка_UTF8_символ_в_UTF8(Симв1),Симв1);
   КонецЦикла;
   Для НомерСимвола = КодСимвола("А") По КодСимвола("Я") Цикл
       Симв1 = Символ(НомерСимвола);
       СоответствиеПерекодирования.Вставить(Кодировка_UTF8_символ_в_UTF8(Симв1),Симв1);
   КонецЦикла;
   ДлинаТекста = СтрДлина(Текст);
   НомПозиции = 0;
   РезТекст = "";
   Пока НомПозиции < ДлинаТекста Цикл
       ТекСимв = Сред(Текст,НомПозиции,1);
       КодСимв = КодСимвола(ТекСимв);
       Если КодСимв > 1050 Тогда
           Сообщить("Перекодировка: Текст, скорее всего, закодирован UTF-16!");
           Возврат "";
       КонецЕсли;
       Попытка
           Если КодСимв < 128 Тогда
               РезТекст = РезТекст + ТекСимв;
           ИначеЕсли (КодСимв >= 192) И (КодСимв <= 223) Тогда
               СледСимв = Сред(Текст,НомПозиции + 1,1);
               РезТекст = РезТекст + СоответствиеПерекодирования[ТекСимв + СледСимв];
               НомПозиции = НомПозиции + 1;
           ИначеЕсли (КодСимв >= 224) И (КодСимв <= 240) Тогда
               СледСимв = Сред(Текст,НомПозиции + 1,1);
               СледСимв1 = Сред(Текст,НомПозиции + 2,1);
               РезТекст = РезТекст + СоответствиеПерекодирования[ТекСимв + СледСимв + СледСимв1];
               НомПозиции = НомПозиции + 2;
           КонецЕсли;
       Исключение
           РезТекст = РезТекст + ТекСимв;
       КонецПопытки;
       НомПозиции = НомПозиции + 1;
   КонецЦикла;
   Возврат РезТекст;
КонецФункции


Но текст оказался UTF-16 :) Так что я теперь пишу перекодировку UTF-16 -> строку
10 Однояйцевый брат Ков
 
20.09.08
14:07
Ужас, а коду надо в 3 строки, и прямо в сабже есть ответ, немного подумать только надо...
(2) иди учи венду, венда круче поточит и перекодирует куда угодно
11 Light Integrator
 
20.09.08
14:29
(10) Ответа в сабж. нет. Если хотите возразить - от вас требуется опровержение.
12 Light Integrator
 
20.09.08
15:40
Кому потребно - результат деятельности:
Функция Кодировка_UTF16_в_Строку(Знач Текст) Экспорт
   ДлинаТекста = СтрДлина(Текст);
   СоответствиеПерекодировки = Новый Соответствие;
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(1106),"А");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(8216),"Б");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(8217),"В");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(8220),"Г");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(8221),"Д");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(8226),"Е");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(8211),"Ж");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(8212),"З");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(152),"И");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(8482),"Й");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(1113),"К");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(8250),"Л");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(1114),"М");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(1116),"Н");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(1115),"О");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(1119),"П");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(160),"Р");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(1038),"С");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(1118),"Т");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(1032),"У");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(164),"Ф");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(1168),"Х");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(166),"Ц");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(167),"Ч");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(1025),"Ш");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(169),"Щ");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(1028),"Ъ");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(171),"Ы");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(172),"Ь");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(173),"Э");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(174),"Ю");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(1031),"Я");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(176),"а");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(177),"б");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(1030),"в");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(1110),"г");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(1169),"д");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(181),"е");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(182),"ж");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(183),"з");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(1105),"и");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(8470),"й");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(1108),"к");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(187),"л");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(1112),"м");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(1029),"н");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(1109),"о");
   СоответствиеПерекодировки.Вставить(Символ(1057) + Символ(1111),"п");
   СоответствиеПерекодировки.Вставить(Символ(1057) + Символ(1026),"р");
   СоответствиеПерекодировки.Вставить(Символ(1057) + Символ(1027),"с");
   СоответствиеПерекодировки.Вставить(Символ(1057) + Символ(8218),"т");
   СоответствиеПерекодировки.Вставить(Символ(1057) + Символ(1107),"у");
   СоответствиеПерекодировки.Вставить(Символ(1057) + Символ(8222),"ф");
   СоответствиеПерекодировки.Вставить(Символ(1057) + Символ(8230),"х");
   СоответствиеПерекодировки.Вставить(Символ(1057) + Символ(8224),"ц");
   СоответствиеПерекодировки.Вставить(Символ(1057) + Символ(8225),"ч");
   СоответствиеПерекодировки.Вставить(Символ(1057) + Символ(8364),"ш");
   СоответствиеПерекодировки.Вставить(Символ(1057) + Символ(8240),"щ");
   СоответствиеПерекодировки.Вставить(Символ(1057) + Символ(1033),"ъ");
   СоответствиеПерекодировки.Вставить(Символ(1057) + Символ(8249),"ы");
   СоответствиеПерекодировки.Вставить(Символ(1057) + Символ(1034),"ь");
   СоответствиеПерекодировки.Вставить(Символ(1057) + Символ(1036),"э");
   СоответствиеПерекодировки.Вставить(Символ(1057) + Символ(1035),"ю");
   СоответствиеПерекодировки.Вставить(Символ(1057) + Символ(1039),"я");
   СоответствиеПерекодировки.Вставить(Символ(1056) + Символ(1027),"Ё");
   СоответствиеПерекодировки.Вставить(Символ(1057) + Символ(8216),"ё");
   НомПозиции = 1;
   РезТекст = "";
   Пока НомПозиции < ДлинаТекста Цикл
       ТекСимв = Сред(Текст,НомПозиции,1);
       КодСимв = КодСимвола(ТекСимв);
       Если (КодСимв = 1056) или (КодСимв = 1057) Тогда
           СледСимв = Сред(Текст,НомПозиции + 1,1);
           РезТекст = РезТекст + СоответствиеПерекодировки[ТекСимв + СледСимв];
           НомПозиции = НомПозиции + 1;
       Иначе
           РезТекст = РезТекст + ТекСимв;
       КонецЕсли;
       НомПозиции = НомПозиции + 1;
   КонецЦикла;
   Возврат РезТекст;
КонецФункции
13 Light Integrator
 
20.09.08
15:56
* Поправка: должно было быть в последнем листинге:
 Пока НомПозиции <= ДлинаТекста Цикл
14 Light Integrator
 
20.09.08
16:23
* У "п" там должно быть 1056
15 Ковычки
 
21.09.08
07:45
(11) ничего он опровергать не будет, и более того скажу - выкинь свой код и изучи ОС на которой работаешь, если не сможешь, то иди в дворники...
Ответ в сабже есть!
16 Light Integrator
 
21.09.08
09:33
(15) Всё-таки попрошу тогда проверить:
   Стрим = Новый COMОбъект("Adodb.Stream");
   Стрим.Type = 2; // Type = 2 - text data (только такой может быть перекодирован)
   Стрим.Mode = 3; // Mode = 3 - Read/Write
   Стрим.Charset = "windows-1251"; //КодировкаТекста1; // windows-1251, utf-8, utf-16, cp866...
   Стрим.Open();
   Стрим.WriteText(Символ(224) + Символ(225) + Символ(226)); // абв - windows-1251
   Стрим.SaveToFile("c:\sample_stream.txt");

Оно сохранит три латинские буквы "a" (т.к. символы 224-226 - это "a" с апострофами в unicode). Речь о 1С 8.

Как правильно?
17 Ковычки
 
21.09.08
09:45
Функция Перекодировка(Стр="",Кодировка="windows-1251")
   Стрим = СоздатьОбъект("Adodb.Stream");
   Стрим.Type = 2;
   Стрим.Mode= 3;
   Стрим.charset="windows-1251";
   Стрим.Open();
   Стрим.WriteText(Стр);
   Стрим.Position=0;
   Стрим.charset=Кодировка;
   Рез=Стрим.ReadText(-1);
   Стрим.Close();
   Возврат    Рез;
КонецФункции

//*******************************************
Процедура Сформировать()
   Текст= СоздатьОбъект("Текст");
   Текст.Открыть("c:\утф-8.txt");
   Стр="";
   Для к=1 По Текст.КоличествоСтрок() Цикл
       Стр=Стр+Текст.ПолучитьСтроку(к)+РазделительСтрок;
   КонецЦикла;
   Предупреждение(Перекодировка(Стр,"utf-8"));
КонецПроцедуры
18 Ковычки
 
21.09.08
09:49

//*******************************************
Процедура Сформировать()
   Чарсеты="ascii
   |utf-16
   |utf-8
   |koi8-r
   |cp866
   |windows-1251";
   Стрим = СоздатьОбъект("Adodb.Stream");
   Стрим.Type = 2;
   Стрим.Mode= 3;
   Для к=1 По СтрКоличествоСтрок(Чарсеты) Цикл
       Чарсет=СтрПолучитьСтроку(Чарсеты,к);
       Стрим.charset=Чарсет;
       Стрим.Open();
       Стрим.WriteText("Проверочка");
       Стрим.SaveToFile("c:\"+Чарсет+".txt",2);
       Стрим.Close();
   КонецЦикла;
КонецПроцедуры

...
Ну а выводы сам уж... (кстати кодировок адо разбирает больше чем приведено)
19 Light Integrator
 
21.09.08
13:26
Вы не поняли - это проблема именно 8-й платформы. Из-за того, что в 8-й всё хранится в Unicode - он в виде unicode букв и попадает в VBScript, а потому не работает.

В 7-й будет работать, в 8-й - не так просто.
20 Ковычки
 
21.09.08
13:38
ну и отправляй наоборот в юникод
21 AngelicCare
 
21.09.08
15:48
(20) Просьба быть внимательным. Этот код не работает в 8.0 без использования файла.

   Стрим = Новый COMОбъект("Adodb.Stream");
   Стрим.Type = 2; // Type = 2 - text data (только такой может быть перекодирован)
   Стрим.Mode = 3; // Mode = 3 - Read/Write
   Стрим.Open();
   Стрим.WriteText("проверка");
   Попытка
       Стрим.SaveToFile("c:\temp\sample_stream.txt");
   Исключение
   КонецПопытки;
   Стрим.Position = 0;
   Стрим.Charset = "utf-16";
   РезультатПерекодировки = Стрим.ReadText(-1);
   Предупреждение(РезультатПерекодировки);
   Стрим.Close();
   Стрим.Charset = "utf-16";
   Стрим.Open();
   Стрим.WriteText("проверка");
   Стрим.Position = 0;
   РезультатПерекодировки = Стрим.ReadText(-1);
   Предупреждение(РезультатПерекодировки);
   Стрим.Close();

В файл сохраняется перекодированное корректно значение, но это не соответствует условиям задачи - требуется без файла.

ReadText - возвращает всегда "проверка" в неперекодированном виде.
22 KAO111
 
21.09.08
17:26
Платформа именно 8.0?

В 8.1 работает пример из СП

   Текст = Новый ЗаписьТекста("d:\win.txt", КодировкаТекста.ANSI);
   Текст.ЗаписатьСтроку("Добро пожаловать!");
   Текст.ЗаписатьСтроку("Посторонним вход воспрещен.");
   Текст.Закрыть();
   Текст = Новый ЗаписьТекста("d:\utf.txt", КодировкаТекста.UTF8);
   Текст.ЗаписатьСтроку("Добро пожаловать!");
   Текст.ЗаписатьСтроку("Посторонним вход воспрещен.");
   Текст.Закрыть();
23 AngelicCare
 
21.09.08
20:05
(22) KAO, просьба читать внимательно и вам: требуется не через файлы.
24 KAO111
 
21.09.08
20:45
(23) Не понятно. Переводить строку, отбрасывая разряды, бессмысленно внутри 1С. Нужно все равно куда-то выдавать данные. Я не вижу цели задачи, но еще можно запустить любой стандартный механизм, например из VBScript, приблизительно:

script = new comobject("scriptcontrol");
script.language = "vbcript";
script.addcode
(
"
|function ToANSI(UTFChar)
|{
|shornum = AscB(UTFChar)
|
|return (Chr(shornum)) ;
|}
|");

ANSIChar = script.run("ToANSI", UTFChar);

Хотя мне кажется, что с точки зрения работы внутри 1С ничего не изменится.


Кроме того, если задача решается для (0) - то в любом случае 1С пишет много временных файлов. Можно создать виртуальный диск в памяти, но тогда ничего не мешает использовать его для конвертации.
25 AngelicCare
 
21.09.08
21:03
KAO, был XML с Base64 полями. Был раскодирован вручную (без использования записи в файл - Base64). И, предстоит, закодировать его обратно.

Вопрос со временными файлами буду изучать.

Наверное, тему можно закрывать т.к. мне сейчас уже проще сделать перекодировку процедурой 1С вручную (набил таблицу замен).
26 Ковычки
 
21.09.08
21:05
Ужас... Он Нас учат жить...
27 AngelicCare
 
21.09.08
21:05
Base64 кодирует бинарные данные, в 1С средств работы с ними без использования файлов нет. Отсюда все проблемы с перекодировками.
28 Ковычки
 
21.09.08
21:06
Еще раз - подумай чем говоришь...
29 AngelicCare
 
21.09.08
21:06
(26) Ковычки, наставляет тот, кто даёт. Другие только вразумляют.
30 Ковычки
 
21.09.08
21:20
почему в (17) я не наблюдаю файла, да и в (18) и даже в (21) хотя тут отсебячину напаяли...
...
-- Поезжайте в Киев! - сказал он неожиданно. - И тогда вы поймете, что я прав. Обязательно поезжайте в Киев!

 -- Какой там Киев! - пробормотал Шура. - Почему?

 -- Поезжайте в Киев и спросите там, что делал Паниковский до революции. Обязательно спросите!

 -- Что вы пристаете? -- хмуро сказал Балаганов.

 -- Нет, вы спросите! - требовал Паниковский. - Поезжайте и спросите!
(с)
31 Light Integrator
 
21.09.08
21:40
:)