如何在 Excel VBA 中将 UTF-8 转换为 UTF-16?

2024-04-28

据我所知,Excel使用UTF-16来表示字符串文字。我从控制台(Mac)/文件(Windows)读取数据,在这两种情况下,字符编码都是混乱的。我必须找到一个适用于两个平台的解决方案,因此 ADO 流不是一个选项。我进行了一些调试,发现实际字节是:



Bytes     | Displayed as | Should be | Correct byte
258,129   | Ă           | Á         | 193
258,356   | ĂŤ           | Í         | 205
313,176   | Ĺ°           | Ű         | 219
313,144   | Ĺ           | Ő         | 213
258,347   | Ăś           | Ü         | 220
258,8211  | Ă–           | Ö         | 214
258,353   | Ăš           | Ú         | 218
258,8220  | Ă“           | Ó         | 211
258,8240  | É           | É         | 201
  

(来自古老的匈牙利测试短语 ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP,其中包含我们所有的特殊字符)。 我正在寻找一种在 Mac 和 Windows 上都能产生正确字符串的算法。 谢谢!


到目前为止发布的答案都无法正确转码包含完整 Unicode 范围内的代码点的输入字符串,例如“????????‍????????????????‍????‍????‍????????‍????‍????‍????????‍????‍????UnicodeSupport????est ????‍????????‍????‍????‍????????????‍♀️????????‍♂️????‍❤️‍????????????‍♀️」。

这就是我编写以下函数的原因,仅使用 Windows 和 MacOS 上都可用的 VBA 内置函数/语句。

此函数可跨平台和跨应用程序运行,并且适用于整个 Unicode 范围。
codePoints > 65535即使内置 VBA,也受支持ChrW() and AscW不支持它们,因为转码完全是“手动”完成的,包括代理对。由于该函数在单个字节数组缓冲区上工作,因此性能也应该相对较好。如果有人发现错误或改进,请告诉我!

这段代码得到了改进,因为这个答案 https://codereview.stackexchange.com/a/284102/234277在 CodeReview 上,非常感谢克里斯蒂安·布斯 https://stackoverflow.com/users/8488913为了那个原因!

'Function transcoding an UTF-8 encoded string to the VBA-native UTF-16-LE
'Author: Guido Witt-Dörring, https://stackoverflow.com/a/75787820/12287457
'                            https://github.com/guwidoe/VBA-StringTools
Public Function DecodeUTF8(ByRef utf8Str As String, _
                  Optional ByVal raiseErrors As Boolean = False) As String

    Const methodName As String = "DecodeUTF8"
    Dim i As Long
    Dim numBytesOfCodePoint As Byte

    Static numBytesOfCodePoints(0 To 255) As Byte
    Static mask(2 To 4) As Long
    Static minCp(2 To 4) As Long

    If numBytesOfCodePoints(0) = 0 Then
        For i = &H0& To &H7F&: numBytesOfCodePoints(i) = 1: Next i '0xxxxxxx
        '110xxxxx - C0 and C1 are invalid (overlong encoding)
        For i = &HC2& To &HDF&: numBytesOfCodePoints(i) = 2: Next i
        For i = &HE0& To &HEF&: numBytesOfCodePoints(i) = 3: Next i '1110xxxx
       '11110xxx - 11110100, 11110101+ (= &HF5+) outside of valid Unicode range
        For i = &HF0& To &HF4&: numBytesOfCodePoints(i) = 4: Next i
        For i = 2 To 4: mask(i) = (2 ^ (7 - i) - 1): Next i
        minCp(2) = &H80&: minCp(3) = &H800&: minCp(4) = &H10000
    End If

    Dim codepoint As Long
    Dim currByte As Byte
    Dim utf8() As Byte:  utf8 = utf8Str
    Dim utf16() As Byte: ReDim utf16(0 To (UBound(utf8) - LBound(utf8) + 1) * 2)
    Dim j As Long:       j = 0
    Dim k As Long

    i = LBound(utf8)
    Do While i <= UBound(utf8)
        codepoint = utf8(i)
        numBytesOfCodePoint = numBytesOfCodePoints(codepoint)

        If numBytesOfCodePoint = 0 Then
            If raiseErrors Then Err.Raise 5, methodName, "Invalid byte"
            GoTo insertErrChar
        ElseIf numBytesOfCodePoint = 1 Then
            utf16(j) = codepoint
            j = j + 2
        ElseIf i + numBytesOfCodePoint - 1 > UBound(utf8) Then
            If raiseErrors Then Err.Raise 5, methodName, _
                    "Incomplete UTF-8 codepoint at end of string."
            GoTo insertErrChar
        Else
            codepoint = utf8(i) And mask(numBytesOfCodePoint)

            For k = 1 To numBytesOfCodePoint - 1
                currByte = utf8(i + k)

                If (currByte And &HC0&) = &H80& Then
                    codepoint = (codepoint * &H40&) + (currByte And &H3F)
                Else
                    If raiseErrors Then _
                        Err.Raise 5, methodName, "Invalid continuation byte"
                    GoTo insertErrChar
                End If
            Next k
            'Convert the Unicode codepoint to UTF-16LE bytes
            If codepoint < minCp(numBytesOfCodePoint) Then
                If raiseErrors Then Err.Raise 5, methodName, "Overlong encoding"
                GoTo insertErrChar
            ElseIf codepoint < &HD800& Then
                utf16(j) = codepoint And &HFF&
                utf16(j + 1) = codepoint \ &H100&
                j = j + 2
            ElseIf codepoint < &HE000& Then
                If raiseErrors Then Err.Raise 5, methodName, _
                "Invalid Unicode codepoint.(Range reserved for surrogate pairs)"
                GoTo insertErrChar
            ElseIf codepoint < &H10000 Then
                If codepoint = &HFEFF& Then GoTo nextCp '(BOM - will be ignored)
                utf16(j) = codepoint And &HFF&
                utf16(j + 1) = codepoint \ &H100&
                j = j + 2
            ElseIf codepoint < &H110000 Then 'Calculate surrogate pair
                Dim m As Long:           m = codepoint - &H10000
                Dim loSurrogate As Long: loSurrogate = &HDC00& Or (m And &H3FF)
                Dim hiSurrogate As Long: hiSurrogate = &HD800& Or (m \ &H400&)

                utf16(j) = hiSurrogate And &HFF&
                utf16(j + 1) = hiSurrogate \ &H100&
                utf16(j + 2) = loSurrogate And &HFF&
                utf16(j + 3) = loSurrogate \ &H100&
                j = j + 4
            Else
                If raiseErrors Then Err.Raise 5, methodName, _
                        "Codepoint outside of valid Unicode range"
insertErrChar:  utf16(j) = &HFD
                utf16(j + 1) = &HFF
                j = j + 2

                If numBytesOfCodePoint = 0 Then numBytesOfCodePoint = 1
            End If
        End If
nextCp: i = i + numBytesOfCodePoint 'Move to the next UTF-8 codepoint
    Loop
    DecodeUTF8 = MidB$(utf16, 1, j)
End Function
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Excel VBA 中将 UTF-8 转换为 UTF-16? 的相关文章

  • 如何粘贴到Excel B列的最后一行?

    我需要将单元格从 H2 L2 一直向下剪切并将其粘贴到 B 列的最后一行 数据每次都会不同 所以我无法对任何范围进行硬编码 VBA 代码会很好 从 H2 L2 向下剪切并粘贴 插入到 B 列的最后一行 到目前为止我得到了 Range H2
  • 如何以编程方式从 Excel 中的 VBA 宏中删除数字签名?

    有没有办法以编程方式从 Excel 工作表的 VBA 宏中删除数字签名 即相当于进入 VBA 编辑器 转到 工具 菜单 gt 数字签名 并单击 删除 的代码 有趣的问题 出于安全原因 它故意不属于 Excel 对象模型的一部分 可以从证书存
  • 将许多表转换为 Excel 列

    我创建了用于文章审阅的网络应用程序 我有一个名为 Article 的表 每个表Article有一些ArticleReview Article ArticleId ArticleTitle NumberOfComment NumberOfVi
  • 如何在Java,Apache POI中获取Excel单元格字段的字体样式?

    我想用Java捕获Excel中单元格字段的字体 我正在使用 Apache POI 如果可以的话我想捕捉font color font family font weight font size etc 我怎样才能实现这个目标 根据评论进行编辑
  • 使用 Jquery Easyui 将数据网格导出到 Excel

    我是 json 新手 我使用 php 从 mysql 表生成了 jason 数据 并希望将生成的 json 导出为 xls 格式 考试导出 php
  • schema.ini 文件不适用于 MS Access

    我有一堆 csv 文件 我通过 VBA 将它们导入到 Access 中的表中 我在与导入的 csv 文件相同的目录中还有一个 schema ini 文件 尽管在 ini 文件中字段被指定为双精度类型 但它们在 Access 中会转换为文本类
  • 将所有工作簿工作表复制到新工作簿 VBA

    我正在使用此代码将工作簿中的每张工作表复制到新工作簿中 它工作正常 但它颠倒了工作表的顺序 是否有办法阻止它这样做 Sub copy copies all the sheets of the open workbook to a new o
  • Navicat utf8 不适用于 mysql 数据库

    我目前正在尝试合并两个不同步的表达式引擎数据库之间的数据更改 为此我选择使用 navicat 该网站在模板中大量使用希腊字符集 当我在 phpmyadmin 中查看希腊语表字段数据时 我按预期看到了希腊语字符 当我将它们加载到 Navica
  • Java中的字节和字符转换

    如果我将一个字符转换为byte然后回到char 那个角色神秘地消失了 变成了别的东西 这怎么可能 这是代码 char a line 1 byte b byte a line 2 char c char b line 3 System out
  • 拆分具有多行文本和单行文本的行

    我试图弄清楚如何拆分数据行 其中行中的 B C D 列包含多行 而其他列不包含多行 我已经弄清楚如何拆分多行单元格 如果我将这些列复制到新工作表中 手动插入行 然后运行下面的宏 仅适用于 A 列 但我在编码时迷失了休息 Here s wha
  • 你将如何开始自动化我的工作? - 第2部分

    后续这个问题 https stackoverflow com questions 2796128 how would you start automating my job 在经历了第一波进货 9 小时的复制 粘贴 后 我现在相信我已经满足
  • 通过 PHP 检测 excel .xlsx 文件 mimetype

    我无法通过 PHP 检测 xlsx Excel 文件的 mimetype 因为它是 zip 存档 文件实用程序 file file xlsx file xlsx Zip archive data at least v2 0 to extra
  • 如何处理 Workbook.SaveAs 覆盖确认上的“否”或“取消”?

    我希望在 VBA 脚本开始修改内容之前提示用户保存工作簿 当 另存为 对话框出现时 如果用户单击 取消 我会引发自定义错误并停止脚本 如果他们单击 保存 并且文件名已存在 我希望询问他们是否覆盖 这是我的代码 Function SaveCu
  • 为什么 Mac OS 上的 C 运行时允许预组合和分解的 UTF-8?

    所以我们都知道 Mac OS 上的文件系统具有使用完全分解的 UTF 8 的古怪功能 如果您调用 POSIX API 例如realpath 例如 您将从 Mac OS 返回这样一个完全分解的 UTF 8 字符串 当使用像这样的 API 时f
  • 如何使用 Excel.UriLink.16 更改 Excel URL 的文件关联?

    我正在尝试更改文件关联 以便在另一个浏览器中打开 Excel 单元格中的 URL 根据使用 CMD ftype命令与Excel UriLink 16 我应该能够使用以下命令从 powershell 通过 cmd 执行此操作 To chang
  • 将 Python Selenium 输出写入 Excel

    我编写了一个脚本来从在线网站上抓取产品信息 目标是将这些信息写入 Excel 文件 由于我的Python知识有限 我只知道如何在Powershell中使用Out file导出 但结果是每个产品的信息都打印在不同的行上 我希望每种产品都有一条
  • Excel VBA - 如何逐行读取csv文件而不是整个文件

    这是我需要读取的 csv 文件内容 header header header header header header value value value value value value value value value 我在网上找到
  • 将包含换行符的文本文件导入到 Excel 中

    我有一个纯文本文件 如下所示 some text containing line breaks 我正在尝试说话excel 2004 Mac v 11 5 正确打开此文件 我希望只看到一个单元格 A1 包含上述所有内容 不带引号 但可惜的是
  • java实现excel价格、收益率函数[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 在 VBA 中按键对字典进行排序

    我使用 VBA 创建了一个字典CreateObject Scripting Dictionary 将源单词映射到要在某些文本中替换的目标单词 这实际上是为了混淆 不幸的是 当我按照下面的代码进行实际替换时 它将按照源单词添加到字典中的顺序替

随机推荐

  • 使用 oauth azure 数据工厂进行分页

    在 Azure 数据工厂内 我通过 REST 复制活动调用 microsoft graph 利用 REST 来获取服务的访问令牌 Graph api 最多返回 200 个结果 因此我有兴趣使用可以在源中创建的分页规则 在邮递员中我可以看到我
  • window.location 的 .NET MVC jQuery 相对路径

    我有一个非常简单的问题 但似乎无法弄清楚 由于 MVC 构建 URL 的方式 它包括所有路由信息 以下内容不起作用 我希望路径名仅返回虚拟目录路径 我所做的只是当用户从下拉列表中选择 ID 时重定向到不同的路由 document ready
  • axios 拦截器内的 useContext

    我不明白为什么我的 useContext 没有在这个函数中被调用 import useContext from react import MyContext from contexts MyContext js import axios f
  • 使用 Node.js 就地流式传输和转换文件

    我想做这样的事情 var fs require fs var through require through var file path to file json var input fs createReadStream file utf
  • 如何将行为设置为投票而不需要用户登录?

    我试图允许用户无需登录 注册即可对线程进行投票 以提高用户参与度 我该怎么做呢 目前 我当前的流程是将投票与访问者的 IP 地址联系起来 以防止多次投票 但另一个问题是 request remote ip 没有为我提供正确的 IP 我在学校
  • 我如何获得 github actions runner 令牌

    我想在工作流程中创建一个虚拟机并设置为自托管运行程序 目前 阻碍我的是缺乏为我提供 Runner Token 的 API 如果存在 我可以创建该实例并将其注册为运行程序 以便能够在下一个作业中使用它 现在有人有办法获得跑步者令牌吗 延迟更新
  • JTable 如何在行之间添加行

    我之前一直在寻找这个问题很长一段时间 但我找不到任何关于这个问题或主题的问题 我假设这可能是不可能做到的 尽管这看起来很奇怪 因为该功能很有用 我希望在有 3 行的情况下 不是在末尾添加另一行 而是在第 1 行之后添加 这有可能吗 请不要提
  • BigQuery 中的 EXP() 返回浮点错误

    我有以下查询 SELECT EXP col FROM project dataset tablename Where col is FLOAT 但是 我收到此错误 Error Floating point error in function
  • sizeof() 函数如何用于 C 中的结构?

    结构体定义如下 typedef struct Sample int test char strtest Sample 在Main Function中 我将结构体称为Sizeof sizeof struct Sample 我听说结构体上 si
  • 如何制作包含DLL文件的JAR文件?

    我购买了一个第三方Java库 其中包括一个JAR文件和两个DLL文件 我编写了自己的 Java 程序来调用第三方 JAR 文件 现在我的问题是如何将我的所有代码打包到一个 JAR 文件中 其中包含我的所有代码以及第三方 JAR 和 DLL
  • 使用 AffineTransform 将形状缩放/转换为给定矩形

    我正在尝试缩放 翻译 java awt Shape with 仿射变换为了将其绘制在定义的边界矩形中 此外 我想在具有 的绘图区域中绘制它zoom 范围 我尝试了 AffineTransform 的各种串联 但找不到正确的序列 例如 以下解
  • 在没有 Webpack 的情况下使用模块“child_process”

    我正在使用 Webpack 来捆绑依赖项 其中之一是电子邮件服务postmark 该服务依赖于称为child process显然是随节点一起提供的 问题是 当我尝试运行 webpack 来捆绑我的应用程序时 它会抱怨 找不到模块 错误 无法
  • 为什么使用 System.Threading.Interlocked.Decrement 而不是减号?

    我将一些 C 代码转换为 vb net converter telerik com 将其转换为 i 进入这个 System Math Max System Threading Interlocked Decrement i i 1 所有的花
  • 我可以在 React Native 中需要一个专门用于 iOS 的模块吗?

    我目前正在使用react native safari view https github com naoufal react native safari view我的 React Native 项目中用于在 iOS 中显示 Web 视图的模
  • 如何让一个不可见的透明按钮起作用?

    查看 Unity 论坛和问答网站中的一些答案 如何制作隐形按钮的答案不起作用 因为删除与按钮关联的图像会使其不起作用 如何解决这个问题并保持不可见属性 同时允许按钮实际工作 这是 Unity 的怪异之处之一 100 的现实世界项目都需要这个
  • 如何转换 R 中列匹配模式中的值

    我有这个数据框mydf 专栏nucleotide可以有A T G C字母 我想更改字母A to T C to G G to C and T to A 如果strand列是 我该怎么做 mydf lt structure list seqna
  • 使用详细信息和摘要标签作为可折叠内联元素

    我正在努力研究这个问题的解决方案 找到一种方法来实现可折叠按钮 或其他类似对象 这样 它们可以在同一行中使用 单击时 其内容显示在按钮所在行和下一行之间 他们反应敏捷 内容的样式独立于标题 我制作这个 gif 是为了更好地了解我想要获得什么
  • 使用 CSS 检查滚动

    我正在尝试创建一个纯 100 CSS 无 jQuery 返回顶部 按钮 但我希 望该按钮仅在访问者向下滚动页面时显示 是否可以用 CSS 来检查这一点 因此 如果访问者向下滚动一点 则会显示 返回顶部 按钮 Thanks 根据光标位置确定
  • Entity Framework 4.1+ 多对多关系更改跟踪

    如何检测 ICollection 属性的更改 多对多关系 public class Company public virtual ICollection
  • 如何在 Excel VBA 中将 UTF-8 转换为 UTF-16?

    据我所知 Excel使用UTF 16来表示字符串文字 我从控制台 Mac 文件 Windows 读取数据 在这两种情况下 字符编码都是混乱的 我必须找到一个适用于两个平台的解决方案 因此 ADO 流不是一个选项 我进行了一些调试 发现实际字