Страницы: 1
RSS
[VBA] Обработка символов с кодами больше 65535
 
Добрый день!

Прошу прощения если вопрос уже обсуждался.

Сейчас я работаю с базой данных китайских иероглифов в Excel и столкнулся с тем, что функции VBA типа Mid, ChrW и т.п. некорректно обрабатывают символы, код которых больше FFFF (65535). Среди иероглифов таких знаков предостаточно, поэтому это проблема. Хотелось бы узнать, есть ли способ обхода. Можно просто ссылку на решение, т.к. сам ничего полезного не нашел.

Например, имеется строка из трех символов: 䢂臘 Третий из них проблемный, т.к. имеет код 282E2 (164578). Поэтому функция mid() выдает на нем некорректный символ - в данном случае несуществующий.

Есть ли способ корректно вытащить третий символ с помощью макроса? Буду благодарен за любой совет.

P.S.: Форум не отображает третий символ в примере выше, поэтому просьба посмотреть в файле.
Изменено: kanji - 24.02.2018 08:31:37
 
Из теории:
В UTF-16 символы кодируются двухбайтовыми словами с использованием всех возможных диапазонов значений (от 000016 до FFFF16). При этом можно кодировать символы Unicode в дипазонах 000016..D7FF16 и E00016..10FFFF16. Исключенный отсюда диапазон D80016..DFFF16 используется как раз для кодирования так называемых суррогатных пар — символов, которые кодируются двумя 16-битными словами. Символы Unicode до FFFF16 включительно (исключая диапазон для суррогатов) записываются как есть 16-битным словом. Символы же в диапазоне 1000016..10FFFF16 (больше 16 бит) уже кодируются парой 16-битных слов. Для этого их код арифметически сдвигается до нуля (из него вычитается минимальное число 1000016). В результате получится значение от нуля до FFFF16, которое занимает до 20 бит. Старшие 10 бит этого значения идут в лидирующее (первое) слово, а младшие 10 бит — в последующее (второе). При этом в обоих словах старшие 6 бит используются для обозначения суррогата. Биты с 11 по 15 имеют значения 110112, а 10-й бит содержит 0 у лидирующего слова и 1 — у последующего.
Из практики: дойду до ПК, посмотрю на функции.
«Бритва Оккама» или «Принцип Калашникова»?
 
#FFFF - это максимум для двухбайтовых чисел)
 
На всякий случай по порядку байтов: Винда и  юникодовые версии функций WinAPI -
строки в них всегда кодируются в UTF-16LE.
«Бритва Оккама» или «Принцип Калашникова»?
 
Строка - это байтовый массив (помним про порядок байтов  - UTF-16LE)
В данном случае ваши 3 символа кодируются 8 байтами. 2 символа по 2 байта, 1 символ 4 байта, читайте матчасть выше.

Код ваших 3 символов в десятичном выражении по байтам:
130
72
216
129
96
216
226
222

ИМХО, не все функции поддерживают 4 байта на символ, или берут 2 первых/последних (или 4 байта интерпретируют как 2 символа по 2 байта) - надо читать матчасть по реализации этих функций.
Используйте байтовый массив в расчетах, см. вложение.
Изменено: bedvit - 26.02.2018 20:48:41
«Бритва Оккама» или «Принцип Калашникова»?
 
bedvit, большое спасибо за ликбез и макрос!

Буду разбираться дальше.

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

Например, ячейка A1 содержит строку: abcde
Задача: записать в ячейку A2 i-й (пусть будет 3-й) символ из этой строки.

В макросе я просто писал что-то вроде:
Код
STRNG=Cells(1,1)
Cells(2,1)=Mid(STRNG,3,1)

В результате получал в ячейке A2 третий символ (т.е. c).

Но с вышеупомянутыми символами это не работает.

Может, действительно, ограничение функции Mid() и ей подобных...

Изменено: kanji - 26.02.2018 21:07:03
 
Вижу два варианта: 1. Искать функции поддерживающие 4 байта на символ.
2. Напилить свой обработчик строк.
Ели в макросах вы не спец, то именно в таком порядке.
«Бритва Оккама» или «Принцип Калашникова»?
 
Цитата
bedvit написал:
Вижу два варианта: 1. Искать функции поддерживающие 4 байта на символ.
Функции рабочего листа UNICODE и UNICHAR.
Владимир
 
sokol92,
спасибо за подсказку.

Да, я видел эти функции и они работают.
Однако меня больше интересует реализация в макросе, т.к. алгоритм в нем написан.
 
Можно вызывать эти функции из VBA через Application.WorksheetFunction (на моей конфигурации 1 000 000 обращений к функции Unicode занимает 1 сек).
Владимир
 
sokol92,
Благодарю за подсказку!
 
Был рад помочь! Если это возможно, сообщите о результатах.
Владимир
 
sokol92,

результат положительный, все работает.
Еще раз благодарю. Выручили.
Правда, видимо не во всех версиях есть Unichar и Unicode, поскольку на одном из ноутов не заработало (в выпадающем списке после ввода Application.WorksheetFunction функции тоже отсутствуют). К сожалению, не посмотрел версию Экселя. На другом ноутбуке все ОК (Excel 2016).
 
Появились в Excel 2013.
Владимир
Страницы: 1
Наверх