Hello I am looking for an automatic solution (i.e. invisible to the average user) to clean up the data card of a virtual part/assembly contained in another assembly. Indeed, if I pass a part virtually in an assembly, it retains its Solidworks properties, in particular the part number which can create a conflict with the original part (because the part number is a PDM variable that must be unique in the vault). I thought in particular of creating a vba macro under SW that would take care of the removal of the SW property in question. I have several questions:
When and how to launch this macro automatically? On an archiving action? Recording? During a change of state?
What is the syntax for extracting/checking in a file in VBA SW?
Is there a simpler solution? (set up under SW how is a virtual managed ?
Hello For the macro side, you can't launch it automatically, you have to go through an add-in and work with the events. So to program in a .NET language After that, I don't know if there is a simpler solution
The macro must already be launched to react to a change in PDM state, this is called event management. A method subscribes to an event, and when the event is fired, the method executes. So we come back to the add-in box.
Hello Without necessarily going through an add-in, you can also modify the link that points to the SW exe to add the launch of a macro at startup. This would allow the use of SW and PDM events. Disadvantage of this method you have to intervene on all the workstations to change this link and remember to do it each time SW version is changed. Otherwise, would your users really be against adding an icon to click to initiate an action?
They wouldn't be against it, but they wouldn't launch it. The problem is invisible to them, the block is done later when a change of state is made wrong because it is variable in duplicate.
That's the problem So there is still the add-in or succeed in modifying the exe launch link to be able to inject a macro when SW is launched. I would have otherwise proposed dispatch to do the control during archiving but it seems to me that on the PDM side the virtual files are not really managed so dispatch could not interpret them since they are not physical files. On the other hand, with the macro to be launched manually, just add a property to the file and check if it is present during the check-in. If not present, refuse the archiving
Thank you for your feedback. What does an add-in mean? Coding a coplement a bit like MyPDMTools? The .exe it's a good idea, except that you should rather launch the macro after the modifications, not at the opening . But I could also run it only on the automaton that generates our neutral files... I have to dig deeper. Dispatch is also a solution, even if it means running it on all files without targeting.
Last question: when you say "refuse archiving" at the end of your message, it's more like refusing the change of state, isn't it? It didn't seem to me that we could block an archive.
You can block an archive, I do it on a Word file that doesn't use the right frame for example. For the macro launched at the opening, it's just a macro that would run in the background and intercept the SW events to apply processing according to the targeted event. An add-in is an executable, but there again, it has to be launched.
So for the time being, I want to know how to block an archive of a file that doesn't have the right frame (for example), because for the moment I know how to do it only by blocking the change of state. Do you use variable valuation when the right frame is used? To my knowledge I only have these options to block an archive:
And possibly on the variable side, this checkbox, but it doesn't check the value, only its existence:
Something that can help to implement a macro: in Solidworks, all virtual files contain the ^ character followed by the name of the file in which the virtual file is saved (NB: In case of sub-level we also have _ characters in addition to the ^ character in the name of the virtual file, but it shouldn't have any impact). So it's on files containing this ^ character that you should run your macro (it should avoid putting the strand in non-virtual files). Because virtual files are temporary, the macro must be launched on an open assembly. in normal work mode it should work but if a clever guy has fun archiving/transitioning a file containing virtual via Windows it's dead (unless you force open the file in Solidworks before working on the property cleanup).
For the macro part, it is surely our friend @Cyril.f who will be the most savvy.
Thank you both, I have to dig into your proposals. For the fact that the file must be opened, it can be feasible because it is precisely when opening the asm on a PLC to generate neutral files that the archiving problem arises (and strangely not when it is the designer who archives...). So I could run the macro on the automaton before the generation.
Hi everyone, and Happy New Year! I'll come back to my topic of cleaning properties in virtuals. Before dealing with the "launch a macro automatically" part, I would first try to create a macro that I would be able to manually launch on a blocked file, as an admin. Could any of you guide me to write a macro that would do the following actions:
On an assembly that is already open, scan all assemblies and child parts
If the child's name contains the character "^", open it
Open the properties window for this virtual file
remove the "Reference" property in the "Customize" tab and in all configurations present in the "Configuration Specific" tab
Close the Properties window
If the open virtual file is itself an assembly, loop in the same way on its children
Save the virtual file
Move on to the next child
Buckling up to the last child
display a pop-up when it's finished.
Obviously what I'm describing is the sequence of actions via windows, there is surely a way to simplify all this via functions but I'm a big noob of SW macros. On the other hand I'm ready to learn if I'm guided with examples of extant macros, I'm not asking for a ready-made job. I tried via the "Record macro" function but it doesn't work on the Properties window.
At the same time, I'll try to see if I can use the BatchProperties tool of myCADTools.
Code not necessarily optimized but partly meets the need. For the loopback on a virtual ASM I haven't had time to look yet (if it inspires someone else to finish the code because not necessarily more time to spend on it for the moment).
Option Explicit
Dim swApp As SldWorks.SldWorks
Dim doc As SldWorks.ModelDoc2
Dim swModel As SldWorks.ModelDoc2
Dim asm As SldWorks.AssemblyDoc
Dim compDoc As SldWorks.ModelDoc2
Dim swModelDocExt As ModelDocExtension
Dim swCustProp As CustomPropertyManager
Dim swConfig As SldWorks.Configuration
Dim swConfMgr As SldWorks.ConfigurationManager
Dim comp As SldWorks.Component2
Dim components As Variant
Dim vComp As Variant
Dim pathChain As Variant
Dim titleChain As Variant
Dim vPath As Variant
Dim vConfigNameArr As Variant
Dim vConfigName As Variant
Dim vPropNames As Variant
Dim vPropTypes As Variant
Dim vPropValues As Variant
Dim resolved As Variant
Dim linkProp As Variant
Dim nDocType As Long
Dim nErrors As Long
Dim nWarnings As Long
Dim nNbrProps As Long
Dim lRetVal As Long
Dim j As Long
Dim i As Long
Dim bResult3 As Boolean
Dim boolstatus As Boolean
Dim wasResolved As Boolean
Dim linkToProp As Boolean
Dim ValOut As String
Dim ResolvedValOut As String
Dim sCustProp As String
Dim sConfig As String
Sub main()
Set swApp = Application.SldWorks
Set doc = swApp.ActiveDoc
If doc Is Nothing Then Exit Sub
If doc.GetType <> swDocASSEMBLY Then Exit Sub
Set asm = doc
components = asm.GetComponents(False) ' Get all components
If IsArray(components) Then
For Each vComp In components
Set comp = vComp
Set compDoc = comp.GetModelDoc2
If Not compDoc Is Nothing Then
bResult3 = compDoc.Extension.IsVirtualComponent3(pathChain, titleChain)
If bResult3 <> False Then
For Each vPath In pathChain
If vPath <> doc.GetPathName Then
If InStr(LCase(vPath), "sldprt") > 0 Then
nDocType = swDocPART
ElseIf InStr(LCase(vPath), "sldasm") > 0 Then
nDocType = swDocASSEMBLY
ElseIf InStr(LCase(vPath), "slddrw") > 0 Then
nDocType = swDocDRAWING
Else
' Probably not a SOLIDWORKS file
nDocType = swDocNONE
' So cannot open the file
Exit Sub
End If
Set swModel = swApp.OpenDoc6(vPath, nDocType, swOpenDocOptions_Silent, "", nErrors, nWarnings)
Set swModelDocExt = swModel.Extension
Set swCustProp = swModelDocExt.CustomPropertyManager("")
nNbrProps = swCustProp.Count
lRetVal = swCustProp.GetAll3(vPropNames, vPropTypes, vPropValues, resolved, linkProp)
For j = 0 To nNbrProps - 1
For i = 0 To UBound(vPropNames)
sCustProp = vPropNames(i)
boolstatus = swModel.DeleteCustomInfo2("", sCustProp)
Next i
Next j
Set swConfMgr = swModel.ConfigurationManager
Set swConfig = swConfMgr.ActiveConfiguration
vConfigNameArr = swModel.GetConfigurationNames
For Each vConfigName In vConfigNameArr
Set swCustProp = swModelDocExt.CustomPropertyManager(vConfigName)
nNbrProps = swCustProp.Count
lRetVal = swCustProp.GetAll3(vPropNames, vPropTypes, vPropValues, resolved, linkProp)
For j = 0 To nNbrProps - 1
sConfig = vConfigName
For i = 0 To UBound(vPropNames)
sCustProp = vPropNames(i)
boolstatus = swModel.DeleteCustomInfo2(sConfig, sCustProp)
Next i
Next j
Next
End If
Next
End If
End If
Next
End If
End Sub
Wow but that's great! And it works Thank you so much! I'll be satisfied with that for the moment, it doesn't actually close on asm child but I can restart it after having the asm child in question, it's fine with me! I'll still see if I can nest an extra loop if nDocType = dwDocASSEMBLY. Thanks again