Skip to main content

Open associated drawings of active document or selected components

This VBA macro allows to open the associated drawings of the selected components in the assembly or active document if nothing is selected.

Unlike out-of-the-box functionality this macro does not have a limitation related to the drawing to be named after the component and located in the same folder. This macro will find all drawings in all sub-folders of the current folder (folder of the active document) regardless if those are named after the component or not.

This macro has an option to open the drawing resolved or in the detailing mode. Modify the value oif OPEN_DRAWING_DETAILING to change the behavior.

Const OPEN_DRAWING_DETAILING As Boolean = True 'opens drawings in detailing mode
Const OPEN_DRAWING_DETAILING As Boolean = False

Dim swApp As SldWorks.SldWorks

Sub main()

Set swApp = Application.SldWorks

Dim swModel As SldWorks.ModelDoc2

Set swModel = swApp.ActiveDoc

try_:
On Error GoTo catch_

If Not swModel Is Nothing Then

If swModel.GetType() <> swDocumentTypes_e.swDocASSEMBLY And _
swModel.GetType() <> swDocumentTypes_e.swDocPART Then
Err.Raise vbError, "", "Active document is not a part or assembly"
End If

Dim vDrawings As Variant

vDrawings = FindDrawings(swModel)

OpenDrawings vDrawings

GoTo finally_

Else
Err.Raise vbError, "", "Please open assembly or drawing document"
End If

catch_:
swApp.SendMsgToUser2 Err.Description, swMessageBoxIcon_e.swMbStop, swMessageBoxBtn_e.swMbOk
finally_:

End Sub

Sub OpenDrawings(vPaths As Variant)

If Not IsEmpty(vPaths) Then

Dim i As Integer

For i = 0 To UBound(vPaths)

Dim drwFilePath As String
drwFilePath = vPaths(i)

Dim swDocSpec As SldWorks.DocumentSpecification
Set swDocSpec = swApp.GetOpenDocSpec(drwFilePath)

If OPEN_DRAWING_DETAILING Then
swDocSpec.DetailingMode = True
End If

Dim swDraw As SldWorks.ModelDoc2
Set swDraw = swApp.OpenDoc7(swDocSpec)

If swDraw Is Nothing Then
Err.Raise vbError, "", "Failed to open drawing. Error code: " & swDocSpec.Error
End If

Next

Else
Err.Raise vbError, "", "No component selected"
End If

End Sub

Function FindDrawings(model As SldWorks.ModelDoc2) As Variant

Dim drwFilePaths() As String

Dim vDrws As Variant
Dim i As Integer
Dim j As Integer

Dim swSelMgr As SldWorks.SelectionMgr
Set swSelMgr = model.SelectionManager

Dim rootDir As String
rootDir = Left(model.GetPathName(), InStrRev(model.GetPathName(), "\"))

If swSelMgr.GetSelectedObjectCount2(-1) = 0 Then

vDrws = FindAssociatedDrawings(rootDir, model.GetPathName())
ReDim drwFilePaths(UBound(vDrws))

For j = 0 To UBound(vDrws)
drwFilePaths(j) = vDrws(j)
Next

Else

For i = 1 To swSelMgr.GetSelectedObjectCount2(-1)

Dim path As String
Dim confName As String

Dim swComp As SldWorks.Component2
Set swComp = swSelMgr.GetSelectedObjectsComponent4(i, -1)

If Not swComp Is Nothing Then

path = swComp.GetPathName()

If model.IsOpenedViewOnly() Then
path = ResolveReferencePath(model.GetPathName(), path)
End If

vDrws = FindAssociatedDrawings(rootDir, path)

For j = 0 To UBound(vDrws)

Dim drwFilePath As String
drwFilePath = vDrws(j)

Dim unique As Boolean
unique = False

If (Not drwFilePaths) = -1 Then
ReDim drwFilePaths(0)
unique = True
Else
unique = Not ContainsFilePath(drwFilePaths, drwFilePath)
If True = unique Then
ReDim Preserve drwFilePaths(UBound(drwFilePaths) + 1)
End If
End If

If True = unique Then
drwFilePaths(UBound(drwFilePaths)) = drwFilePath
End If

Next

End If

Next

End If

If (Not drwFilePaths) <> -1 Then
FindDrawings = drwFilePaths
Else
FindDrawings = Empty
End If

End Function

Function FindAssociatedDrawings(rootDir As String, filePath As String) As Variant

Dim paths() As String

Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")

Dim folder As Object
Set folder = fso.GetFolder(rootDir)

CollectDrawingFilesFromFolder folder, filePath, paths

If (Not paths) <> -1 Then
FindAssociatedDrawings = paths
Else
Err.Raise vbError, "", "Failed to find the associated drawings for " & filePath
End If

End Function

Sub CollectDrawingFilesFromFolder(folder As Object, targetFilePath As String, ByRef paths() As String)

For Each file In folder.files

Dim fileExt As String
fileExt = Right(file.path, Len(file.path) - InStrRev(file.path, "."))

If LCase(fileExt) = LCase("slddrw") Then

If IsReferencingDrawing(file.path, targetFilePath) Then
If (Not paths) = -1 Then
ReDim paths(0)
Else
ReDim Preserve paths(UBound(paths) + 1)
End If
paths(UBound(paths)) = file.path
End If
End If
Next

Dim subFolder As Object
For Each subFolder In folder.SubFolders
CollectDrawingFilesFromFolder subFolder, targetFilePath, paths
Next

End Sub

Function IsReferencingDrawing(drwFilePath As String, destFilePath As String) As Boolean

Dim vDepends As Variant
vDepends = swApp.GetDocumentDependencies2(drwFilePath, False, True, False)

Dim i As Integer

If Not IsEmpty(vDepends) Then

For i = 1 To UBound(vDepends) Step 2

If LCase(CStr(vDepends(i))) = LCase(destFilePath) Then
IsReferencingDrawing = True
Exit Function
End If
Next
End If

IsReferencingDrawing = False

End Function

Function ContainsFilePath(vPaths As Variant, path As String) As Boolean

Dim i As Integer

For i = 0 To UBound(vPaths)
If LCase(path) = LCase(vPaths(i)) Then
ContainsFilePath = True
Exit Function
End If
Next

ContainsFilePath = False

End Function

Function ResolveReferencePath(rootDocPath As String, refPath As String) As String

Dim pathParts As Variant
pathParts = Split(refPath, "\")

Dim rootFolder As String
rootFolder = rootDocPath
rootFolder = Left(rootFolder, InStrRev(rootFolder, "\") - 1)

Dim i As Integer

Dim curRelPath As String

For i = UBound(pathParts) To 1 Step -1

curRelPath = pathParts(i) & IIf(curRelPath <> "", "\", "") & curRelPath
Dim path As String
path = rootFolder & "\" & curRelPath

If Dir(path) <> "" Then
ResolveReferencePath = path
Exit Function
End If

Next

ResolveReferencePath = refPath

End Function