VBA中Dir函数无法检测SharePoint文件存在性,求替代解决方案
我开发了一个程序,希望在执行耗时操作前检查多个文件是否存在,目前使用以下函数检测工作簿是否存在:
Function WorkbookExists(FileName As String) If Len(Dir(FileName)) > 0 Then WorkbookExists = True Else WorkbookExists = False End Function
该函数对本地地址(如"C:\Users\abcdef\sample.xlsx")有效,返回True后,我可通过Workbooks.Open(FileName)正常打开文件。
但检测SharePoint文件时,调用WorkbookExists("https://blah-my.sharepoint.com/personal/user/sample.xlsx"),Dir(FileName)会抛出“运行时错误52:错误的文件名或编号”,而Workbooks.Open(FileName)却能正常打开该文件。
请问这是Dir()的局限性吗?是否有其他方法可检测文件存在性?我的计算机已同步该SharePoint站点下的所有文件,ThisWorkbook.Path返回的也是SharePoint地址。我原本预期该函数返回True,因为文件确实存在。
1. Dir()的局限性说明
是的,Dir()函数仅支持本地文件路径和传统SMB网络共享路径(如\\server\shared_folder),无法直接解析HTTP/HTTPS协议的SharePoint在线地址,这就是触发运行时错误52的原因。
2. 可行的替代检测方法
方法一:利用同步本地路径 + FileSystemObject
由于你已同步SharePoint站点到本地,可以将在线URL转换为同步后的本地路径,再用Scripting.FileSystemObject的FileExists方法检测:
Function WorkbookExists(FileName As String) As Boolean Dim fso As Object Set fso = CreateObject("Scripting.FileSystemObject") ' 替换SharePoint URL为本地同步路径,根据你的实际同步位置调整 If InStr(FileName, "https://blah-my.sharepoint.com/personal/user") > 0 Then FileName = Replace(FileName, _ "https://blah-my.sharepoint.com/personal/user", _ "C:\Users\你的用户名\SharePoint\personal_user") End If WorkbookExists = fso.FileExists(FileName) Set fso = Nothing End Function
方法二:通过Workbooks.Open错误捕获间接检测
既然Workbooks.Open能正常打开SharePoint文件,可尝试只读打开文件并捕获错误,以此判断文件是否存在,注意打开后及时关闭:
Function WorkbookExists(FileName As String) As Boolean Dim targetWb As Workbook On Error Resume Next ' 以只读模式打开,避免锁定文件 Set targetWb = Workbooks.Open(FileName, ReadOnly:=True) On Error GoTo 0 If Not targetWb Is Nothing Then WorkbookExists = True targetWb.Close SaveChanges:=False Else WorkbookExists = False End If Set targetWb = Nothing End Function
方法三:使用FileLen函数(仅适用于已同步文件)
已同步的SharePoint文件会被系统映射为本地资源,FileLen函数可以直接处理其HTTPS地址,通过捕获错误判断存在性:
Function WorkbookExists(FileName As String) As Boolean On Error Resume Next Dim dummySize As Long dummySize = FileLen(FileName) On Error GoTo 0 ' 无错误则文件存在 WorkbookExists = (Err.Number = 0) End Function
内容的提问来源于stack exchange,提问作者Struan

