如何使用VBA在关闭MS Access表单时关闭已打开的PDF文件?
用VBA实现Access表单关闭时自动关闭对应PDF发票
完全可以通过VBA实现这个需求,核心思路是打开PDF时记录其进程ID,在表单关闭时根据该ID终止对应进程。以下是具体实现步骤和代码:
步骤1:声明必要的Windows API和变量
在Access表单的模块中,先声明用于启动进程、获取进程ID和终止进程的Windows API,同时定义一个私有变量存储PDF的进程ID:
' 定义ShellExecuteEx所需的结构 Private Type SHELLEXECUTEINFO cbSize As Long fMask As Long hwnd As Long lpVerb As String lpFile As String lpParameters As String lpDirectory As String nShow As Long hInstApp As Long lpIDList As Long lpClass As String hkeyClass As Long dwHotKey As Long hIcon As Long hProcess As Long End Type ' 声明API函数 Private Declare PtrSafe Function ShellExecuteEx Lib "shell32.dll" Alias "ShellExecuteExA" (lpExecInfo As SHELLEXECUTEINFO) As Long Private Declare PtrSafe Function OpenProcess Lib "kernel32.dll" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long Private Declare PtrSafe Function TerminateProcess Lib "kernel32.dll" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long Private Declare PtrSafe Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long Private Declare PtrSafe Function GetProcessId Lib "kernel32.dll" (ByVal hProcess As Long) As Long ' 定义常量 Private Const SEE_MASK_NOCLOSEPROCESS = &H40 Private Const PROCESS_TERMINATE = &H1 ' 存储PDF进程ID的变量 Private pdfProcessId As Long
步骤2:编写打开PDF并记录进程ID的函数
这个函数会调用系统默认的PDF阅读器打开文件,并捕获其进程ID:
Private Sub OpenPdfAndRecordId(pdfPath As String) Dim sei As SHELLEXECUTEINFO ' 初始化SHELLEXECUTEINFO结构 sei.cbSize = Len(sei) sei.fMask = SEE_MASK_NOCLOSEPROCESS sei.hwnd = Me.hwnd sei.lpVerb = "open" sei.lpFile = pdfPath sei.lpParameters = "" sei.lpDirectory = "" sei.nShow = vbNormalFocus sei.hInstApp = 0 sei.lpIDList = 0 ' 执行打开操作并获取进程句柄 If ShellExecuteEx(sei) Then pdfProcessId = GetProcessId(sei.hProcess) CloseHandle sei.hProcess ' 关闭进程句柄 End If End Sub
步骤3:触发PDF打开操作
在表单的合适事件(比如按钮点击、表单加载)中调用上面的函数,传入PDF文件路径。示例为按钮点击事件:
Private Sub cmdOpenInvoicePdf_Click() Dim fd As FileDialog Set fd = Application.FileDialog(msoFileDialogFilePicker) With fd .Filters.Clear .Filters.Add "PDF文件", "*.pdf" .AllowMultiSelect = False If .Show = -1 Then OpenPdfAndRecordId .SelectedItems(1) End If End With Set fd = Nothing End Sub
步骤4:表单关闭时终止PDF进程
在表单的Form_Close事件中,根据记录的进程ID关闭PDF进程:
Private Sub Form_Close() Dim hProcess As Long ' 如果存在有效的进程ID If pdfProcessId <> 0 Then ' 获取进程的终止权限句柄 hProcess = OpenProcess(PROCESS_TERMINATE, False, pdfProcessId) If hProcess <> 0 Then ' 终止进程 TerminateProcess hProcess, 0 CloseHandle hProcess ' 关闭句柄 End If End If End Sub
注意事项
- 该方法适用于所有系统默认的PDF阅读器(如Adobe Acrobat、Microsoft Edge、Foxit Reader等),因为ShellExecuteEx会调用关联的程序并捕获其进程。
- 如果用户手动关闭了PDF文件,表单关闭时该代码不会报错(进程已不存在,
OpenProcess会返回0,后续操作会跳过)。 - 确保用户有足够的权限终止进程,本地用户打开的PDF进程一般都有权限操作。
内容的提问来源于stack exchange,提问作者user2395238
相关产品推荐
相关产品推荐

