You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VBA打开Unicode文件名二进制读取失败,报运行时错误52求助

解决VBA读取Unicode文件名文件时的错误52问题

这个问题我之前也碰到过,核心原因是VBA原生的Open语句仅支持ANSI编码的文件路径,完全不兼容Unicode字符(比如特殊中文、非拉丁语系字符),所以当你传入带Unicode的路径时就会触发"Bad file name or number"错误。下面给你两个可靠的解决办法:

方法一:使用Windows API的Unicode版本函数(推荐)

通过调用Windows API的宽字符版本函数(后缀带W的),可以完美支持Unicode路径。具体步骤如下:

  1. 在VBA模块的最顶部添加API声明(兼容32位和64位Office):
#If VBA7 Then
    Private Declare PtrSafe Function CreateFileW Lib "kernel32" (ByVal lpFileName As LongPtr, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As LongPtr, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As LongPtr) As LongPtr
    Private Declare PtrSafe Function ReadFile Lib "kernel32" (ByVal hFile As LongPtr, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, ByVal lpOverlapped As LongPtr) As Long
    Private Declare PtrSafe Function CloseHandle Lib "kernel32" (ByVal hObject As LongPtr) As Long
    Private Declare PtrSafe Function GetFileSize Lib "kernel32" (ByVal hFile As LongPtr, lpFileSizeHigh As Long) As Long
#Else
    Private Declare Function CreateFileW Lib "kernel32" (ByVal lpFileName As Long, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
    Private Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, ByVal lpOverlapped As Long) As Long
    Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
    Private Declare Function GetFileSize Lib "kernel32" (ByVal hFile As Long, lpFileSizeHigh As Long) As Long
#End If

Private Const GENERIC_READ As Long = &H80000000
Private Const OPEN_EXISTING As Long = 3
Private Const FILE_SHARE_READ As Long = &H1
  1. 重写你的GetFileBytes函数,用API替代原生Open:
Function GetFileBytes(ByVal sPath As String) As Byte()
    Dim hFile As LongPtr
    Dim fileSize As Long
    Dim bytesRead As Long
    Dim bytRtnVal() As Byte
    
    ' 打开Unicode路径的文件
    hFile = CreateFileW(StrPtr(sPath), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0)
    
    If hFile = -1 Then
        Err.Raise 53 ' 文件未找到或无法打开
    End If
    
    ' 获取文件大小
    fileSize = GetFileSize(hFile, 0)
    If fileSize = 0 Then
        ' 处理空文件
        ReDim bytRtnVal(0 To -1)
    Else
        ReDim bytRtnVal(0 To fileSize - 1) As Byte
        ' 读取文件内容到字节数组
        ReadFile hFile, bytRtnVal(0), fileSize, bytesRead, 0
        If bytesRead <> fileSize Then
            Err.Raise 70 ' 读取文件失败
        End If
    End If
    
    ' 关闭文件句柄
    CloseHandle hFile
    
    GetFileBytes = bytRtnVal
    Erase bytRtnVal
End Function

方法二:使用FileSystemObject(简单场景备选)

如果你不想用API,也可以用FSO来读取二进制文件,FSO对Unicode路径的支持更好:

Function GetFileBytes_FSO(ByVal sPath As String) As Byte()
    Dim fso As Object
    Dim fileStream As Object
    
    Set fso = CreateObject("Scripting.FileSystemObject")
    If Not fso.FileExists(sPath) Then
        Err.Raise 53 ' 文件未找到
    End If
    
    Set fileStream = fso.OpenTextFile(sPath, 1, False, -2) ' -2代表Unicode格式打开
    GetFileBytes_FSO = fileStream.ReadAll
    fileStream.Close
    
    Set fileStream = Nothing
    Set fso = Nothing
End Function

注意:FSO对于超大文件的读取效率不如API,所以大文件优先用方法一。

额外提醒

  • 可以用Debug.Print sPath把路径输出到立即窗口,确认路径没有隐藏的不可见字符
  • 确保Excel单元格里的路径没有被自动截断或格式错乱

内容的提问来源于stack exchange,提问作者MarkS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:55:28