VBA调用FollowHyperlink首次无法打开PDF的原因及解决方法
问题原因解释
- PDF阅读器启动需要一定时间,原代码调用
FollowHyperlink后立刻执行IsFileOpen检查,此时PDF阅读器还没完成文件锁定,IsFileOpen会误判文件未打开,触发重复调用FollowHyperlink。 - 重复调用
FollowHyperlink时,系统会因为已有一个正在启动的进程尝试打开该PDF,拒绝后续的打开请求,最终导致PDF首次执行时无法正常打开。
解决方法
方法1:给原代码添加启动延迟
在调用FollowHyperlink后,添加一段等待时间,让PDF阅读器有足够时间启动并锁定文件,再执行检查:
Function OpenFile(ByRef fileFullName As String) OpenTheFile: ThisWorkbook.FollowHyperlink (fileFullName) ' 添加1秒延迟(可根据电脑性能调整时长,比如慢机器设为2秒) Application.Wait Now + TimeValue("00:00:01") Dim fileOpenCheck As Boolean fileOpenCheck = IsFileOpen(fileFullName) If Not fileOpenCheck Then GoTo OpenTheFile End If End Function Function IsFileOpen(FileName As String) Dim ff As Long, ErrNum As Long On Error Resume Next ff = FreeFile() Open FileName For Input Lock Read As #ff Close ff ErrNum = Err On Error GoTo 0 Select Case ErrNum Case 0: IsFileOpen = False Case 70: IsFileOpen = True Case Else: Error ErrNum ' 修正原代码笔误:ErrNo改为ErrNum End Select End Function
方法2:改用ShellExecute API(更可靠)
使用Windows API直接调用关联程序打开文件,避免FollowHyperlink的重复调用问题,也不需要循环检查:
' 必须放在模块的最顶部声明API Declare PtrSafe Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" ( _ ByVal hWnd As LongPtr, _ ByVal lpOperation As String, _ ByVal lpFile As String, _ ByVal lpParameters As String, _ ByVal lpDirectory As String, _ ByVal nShowCmd As Long _ ) As LongPtr Function OpenFile(ByRef fileFullName As String) ' 1表示让程序正常显示窗口 ShellExecute 0, "open", fileFullName, vbNullString, vbNullString, 1 End Function
这个方法直接让系统处理文件打开逻辑,适用于所有类型的文件,不会出现重复调用的冲突问题。
内容的提问来源于stack exchange,提问作者codeEnthusiast
相关产品推荐
相关产品推荐

