【发布时间】:2019-10-05 23:01:32
【问题描述】:
我创建了一个文档,其中只有一个“赞”Emoji(Unicode 代码点 U+1F44D),我通过标准 Windows+; 快捷方式插入:
但我无法获得其使用 VBA 的实际代码点。
我得到这些值(调试):
text = 12
length = 2
arrBytes = { 49, 0, 50, 0 }
使用以下子程序:
Sub test()
Dim text As String
Dim length As Integer
Dim arrBytes() As Byte
text = ActiveDocument.Range.Characters(1).text
length = Len(ActiveDocument.Range.Characters(1).text)
arrBytes = ActiveDocument.Range.Characters(1).text
End Sub
但如果我通过菜单 Insert > Symbol > Font "Segoe UI Emoji" > U+1F44D 插入了相同的 Emoji (竖起大拇指),相同的 Sub 过程得到了我期望的值(在调试中;?? 不是“真实”字符,它们是 surrogate code points 单独没有任何意义):
text = ??
length = 2
arrBytes = { 61, 216, 77, 220 }
(供参考,此code 将这两个字符解码为&#x1F44D)
如果使用 Windows+; 插入 Emoji,如何确定实际字符?(请用户选择上述解决方法是不属于我的问题)
附录 5 月 26 日:@Florent B. 的解决方案适用于我所有的 3 台计算机 (ActiveDocument.Content.InsertXML ActiveDocument.Content.XML)。重新加载 XML 可能会对 VBA 程序产生影响,例如它会重新编号图像“形状 ID”,但这是另一回事。
ADDENDUM May 22nd:对于使用 Windows+; 添加的符号,我可以找到正确的值(4 bytes { 61, 216 , 77, 220 }) 只在文档 Range 对象的XML 属性中,但它要求我解析整个 XML 并确定哪些 XML 字符对应 Range 对象的哪些位置,不幸的是我觉得它需要很多知识或假设。这是我可以看到 4 个字节的 XML 部分(<w:t>??</w:t> 其中 ?? 对应于 4 个字节):
<?xml version="1.0" standalone="yes"?>
<?mso-application progid="Word.Document"?>
<w:wordDocument ...>
... (around 23.000 characters)
<w:body>
<wx:sect>
<w:p wsp:rsidR="002703DB" wsp:rsidRDefault="003926FB">
<w:r>
<w:rPr>
<w:rFonts w:ascii="Segoe UI Emoji" w:h-ansi="Segoe UI Emoji"/>
<wx:font wx:val="Segoe UI Emoji"/>
</w:rPr>
<w:t>??</w:t>
</w:r>
</w:p>
<w:sectPr wsp:rsidR="002703DB" wsp:rsidSect="002849CD"><w:pgSz w:w="11906"
w:h="16838"/><w:pgMar w:top="1417" w:right="1417" w:bottom="1417"
w:left="1417" w:header="708" w:footer="708" w:gutter="0"/><w:cols
w:space="708"/><w:docGrid w:line-pitch="360"/></w:sectPr>
</wx:sect>
</w:body>
</w:wordDocument>
当我将表情符号作为符号插入时,XML 几乎相同,还有 2 个“rFonts”:
<w:body>
<wx:sect>
<w:p wsp:rsidR="00CD420D" wsp:rsidRDefault="00CD420D">
<w:r>
<w:rPr>
<w:rFonts w:ascii="Segoe UI Emoji" w:fareast="Segoe UI Emoji"
w:h-ansi="Segoe UI Emoji" w:cs="Segoe UI Emoji"/>
<wx:font wx:val="Segoe UI Emoji"/>
</w:rPr>
<w:t>??</w:t>
</w:r>
</w:p>
<w:sectPr wsp:rsidR="00CD420D" wsp:rsidSect="002849CD"><w:pgSz w:w="11906"
w:h="16838"/><w:pgMar w:top="1417" w:right="1417" w:bottom="1417"
w:left="1417" w:header="708" w:footer="708" w:gutter="0"/><w:cols
w:space="708"/><w:docGrid w:line-pitch="360"/></w:sectPr>
</wx:sect>
</w:body>
</w:wordDocument>
PS:我可以重现问题的计算机/软件:
- 计算机 1(联想 X230):
- MS Word Office 365 1904 (16.0.11601.20174) 32 位,Windows 10 Professional 10.0.17763 x64
- 同样升级到 Office 365 1907 16.0.11901.20176、MSO (16.0.11901.20070) 32 位、Windows 10 Professional 1809 17763.652 x64
- 计算机 2:
- MS Word Office 365 1904 (16.0.11601.20184) 64 位,Windows 10 Professional 1809 17763.503 x64
- 计算机 3(戴尔):
- MS Word Office 365 ProPlus 1808 (16.0.10730.20334) 64 位,Windows 10 Enterprise 10.0.17763 x64
【问题讨论】:
-
仅供参考,我无法在 Office 2016 (Win10 1809) 上重现此内容。
-
请注意,Windows 插入的内容可能与 Word 的 Insert/Symbol 插入的内容不同。表情符号可能看起来相同,但它使用与 Word 的内部功能相同的 Unicode 字体或字符组合并不是一个假设。如果您要向我们展示您提到的 Word Open XML,这可以告诉我们更多关于 Windows 如何插入 Emoji 的信息。 FWIW 我最好的猜测是它被插入为某种图像,而不是字体字符,这就是 Insert/Symbol 的工作原理。
-
Maby 通过从 XML 重建范围:
ActiveDocument.Content.InsertXML ActiveDocument.Content.XML? -
@Sandra Rossi,我猜
Range错误地填充了十进制代码点 128077 (0x1F44D) 的前两个字符31 00 32 00,而不是 UTF-16 代理代码3D D8 4D DC。我不知道重新加载 XML 是否有副作用。也许有人对如何修复Range有更好的想法。 -
@FlorentB。你能把它写成答案吗?如果你愿意,我认为 OP 会接受它。