Сейчас я работаю с базой данных китайских иероглифов в Excel и столкнулся с тем, что функции VBA типа Mid, ChrW и т.п. некорректно обрабатывают символы, код которых больше FFFF (65535). Среди иероглифов таких знаков предостаточно, поэтому это проблема. Хотелось бы узнать, есть ли способ обхода. Можно просто ссылку на решение, т.к. сам ничего полезного не нашел.
Например, имеется строка из трех символов: 䢂臘 Третий из них проблемный, т.к. имеет код 282E2 (164578). Поэтому функция mid() выдает на нем некорректный символ - в данном случае несуществующий.
Есть ли способ корректно вытащить третий символ с помощью макроса? Буду благодарен за любой совет.
P.S.: Форум не отображает третий символ в примере выше, поэтому просьба посмотреть в файле.
Из теории: В 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 — у последующего. Из практики: дойду до ПК, посмотрю на функции.
Строка - это байтовый массив (помним про порядок байтов - UTF-16LE) В данном случае ваши 3 символа кодируются 8 байтами. 2 символа по 2 байта, 1 символ 4 байта, читайте матчасть выше.
Код ваших 3 символов в десятичном выражении по байтам: 130 72 216 129 96 216 226 222
ИМХО, не все функции поддерживают 4 байта на символ, или берут 2 первых/последних (или 4 байта интерпретируют как 2 символа по 2 байта) - надо читать матчасть по реализации этих функций. Используйте байтовый массив в расчетах, см. вложение.
Вижу два варианта: 1. Искать функции поддерживающие 4 байта на символ. 2. Напилить свой обработчик строк. Ели в макросах вы не спец, то именно в таком порядке.
результат положительный, все работает. Еще раз благодарю. Выручили. Правда, видимо не во всех версиях есть Unichar и Unicode, поскольку на одном из ноутов не заработало (в выпадающем списке после ввода Application.WorksheetFunction функции тоже отсутствуют). К сожалению, не посмотрел версию Экселя. На другом ноутбуке все ОК (Excel 2016).