Macro Identification and Removal of Faulted Constraints

Hi everyone!

Let's cut to the chase:
BE of 28 people who were misinformed about the option Delete child features in assemblies

and who today are annoyed with this:

.

I am asked today if it is possible with a macro to identify the constraints in error due to missing components and to remove them.

With the help of the AI, I have this code which unfortunately is not operational (the condition If swFeature.GetTypeName = " Mate " is never checked):

Dim swApp As Object
Dim swModel As ModelDoc2
Dim swAssembly As AssemblyDoc
Dim swMate As Mate2
Dim swFeature As Feature
Dim swEntity As Object
Dim swComponent As Component2
Dim swError As Long

Sub main()

Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
Set swAssembly = swModel

' Parcourir toutes les contraintes de l'assemblage
Set swFeature = swAssembly.FirstFeature
    Do While Not swFeature Is Nothing
        If swFeature.GetTypeName = "Mate" Then
            Set swMate = swFeature.GetSpecificFeature2
            swError = swMate.Status
            ' Vérifier si la contrainte est en erreur
            If swError <> swMateStatusOK Then
                ' Vérifier les composants associés
                Set swEntity = swMate.GetMateEntities(0)
                If Not swEntity Is Nothing Then
                    Set swComponent = swEntity.GetComponent
                    If swComponent Is Nothing Then
                        ' Supprimer la contrainte en erreur
                        swAssembly.DeleteFeature swFeature.Name
                    End If
                End If
            End If
        End If
        Set swFeature = swFeature.GetNextFeature
    Loop
End Sub

Could anyone tell me what's wrong?
Thank you in advance.

Have you tried with " Constraints " instead of " Mate "? :


Edit: after quick test and adding a debug.print:
image

MateGroup seems to work for the 1st check, but it bugs again just behind.

Hello
This example of the API seems to me to meet the need for constraint scanning.
Get Mates and Mate Entities Example (VBA) - 2024 - SOLIDWORKS API Help
On the other hand, for the broken constrained part there is nothing direct if I don't make a mistake, so you have to manage a processing on the line of the example:

  Debug.Print "      Component         = " & swComp.Name2

In my tests, normally there are the two components indicated with a " / " between each name. If any are missing (even if only a reference), he puts the name of the ASM as the name of the component.

1 Like

Hello

Using AI, I have this code:

Option Explicit

' Références nécessaires :
'  - SolidWorks 2020 Type Library
'  - SolidWorks 2020 Constant Type Library

' Constantes d'erreur (à adapter/compléter selon votre SW 2020)
Const swMateErrorNone              As Long = 0
Const swMateErrorEntityNotFound    As Long = 1
Const swMateErrorComponentNotFound As Long = 2

Sub main()
    Dim swApp       As SldWorks.SldWorks
    Dim swModel     As SldWorks.ModelDoc2
    Dim swAssy      As SldWorks.AssemblyDoc
    Dim swFeat      As SldWorks.Feature
    Dim nextFeat    As SldWorks.Feature
    Dim swMate      As SldWorks.Mate2
    Dim deleteCount As Long
    Dim ok          As Boolean
    
    Set swApp = Application.SldWorks
    Set swModel = swApp.ActiveDoc
    
    ' Vérification : document ouvert et de type assemblage
    If swModel Is Nothing Or swModel.GetType <> swDocASSEMBLY Then
        MsgBox "Ouvrez un assemblage avant d'exécuter la macro.", vbExclamation
        Exit Sub
    End If
    
    Set swAssy = swModel
    deleteCount = 0
    
    ' Parcours de toutes les features
    Set swFeat = swModel.FirstFeature
    Do While Not swFeat Is Nothing
        Set nextFeat = swFeat.GetNextFeature
        
        ' Tenter de récupérer un Mate2
        On Error Resume Next
        Set swMate = swFeat.GetSpecificFeature2
        On Error GoTo 0
        
        If Not swMate Is Nothing Then
            ' **Filtre** : on ne supprime QUE si c'est bien un
            ' composant manquant (code 2)
            If swMate.GetMateError2 = swMateErrorComponentNotFound Then
                swModel.ClearSelection2 True
                ok = swFeat.Select2(False, -1)
                If ok Then
                    swAssy.EditDelete
                    deleteCount = deleteCount + 1
                End If
            End If
        End If
        
        Set swFeat = nextFeat
    Loop
     
    MsgBox deleteCount & " contrainte(s) en erreur supprimée(s).", vbInformation
End Sub

On the other hand I can't really test because when I delete components, my associated constraints switch to a kind of " deleted (missing) " state but not to " error "?? :
image

EDIT: new code to target missing components only

EDIT2:

The following are the values of the error codes returned by GetMateError2, as defined in the swFeatureError_e enumeration (mate-related entries):

Constant Value Meaning
swFeatureErrorNone 0 No mistakes
swFeatureErrorMateInvalidEdge 38 One of the edges of the mate is deleted, invalid or no longer exists
swFeatureErrorMateInvalidFace 39 One of the faces of the mate is deleted, invalid or no longer exists
swFeatureErrorMateFailedCreatingSurface 40 Mat surface type not supported
swFeatureErrorMateInvalidEntity 41 One of the features in the mate is deleted, invalid, or no longer exists
swFeatureErrorMateUnknownTangent 42 The tangent mate is not satisfied
swFeatureErrorMateDanglingGeometry 43 The mate points to a "dangling" geometry (missing face/edge)
swFeatureErrorMateEntityNotLinear 44 Nonlinear edges cannot be used for this mate
swFeatureErrorMateEntityFailed 45 Mating not supported or impossible on any of the components
swFeatureErrorMateOverdefined 46 This matte over-defines the assembly
swFeatureErrorMateIlldefined 47 This mate cannot be solved (poorly defined)
swFeatureErrorMateBroken 48 One or more mate entities are deleted/deleted (mate "broken")

These constants allow you to precisely filter the reasons for errors in your mates, for example to remove only those whose entities (faces, edges, etc.) are missing (codes 38, 39 or 43). (help.solidworks.com)


Maybe the constant to put here could be 41, 45, or 48:

Const swMateErrorComponentNotFound As Long = 41

Other constants here: https://help.solidworks.com/2021/english/api/swconst/SolidWorks.Interop.swconst~SolidWorks.Interop.swconst.swFeatureError_e.html
I tried 63 and 64 but don't work either...

1 Like

Hello
You have to check this option in the general SW options:

image

4 Likes

Thank you @Cyril_f , I couldn't find this option anymore.

So @Silver_Surfer , a possible alternative to the macro, is to uncheck the box shown by @Cyril_f which groups the constraints with missing components apart from the other errors:

image

All you have to do is select all the constraints in the " (missing) " folder, right-click, then " delete " (the red cross).

To be confirmed anyway if nothing else can be found in this case. My habits of constraints are too good; I have trouble generating errors :sweat_smile:

1 Like

They must be erased one by one!! This is still the best way to educate them.

2 Likes

Thank you all for your answers;
I'll look at all of this and I'll come back to the post.

1 Like

Not their fault: My predecessor told them never to tick this option!

In fact it's not such a good idea because they would be paid to repair their c_nneries.
The real best way is to withhold a salary up to the amount of time lost caused by their c_nneries! That's the only way it will fit.

Certainly for the option ok, but for habits there is bad will; I have never checked the option and I have never left constraints related to components that no longer exist.

Maybe it's just me who is too hard, eh, but a lack of rigor that impacts the rest of the team drives me crazy.

Hello

I don't know how to code in VBA too much but here is a code that works in C# (without subassembly handling or error handling)

ModelDoc2 swDoc = null;
Feature swFeat = null;
List<Feature> listFeat = new List<Feature>();
Mate2 swMate = null;
Object swSpecificFeature = null;
bool boolstatus = false;

swDoc = ((ModelDoc2)(swApp.ActiveDoc));
swFeat = (Feature)swDoc.FirstFeature();

while (swFeat != null)
{
    if (swFeat.GetTypeName() == "MateGroup")
    {
        swFeat = (Feature)swFeat.IGetFirstSubFeature();
        while (swFeat != null)
        {
            swSpecificFeature = swFeat.GetSpecificFeature2();
            swMate = swSpecificFeature as Mate2;
            if (swMate != null)
            {
                int errorCode = swFeat.GetErrorCode2(out boolstatus);
                if (errorCode == (int)swFeatureError_e.swSketchErrorExtRefFail)
                {
                    listFeat.Add(swFeat); //ajoute à la liste les contraintes avec l'erreur référence manquante
                }
            }
            swFeat = (Feature)swFeat.IGetNextSubFeature();
        }
        break;
    }
    swFeat = (Feature)swFeat.GetNextFeature();
}

int count = 0;
foreach (Feature swFeatSuppr in listFeat) // supprime les contraintes présentes dans la liste
{
    if (swFeatSuppr.Select2(false, 0))
    {
        swDoc.EditDelete();
        count++;
    }
}

MessageBox.Show(count + " contraintes ont été supprimées");

image

image

1 Like

By the way, AI invents a lot of methods that don't exist in the Solidworks API :roll_eyes:

2 Likes

Re Hello everyone!

So the best answer will be attributed to @Konti : even if I found elements to unlock me in many other answers, it is his that allowed me to move forward the most (and this despite the fact that his code is written in C#).

Thank you @Konti !

Here is the solution in detail:
Indeed, as the @Konti code shows, it is the error code 51 swSketchErrorExtRefFail that should be used.
When a component is deleted without removing its associated constraints, the constraint references take a flag **External**
image

For some reason, the first idea I had was to check the component associated with the wobbly constraint reference entity didn't work: there was still a filename associated with it, but it had nothing to do with the original one. Brief! Incomprehensible.

The condition for this to work is that the system option Treat missing constraint references as errors must be checked (precisely in order for code 51 to be associated with the constraint).
image

CAREFUL!! If a file is missing (i.e. SW can't find it), it appears as deleted in the tree and for all configurations if there are any, and the constraints associated with it also go back to error code 51; It is therefore necessary to think about solving/finding these components before exploiting the macro.

The other problem I encountered is related to the function of grouping constraints by status (*Thanks to @Sylk for making this display option appear in one of his posts):
If the constraint is a subfunction of the Default Constraints feature in the tree of an assembly, the user folders or auto-grouping folders are at the same level and must be discarded before analyzing the constraint.

There you go! Thank you all once again.
Below is my code:

Option Explicit

Dim swApp As SldWorks.SldWorks

Dim swModel As SldWorks.ModelDoc2
Dim swModelDocExt As SldWorks.ModelDocExtension
Dim swSelMgr As SldWorks.SelectionMgr

Dim swFeat As SldWorks.Feature
Dim swMateGroup As SldWorks.Feature
Dim swSubFolder As SldWorks.Feature
Dim swMateFeat As SldWorks.Feature
Dim swSubFeat As SldWorks.Feature

Dim swMate As IMate2
Dim swComp As SldWorks.Component2
Dim swMateEnt(2) As SldWorks.MateEntity2

Dim fileName As String
Dim Error As Long
Dim IsWarning As Boolean
Dim i As Long
Dim DeleteOption As Long
Dim status As Boolean
Dim Append As Boolean
Dim Mark As Integer
Dim List As Boolean


Sub main()
    
    Set swApp = Application.SldWorks
    Set swModel = swApp.ActiveDoc
    Set swSelMgr = swModel.SelectionManager
    Set swModelDocExt = swModel.Extension
    
    'Get the first feature in the assembly
    Set swFeat = swModel.FirstFeature
    'Iterate over features in FeatureManager design tree
    Do While Not swFeat Is Nothing
        If "MateGroup" = swFeat.GetTypeName Then
            Set swMateGroup = swFeat
            Exit Do
        End If
        Set swFeat = swFeat.GetNextFeature
    Loop
    
    Debug.Print "  " & swMateGroup.Name
    Debug.Print ""
    
    
    Set swSubFeat = swMateGroup.IGetFirstSubFeature
   'iterate over subfeatures (Mate or folders)
    Do While Not swSubFeat Is Nothing
        If "FtrFolder" = swSubFeat.GetTypeName Then
            '--------------------------------------------------------------------
            Debug.Print "swSubFeat TypeName:        " & swSubFeat.GetTypeName _
            & ",        Name:        " & swSubFeat.Name
            '--------------------------------------------------------------------
            GoTo Line1
        ElseIf "GroupedMatesFolder" = swSubFeat.GetTypeName Then
            '--------------------------------------------------------------------
            Debug.Print "swSubFeat TypeName:        " & swSubFeat.GetTypeName _
            & ",        Name:        " & swSubFeat.Name
            '--------------------------------------------------------------------
            GoTo Line1
            
        End If
        'MsgBox swSubFeat.GetTypeName
       Set swMate = swSubFeat.GetSpecificFeature2
        If Not swMate Is Nothing Then
            Error = swSubFeat.GetErrorCode2(IsWarning)

            ' Error 51 ?
            If Error = 51 Then List = swSubFeat.Select2(True, 0)
        End If
Line1:
                    
        Set swSubFeat = swSubFeat.IGetNextSubFeature
        
    Loop

    'Delete List
        ' To delete absorbed features, use enum swDeleteSelectionOptions_e.swDelete_Absorbed
        ' To delete children features, use enum swDeleteSelectionOptions_e.swDelete_Children
        ' To keep absorbed features and children features, set DeleteOption = 0
    DeleteOption = swDeleteSelectionOptions_e.swDelete_Absorbed
    'DeleteOption = swDeleteSelectionOptions_e.swDelete_Children
    'DeleteOption = 0
    'DeleteOption =swDeleteSelectionOptions_e.swDelete_Absorbed + swDeleteSelectionOptions_e.swDelete_Children
    
    status = swModelDocExt.DeleteSelection2(DeleteOption)
    
End Sub

4 Likes

F*** but how great your macro is!

Come on, a little backup in mine. Thank you for sharing and congratulations for the work done!

2 Likes