前言

在之前写的 SolidWorks 遍历装配体(VBA)中介绍了一种遍历装配体的方法,但是有一些缺点,比如会跳过已压缩和轻化的零部件。如果要想解决这个问题,那么运行起来会速度很慢。所以我又发现了另一种快速遍历装配体的方法。

思路

通过不断递归使用 TraverseComponent 这个函数,实现获取装配体下的每一个零部件名称。

TraverseComponent

1
2
3
4
5
6
7
8
9
10
11
12
13
'遍历装配体
Sub TraverseComponent(swComp As SldWorks.Component2)
Dim vChildComp As Variant
Dim swChildComp As SldWorks.Component2
Dim i As Long

vChildComp = swComp.GetChildren
For i = 0 To UBound(vChildComp)
Set swChildComp = vChildComp(i)
Debug.Print swChildComp.Name2
TraverseComponent swChildComp
Next i
End Sub

奇怪的输出

嵌套装配体

如果实际运行的话,会发现输出的只有零件名称。比如装配体 Asm 下有装配体 Asm1零件 Prt2装配体 Asm1 下有零件 Prt1.1Prt1.2,实际输出会不包含装配体 Asm装配体 Asm1,只会有零件 Prt1零件 Prt1.1零件 Prt1.1。所以需要加上 swComp.Name2 来输出其中的装配体。

奇怪的文件名?

  1. 如果有嵌套装配体的话,会发现输出是装配体 / 零部件名,比如 Asm1-1/Prt1.1-1
  2. 实际运行起来会发现输出的零部件名后面带了个 “-X”(X 为数字),这其实是因为 SolidWorks 会自动在装配体下的零部件加上唯一的实例序号 X,用于区分多个相同零部件。想要把这个去掉我也没想到有特别好的办法,只能匹配最后几个字符去除。

完整代码

经改进优化后的代码是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
Option Explicit

Sub main()

'施法前摇
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc

If swModel.GetType <> SwConst.swDocASSEMBLY Then
swApp.SendMsgToUser "请在装配体中运行"
Exit Sub
End If

'遍历装配(使用字典去除重复出现的零部件名)
Dim swConfMgr As SldWorks.ConfigurationManager
Dim swConf As SldWorks.Configuration
Dim swRootComp As SldWorks.Component2
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
Set swConfMgr = swModel.ConfigurationManager
Set swConf = swConfMgr.ActiveConfiguration
Set swRootComp = swConf.GetRootComponent3(True)
Debug.Print "File = " & swModel.GetPathName
If swModel.GetType = SwConst.swDocASSEMBLY Then
TraverseComponent swRootComp, dict
End If
'增加顶层装配体
dict(Left(swModel.GetTitle, InStrRev(swModel.GetTitle, ".") - 1)) = ""
End Sub

'遍历装配体
Sub TraverseComponent(swComp As SldWorks.Component2)
Dim vChildComp As Variant
Dim swChildComp As SldWorks.Component2
Dim i As Long

vChildComp = swComp.GetChildren
For i = 0 To UBound(vChildComp)
Set swChildComp = vChildComp(i)
'零件名
dict(TrueName(swChildComp.Name2)) = ""
'装配体名
dict(TrueName(swComp.Name2)) = ""
TraverseComponent swChildComp, dict
Next i
End Sub

'获取真实零部件名
Function TrueName(longname As String)
'获取最后一个/后面的零件名
If InStr(longname, "/") > 0 Then
Dim tmp As Variant
tmp = Split(longname, "/")
tmp = tmp(UBound(tmp))
TrueName = Left(tmp, InStrRev(tmp, "-") - 1)
Else
'这里暂时没想到更好的方法
TrueName = IIf(InStr(Right(longname, 3), "-"), _
Left(longname, InStrRev(longname, "-") - 1), _
longname)
End If

End Function

网站地图 | 状态监测 | 图片加密&解密 | File Server | 博友圈 | 博客说
Copyright 2022-2025 | Powered by Hexo 7.3.0 & Stellar 1.29.1
总访问量次 |