Emptying the properties of a virtual (by macro?)

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 ?

Thank you in advance for your ideas!

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

And is launching during a PDM state change feasible?

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.

OK, I have to dig into the add-in topic, I don't know what it is.

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?

1 Like

They wouldn't be against it, but they wouldn't :slight_smile: 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 :slight_smile:
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 :slight_smile: . 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:
2023-11-03 14_40_47-Window

And possibly on the variable side, this checkbox, but it doesn't check the value, only its existence:
2023-11-03 14_45_36-Clipboard

I do it with dispatch.

Not tested on SW, but in any case works very well on Word (it cancels the archive request and reopens the file)

2 Likes

Hello

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.

1 Like

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 :slight_smile: 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.

Hello

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 :slight_smile:
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 :stuck_out_tongue: me!
I'll still see if I can nest an extra loop if nDocType = dwDocASSEMBLY.
Thanks again

1 Like