如何让Excel VBA在SolidWorks图纸完全加载后再执行后续操作?
解决方案:同步控制SolidWorks文件加载与VBA执行
方案1:直接使用SolidWorks COM自动化(推荐)
放弃Shell调用,直接通过VBA连接SolidWorks的COM对象,这样可以同步等待文件加载完成,还能直接读取零件/工程图信息,完全避免异步问题。
实现步骤与代码示例
先在Excel VBA编辑器中引用SolidWorks类型库:
- 打开VBA编辑器(Alt+F11)
- 点击「工具」→「引用」,找到并勾选
SolidWorks xx.x Object Library(xx.x对应你的SolidWorks版本)
核心代码:
Sub ExtractSolidWorksData() Dim swApp As SldWorks.SldWorks Dim swModel As SldWorks.ModelDoc2 Dim filePath As String Dim folderPath As String Dim fileExt As String ' 设置目标文件夹和文件扩展名(比如工程图.slddrw) folderPath = "C:\Your\Drawing\Folder\" fileExt = "*.slddrw" ' 创建或连接SolidWorks实例 Set swApp = CreateObject("SldWorks.Application") swApp.Visible = False ' 后台运行,提升效率 ' 遍历文件夹中的工程图文件 filePath = Dir(folderPath & fileExt) Do While filePath <> "" On Error Resume Next ' 打开文件,同步等待加载完成 Set swModel = swApp.OpenDoc6(folderPath & filePath, swDocDRAWING, swOpenDocOptions_Silent, "", 0, 0) On Error GoTo 0 If Not swModel Is Nothing Then ' 这里添加提取零件信息的代码 ' 示例:获取文件名和零件编号 Debug.Print "文件名:" & swModel.GetPathName Debug.Print "零件编号:" & swModel.GetCustomInfoValue("", "Part Number") ' 关闭文件,不保存 swApp.CloseDoc swModel.GetPathName Set swModel = Nothing Else Debug.Print "无法打开文件:" & folderPath & filePath End If ' 下一个文件 filePath = Dir() Loop ' 退出SolidWorks swApp.ExitApp Set swApp = Nothing End Sub
方案2:用Windows API等待Shell进程完成(兼容现有Shell调用逻辑)
如果必须保留Shell调用,可通过CreateProcess启动进程并使用WaitForSingleObject同步等待进程结束,替代固定时长的Application.Wait。
实现代码
' 声明Windows API函数 Private Declare PtrSafe Function CreateProcess Lib "kernel32" Alias "CreateProcessA" ( _ ByVal lpApplicationName As String, _ ByVal lpCommandLine As String, _ ByVal lpProcessAttributes As LongPtr, _ ByVal lpThreadAttributes As LongPtr, _ ByVal bInheritHandles As Long, _ ByVal dwCreationFlags As Long, _ ByVal lpEnvironment As LongPtr, _ ByVal lpCurrentDirectory As String, _ lpStartupInfo As STARTUPINFO, _ lpProcessInformation As PROCESS_INFORMATION) As LongPtr Private Declare PtrSafe Function WaitForSingleObject Lib "kernel32" ( _ ByVal hHandle As LongPtr, _ ByVal dwMilliseconds As Long) As LongPtr Private Declare PtrSafe Function CloseHandle Lib "kernel32" ( _ ByVal hObject As LongPtr) As LongPtr Private Type STARTUPINFO cb As Long lpReserved As String lpDesktop As String lpTitle As String dwX As Long dwY As Long dwXSize As Long dwYSize As Long dwXCountChars As Long dwYCountChars As Long dwFillAttribute As Long dwFlags As Long wShowWindow As Integer cbReserved2 As Integer lpReserved2 As LongPtr hStdInput As LongPtr hStdOutput As LongPtr hStdError As LongPtr End Type Private Type PROCESS_INFORMATION hProcess As LongPtr hThread As LongPtr dwProcessId As Long dwThreadId As Long End Type Private Const INFINITE = &HFFFFFFFF Sub RunSolidWorksAndWait() Dim swExePath As String Dim drawingPath As String Dim cmdLine As String Dim si As STARTUPINFO Dim pi As PROCESS_INFORMATION Dim result As LongPtr ' SolidWorks安装路径(根据你的实际路径修改) swExePath = "C:\Program Files\SOLIDWORKS Corp\SOLIDWORKS\SLDWORKS.exe" ' 目标工程图路径 drawingPath = "C:\Your\Drawing\Path\Sample.slddrw" ' 构造命令行 cmdLine = """" & swExePath & """ """ & drawingPath & """" ' 初始化STARTUPINFO si.cb = Len(si) ' 启动SolidWorks进程 result = CreateProcess(vbNullString, cmdLine, 0, 0, 1, 0, 0, "", si, pi) If result <> 0 Then ' 等待进程结束(无限等待,直到图纸处理完成) WaitForSingleObject pi.hProcess, INFINITE ' 关闭句柄 CloseHandle pi.hThread CloseHandle pi.hProcess Else Debug.Print "无法启动SolidWorks进程" End If End Sub
关键说明
- 方案1的优势:直接与SolidWorks交互,能精确控制文件加载、信息提取的全流程,不需要依赖外部进程等待,效率更高,还能直接访问SolidWorks的所有API接口获取详细信息。
- 方案2适合必须保留Shell调用的场景,但需要注意:如果Shell启动的是SolidWorks打开图纸后自动关闭的宏,这个方法才有效;如果SolidWorks打开图纸后保持运行,
WaitForSingleObject会一直等待,需要配合自动关闭的宏使用。
内容的提问来源于stack exchange,提问作者Nick Wester
相关产品推荐
相关产品推荐

