This website uses cookies to ensure you get the best experience on our website. By using our website you agree on the following Cookie Policy, Privacy Policy, and Terms Of Use
This VBA macro mimics the functionality of Make Independent feature of SOLIDWORKS, but will also additionally copy and rename the file associated with the copied part or assembly component.
This macro can work with a single component or multiple selected components, but all of the components must correspond to the same file.
Macro will copy the associated drawing and place it next to the target file with the same name.
Notes
Macro will only copy drawing which matches the name of the source file and placed in the same folder
To specify the subfolder of the drawings set the sub folder name in DRAWINGS_FOLDER constant. It is also possible to use an absolute path to specify the external drawings folder
Macro will not overwrite the destination drawing file if already exists
#If VBA7 ThenPrivateDeclare PtrSafe Function PathIsRelative Lib"shlwapi"Alias"PathIsRelativeA" (ByVal path AsString) AsBoolean#ElsePrivateDeclareFunction PathIsRelative Lib"shlwapi"Alias"PathIsRelativeA" (ByVal Path AsString) Asboolean#End IfPrivateDeclare PtrSafe Function GetSaveFileName Lib"comdlg32.dll"Alias"GetSaveFileNameA" (pOpenfilename As OPENFILENAME) AsBooleanPrivate Type OPENFILENAME
lStructSize AsLong
hwndOwner As LongPtr
hInstance As LongPtr
lpstrFilter AsString
lpstrCustomFilter AsString
nMaxCustFilter AsLong
nFilterIndex AsLong
lpstrFile AsString
nMaxFile AsLong
lpstrFileTitle AsString
nMaxFileTitle AsLong
lpstrInitialDir AsString
lpstrTitle AsString
Flags As LongPtr
nFileOffset AsInteger
nFileExtension AsInteger
lpstrDefExt AsString
lCustData AsLong
lpfnHook AsLong
lpTemplateName AsStringEnd Type
Const DRAWINGS_FOLDER AsString = ""Dim swApp As SldWorks.SldWorks
Sub main()
Set swApp = Application.SldWorks
try_:
OnErrorGoTo catch_
Dim swModel As SldWorks.ModelDoc2
Set swModel = swApp.ActiveDoc
IfNot swModel IsNothingThenIf swModel.GetType() = swDocumentTypes_e.swDocASSEMBLY ThenDim swAssy As SldWorks.AssemblyDoc
Set swAssy = swModel
Dim vComps AsVariant
vComps = GetSelectedComponents(swModel.SelectionManager)
IfNot IsEmpty(vComps) ThenDim i AsIntegerDim path AsString
path = vComps(0).GetPathName()
For i = 1 To UBound(vComps)
If LCase(vComps(i).GetPathName()) <> LCase(path) Then
Err.Raise vbError, "", "Only identical components are supported"EndIfNextDim ext AsString
ext = Right(path, Len(path) - InStrRev(path, ".") + 1)
Dim filter AsStringDim fileType AsStringIf LCase(ext) = ".sldprt"Then
fileType = "SOLIDWORKS Parts"ElseIf LCase(ext) = ".sldasm"Then
fileType = "SOLIDWORKS Assemblies"Else
Err.Raise vbError, "", "Unknown error"EndIf
filter = fileType & " (*" & ext & ")|*" & ext & "|All Files (*.*)|*.*"Dim replaceFilePath AsString
replaceFilePath = BrowseForFileSave("Select replacement file path", filter, path)
If replaceFilePath <> ""ThenIfFalse = swAssy.MakeIndependent(replaceFilePath) Then
Err.Raise vbError, "", "Failed to make components independent"EndIf
MakeDrawingIndependent path, replaceFilePath
EndIfElse
Err.Raise vbError, "", "Select components"EndIfElse
Err.Raise vbError, "", "Only assembly documents are supported"EndIfElse
Err.Raise vbError, "", "No model found"EndIfGoTo finally_
catch_:
MsgBox Err.Description, vbCritical
finally_:
EndSubSub MakeDrawingIndependent(srcFilePath AsString, destFilePath AsString)
Dim srcDrwFilePath AsString
srcDrwFilePath = ResolveDrawingPath(srcFilePath)
Dim fso AsObjectSet fso = CreateObject("Scripting.FileSystemObject")
If fso.FileExists(srcDrwFilePath) ThenDim destDrwFilePath AsString
destDrwFilePath = ResolveDrawingPath(destFilePath)
If fso.FileExists(destDrwFilePath) Then
Err.Raise vbError, "", "Destination drawing already exists"EndIf
fso.CopyFile srcDrwFilePath, destDrwFilePath, FalseDim destDrwFilePathAttr As VbFileAttribute
destDrwFilePathAttr = GetAttr(destDrwFilePath)
If destDrwFilePathAttr And vbReadOnly Then
Debug.Print "Removing the read-only flag from the destination drawing: " & destDrwFilePath
SetAttr destDrwFilePath, destDrwFilePathAttr Xor vbReadOnly
EndIfIfFalse = swApp.ReplaceReferencedDocument(destDrwFilePath, srcFilePath, destFilePath) Then
Err.Raise vbError, "", "Failed to replace referenced drawing document"EndIfEndIfEndSubFunction ResolveDrawingPath(origFilePath AsString) AsStringDim targFolder AsStringIf DRAWINGS_FOLDER = ""Then
targFolder = GetFolderName(origFilePath)
ElseIf PathIsRelative(DRAWINGS_FOLDER) Then
targFolder = GetFolderName(origFilePath) & "\" & DRAWINGS_FOLDER
Else
targFolder = DRAWINGS_FOLDER
EndIfEndIf
ResolveDrawingPath = targFolder & "\" & GetFileNameWithoutExtension(origFilePath) & ".slddrw"EndFunctionFunction GetSelectedComponents(selMgr As SldWorks.SelectionMgr) AsVariantDim isInit AsBoolean
isInit = FalseDim swComps() As SldWorks.Component2
Dim i AsIntegerFor i = 1 To selMgr.GetSelectedObjectCount2(-1)
Dim swComp As SldWorks.Component2
Set swComp = selMgr.GetSelectedObjectsComponent4(i, -1)
IfNot swComp IsNothingThenIfNot isInit ThenReDim swComps(0)
Set swComps(0) = swComp
isInit = TrueElseIfNot Contains(swComps, swComp) ThenReDimPreserve swComps(UBound(swComps) + 1)
Set swComps(UBound(swComps)) = swComp
EndIfEndIfEndIfNextIf isInit Then
GetSelectedComponents = swComps
Else
GetSelectedComponents = Empty
EndIfEndFunctionFunction BrowseForFileSave(title AsString, filters AsString, initFilePath AsString) AsStringDim ofn As OPENFILENAME
Const FILE_PATH_BUFFER_SIZE AsInteger = 260
Dim initFileName AsString
initFileName = Right(initFilePath, Len(initFilePath) - InStrRev(initFilePath, "\"))
ofn.lpstrFilter = Replace(filters, "|", Chr(0)) & Chr(0)
ofn.lpstrTitle = title
ofn.nMaxFile = FILE_PATH_BUFFER_SIZE
ofn.nMaxFileTitle = FILE_PATH_BUFFER_SIZE
ofn.lpstrInitialDir = Left(initFilePath, InStrRev(initFilePath, "\") - 1)
ofn.lpstrFile = initFileName & String(FILE_PATH_BUFFER_SIZE - Len(initFileName), Chr(0))
ofn.lStructSize = LenB(ofn)
Dim res AsBoolean
res = GetSaveFileName(ofn)
If res ThenDim filePath AsString
filePath = Left(ofn.lpstrFile, InStr(ofn.lpstrFile, vbNullChar) - 1)
Dim vFilters AsVariant
vFilters = Split(filters, "|")
Dim ext AsString
ext = vFilters((ofn.nFilterIndex - 1) * 2 + 1)
ext = Right(ext, Len(ext) - InStrRev(ext, ".") + 1)
If LCase(Right(filePath, Len(ext))) <> LCase(ext) Then
filePath = filePath & ext
EndIf
BrowseForFileSave = filePath
Else
BrowseForFileSave = ""EndIfEndFunctionFunction Contains(vArr AsVariant, item AsObject) AsBooleanDim i AsIntegerFor i = 0 To UBound(vArr)
If vArr(i) Is item Then
Contains = TrueExitFunctionEndIfNext
Contains = FalseEndFunctionFunction GetFolderName(filePath AsString) AsString
GetFolderName = Left(filePath, InStrRev(filePath, "\") - 1)
EndFunctionFunction GetFileNameWithoutExtension(filePath AsString) AsString
GetFileNameWithoutExtension = Mid(filePath, InStrRev(filePath, "\") + 1, InStrRev(filePath, ".") - InStrRev(filePath, "\") - 1)
EndFunction
Notifications
Join session by SOLIDWORKS and PDM API expret Artem Taturevych at 3DEXPERIENCE World 2025 on Feb 26 at 08:30 AM CST to explore 10 essential macros for automating drawings, assemblies, custom properties, and more