vba - VBA,如何快速检查文件是否存在(网络上的文件)
问题描述
我正在尝试检查网络上是否存在文件。但有时网络未连接,应用程序冻结。
Private Function FileExistsSlow(ByVal path_ As String) As Boolean
On Error Resume Next
FileExists = False
FileExists = (Len(Dir(path_)) > 0)
End Function
解决方案
这是快速变体
添加具有以下代码的模块:
#If VBA7 Then
Private Declare PtrSafe Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long
Private Declare PtrSafe Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Private Declare PtrSafe Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As LongPtr
Private Declare PtrSafe Function CloseHandle Lib "kernel32" (ByVal hObject As LongPtr) As Long
Private Declare PtrSafe Function FormatMessage Lib "kernel32" Alias "FormatMessageA" (ByVal dwFlags As Long, lpSource As Any, ByVal dwMessageId As Long, ByVal dwLanguageId As Long, ByVal lpBuffer As String, ByVal nSize As Long, Arguments As Long) As Long
#Else
Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA" (ByVal dwFlags As Long, lpSource As Any, ByVal dwMessageId As Long, ByVal dwLanguageId As Long, ByVal lpBuffer As String, ByVal nSize As Long, Arguments As Long) As Long
#End If
Public Const INFINITE = &HFFFF
Public Const PROCESS_ALL_ACCESS = &H1F0FFF
public Const SYNCHRONIZE = &H100000
Sub test()
If FileExistsFast("c:\Windows\win.ini") Then
MsgBox "exists"
Else
MsgBox "not"
End If
End Sub
Sub test_hard()
Dim file
file = "\\random" & Mid(Str(Rnd()), 3, 5) & "\Windows\win.ini"
'msgbox file
If FileExistsFast(file) Then
MsgBox "exists"
Else
MsgBox "not"
End If
End Sub
Public Function FileExistsFast(file)
FileExistsFast = False
Dim Cmd As String
Cmd = "cmd /c dir """ & file & """"
lTaskID = Shell(Cmd, 0)
' Get process handle
' lPID = OpenProcess(PROCESS_ALL_ACCESS, True, lTaskID)
lPID = OpenProcess(SYNCHRONIZE, True, lTaskID) ' suggested by a comment from IInspectable not sure if it works, should work
If lPID Then
'Wait for process to finish
Dim result As Integer
result = WaitForSingleObject(lPID, 1000) ' set tiemout for 1000 ms
If result > 240 Then ' 258 process not closed yet , 259 status of process is not closed
'MsgBox "not returned "
Else
'Get Exit Process
If GetExitCodeProcess(lPID, lexitcode) Then
'Received value
'MsgBox "Successfully returned " & lExitCode, vbInformation
If lexitcode = 0 Then
FileExistsFast = True
End If
Else
MsgBox "Failed: " & DLLErrorText(Err.LastDllError), vbCritical
End If
End If
lTaskID = CloseHandle(lPID)
Else
lTaskID = 0
MsgBox "Failed: " & DLLErrorText(Err.LastDllError), vbCritical
End If
End Function
Public Function DLLErrorText(ByVal lLastDLLError As Long) As String
Dim sBuff As String * 256
Dim lCount As Long
Const FORMAT_MESSAGE_ALLOCATE_BUFFER = &H100, FORMAT_MESSAGE_ARGUMENT_ARRAY = &H2000
Const FORMAT_MESSAGE_FROM_HMODULE = &H800, FORMAT_MESSAGE_FROM_STRING = &H400
Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000, FORMAT_MESSAGE_IGNORE_INSERTS = &H200
Const FORMAT_MESSAGE_MAX_WIDTH_MASK = &HFF
lCount = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM Or FORMAT_MESSAGE_IGNORE_INSERTS, 0, lLastDLLError, 0&, sBuff, Len(sBuff), ByVal 0)
If lCount Then
DLLErrorText = Left$(sBuff, lCount - 2) \\Remove line feeds
End If
End Function
推荐阅读
- python - ID 和月份上的 Groupby 列,并为每个月分配值作为新的 colmuns
- python - (已解决)- 在 Linux 中使用 Eric-IDE 和 pyenv
- python - 如何根据其他数据框的条件删除熊猫组
- python - Django:ModuleNotFoundError:没有名为“sslserver”的模块
- android - 每次切换标签时,AnyChart AreaChart 都会翻倍
- php - FFMPEG 执行退出代码 126
- c++ - std::atomic 中的任何内容都无需等待?
- pandas - Python pandas 分位数数据分析
- php - Laravel 不支持 DELETE & PUT 请求?
- php - 如何增加服务器发送事件的重新打开时间?