如何在 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? 的相关文章

  • 有没有更快的方法来使用Powershell解析Excel文档?

    我正在与一个接口MS Excel文件通过Powershell 每个 Excel 文档可能有大约 1000 行数据 目前这个脚本似乎读取了Excel文件并以每 0 6 秒 1 条记录的速率将值写入屏幕 乍一看 这似乎非常慢 这是我第一次阅读E
  • 使用 VBScript 在日期字段值上选择错误的数据

    我有一张包含以下数据的表 现在 Excel 共有 36 个任务 每个任务有 4 列 第一个任务 即 Task1 名称将始终从 L 列开始 144 列描述了 36 个任务 现在我们需要按行进行检查 并需要检查 TNStart 开始日期 你们能
  • 使用PHP从doc、xls文件中读取数据

    我想知道是否可以从 doc 和 xls 文件中读取数据并将 将内容读取到图像文件中 创建文档的页面样本 例如 我有一些文件希望我的客户购买 所以我需要自动创建小图像 例如我的文档样本 我们将不胜感激您的帮助 对于读取 xls 文件 我真的推
  • 如何将 .xlsx 文件上传到 jenkins 作业

    如何将 xlsx 文件作为构建参数上传到 jenkins 作业 我尝试使用文件参数 但我发现该文件正在丢失其扩展名或原始格式 有什么方法可以从 jenkins UI 将 excel 文件上传到 jenkins 作业吗 In the file
  • 将 MS 转换为秒

    我发现这个公式可以用来将 MS 转换为秒 但它是为 Excel 2002 编写的 而我正在使用 2010 CONCATENATE TEXT INT B1 1000 86400 hh mm ss B1 INT B1 1000 1000 以下是
  • 使用“Openxml writer”合并 Excel 中的单元格

    我想合并单元格是excel 通过使用 DOM 方法 我可以轻松做到这一点 但由于我的 Excel 文件太大 当我尝试获取工作表时 它会抛出内存不足异常 所以我必须使用SAX方法来读取excel文件 但我不知道如何用这种方法合并单元格 查了很
  • 在工作表中合并行和求和值

    我有一个 Excel 工作表 其中包含以下数据 管道 来分隔列 A B C X 50 60 D E F X 40 30 A B C X 10 20 A B C Y 20 20 A B C X 20 70 D E F X 10 50 A B
  • 比较 EXCEL 中的列本身以检查其是否有重复值

    假设我有一个名为项目代码的列 如下所示 row code 1 A123 2 B123 n A123 代码列中的值可能出现多次 如何使用Excel公式或Excel中的任何方法检查列中的重复记录 Thanks 根据您使用的 Excel 版本 您
  • 从Excel工作表中读取汉字? (总是返回“???”)

    如何从Excel单元格中读取汉字并将其写入文件 当我取值时 Worksheets ActiveCell Worksheet Name Cells 3 columnNumbers 0 value 它总是返回 Dim fileStream Fi
  • PHP:使用 UTF-8 的 strpos 和 substr

    假设我有一个很长的 UTF 8 编码字符串 并说我想检测是否 var存在于该字符串中 假设 var始终是简单的字母或 ASCII 字符数字 例如 hello123 我不需要使用mb strpos or iconv strpos正确的 因为只
  • 如何使用 Python 将多个文本文件中的数据提取到 Excel 中? (每张纸一个文件的数据)

    到目前为止 为了让我的代码读取文本文件并导出到 Excel 我有 import glob data for infile in glob glob txt with open infile as inf data infile l 1 fo
  • 从Excel单元格中提取固定长度的数字

    一些类似名称的线程 但仍然无法解决我的问题 我需要从 Excel 字符串中提取固定长度的 NUMBER 值 在我的场景中为 8 位数字 为此目的提供了以下 Excel 公式 MID A1 FIND SUBSTITUTE SUBSTITUTE
  • 如何获取活跃的Excel实例?

    我有一个 C 应用程序 该应用程序根据用户需求将信息粘贴到 excel 背后的逻辑是这样的 如果没有正在运行的 excel 实例 它会创建一个实例并粘贴到该实例 如果只有一个实例在运行 它会尝试获取该实例并使用它 这是我用来执行此操作的代码
  • 将数据从 R 导出到 Excel

    我试图将从 R 获得的一些结果导出到 Excel 中 但未成功 我尝试过以下代码 write table ALBERTA1 D ALBERTA1 txt sep t write csv ALBERTA1 ALBERTA1 csv your
  • 从 X、Y、Z 数据、Excel 或其他工具进行 3D 绘图

    我的数据看起来像这样 1000 13 75 2 1000 21 79 21 1000 29 80 02 5000 29 87 9 5000 37 88 54 5000 45 88 56 10000 29 90 11 10000 37 90
  • 有没有一种方法可以将这些列转换为数据格式?

    有没有办法将这些列转换为数据格式 gg mm aaaa 时 分 秒 日期 20220601 gt gt gt gt 2022 06 01 小时 3047 gt gt gt gt gt 00 30 47 时 分 秒 我对 B 列有严重问题 我
  • 在 Excel 中查找结果将行复制到另一张工作表

    我需要一些帮助将数据从一个 Excel 工作表复制到另一个 例如 样本数据 A B C 1 aaa bbb ddd 2 bbb ccc eee 2 bbb ccc eee 3 ccc fff rrr 4 ccc fff ttt 5 ddd
  • 行编号选择自动填充直到最后[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我有一个包含数千行的表 我想通过在第一行旁边添加 1 2 3 来对行进行编号 然后选择这些行并拖动到最后以使用递增的数字进行填充 如何自动
  • VBA将二进制图像转换为网页的base64编码字符串

    我正在尝试读取 JPG 文件并将该文件转换为 base64 编码的字符串 该字符串可用作网页上的嵌入 jpeg 我在网上发现了两个在 VBA 中进行 Base64 编码 解码的函数 它们似乎被广泛接受 编码 解码过程产生了我的原始二进制字符
  • 从 Excel 应用程序对象中查找位数(32 位/64 位)?

    是否可以从 Microsoft Office Interop Excel ApplicationClass 确定 Excel 是以 32 位还是 64 位运行 Edit该解决方案应该适用于 Excel 2010 和 Excel 2007 此

随机推荐

  • 使用 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 流不是一个选项 我进行了一些调试 发现实际字