Macro identification et suppression de contraintes en erreur

Salut à tous !

Allons droit au but :
BE de 28 personnes mal (in)formées au sujet de l’option Supprimer les fonctions enfants dans les assemblages

et qui aujourd’hui sont emmerd*£§ avec ça :

.

On me demande aujourd’hui s’il est possible avec une macro d’identifier les contraintes en erreur pour cause de composant manquants et de les supprimer.

A l’aide de l’IA, j’ai ce code qui malheureusement n’est pas opérationnel (la condition If swFeature.GetTypeName = « Mate » n’est jamais vérifiée) :

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

Est-ce que quelqu’un saurait me dire ce qu’il cloche ?
Merci par avance.

Tu as essayé avec « Contraintes » (FR) au lieu de « Mate »? :


Edit: après test rapide et ajout d’un debug.print:
image

MateGroup semble fonctionner pour la 1ère vérification, par contre cela bug de nouveau juste derrière.

Bonjour,
Cet exemple de l’API me semble répondre au besoin pour ce qui est du scanne des contraintes.
Get Mates and Mate Entities Example (VBA) - 2024 - SOLIDWORKS API Help
En revanche pour la partie contrainte rompue il n’y a rien de direct si je ne fais pas d’erreur, il faut donc gérer un traitement sur la ligne de l’exemple :

  Debug.Print "      Component         = " & swComp.Name2

Dans mes tests, normalement il y a les deux composants indiqués avec un « / » entre chaque nom. S’il en manque (ne serait-ce qu’une référence) il met en nom de composant le nom de l’ASM.

1 « J'aime »

Bonjour

A l’aide de l’IA, j’ai ce 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

Par contre je ne peux pas vraiment tester car quand je supprime des composants, mes contraintes associées basculent dans une espèce d’état « supprimé (manquant) » mais pas en « erreur » ?? :
image

EDIT: nouveau code pour cibler les composants manquants uniquement

EDIT2:

Voici les valeurs des codes d’erreur retournés par GetMateError2, telles qu’elles sont définies dans l’énumération swFeatureError_e (mate‑related entries) :

Constante Valeur Signification
swFeatureErrorNone 0 Pas d’erreur
swFeatureErrorMateInvalidEdge 38 L’une des arêtes du mate est supprimée, invalide ou n’existe plus
swFeatureErrorMateInvalidFace 39 L’une des faces du mate est supprimée, invalide ou n’existe plus
swFeatureErrorMateFailedCreatingSurface 40 Type de surface de mate non pris en charge
swFeatureErrorMateInvalidEntity 41 L’une des entités du mate est supprimée, invalide ou n’existe plus
swFeatureErrorMateUnknownTangent 42 Le mate tangent n’est pas satisfait
swFeatureErrorMateDanglingGeometry 43 Le mate pointe vers une géométrie « dangling » (face/edge manquante)
swFeatureErrorMateEntityNotLinear 44 Arêtes non linéaires ne peuvent pas être utilisées pour ce mate
swFeatureErrorMateEntityFailed 45 Mating non supporté ou impossible sur l’un des composants
swFeatureErrorMateOverdefined 46 Ce mate sur‑définit l’assemblage
swFeatureErrorMateIlldefined 47 Ce mate ne peut pas être résolu (mal défini)
swFeatureErrorMateBroken 48 Un ou plusieurs mate entities sont supprimés/supprimés (mate “cassé”)

Ces constantes vous permettent de filtrer précisément les raisons d’erreur de vos mates, par exemple pour ne supprimer que ceux dont les entités (faces, arêtes…) sont manquantes (codes 38, 39 ou 43). (help.solidworks.com)


Peut-être que la constante à mettre ici pourrait être 41, 45, ou 48 :

Const swMateErrorComponentNotFound As Long = 41

D’autres constantes ici : swFeatureError_e Enumeration - 2021 - SOLIDWORKS API Help
J’ai essayé 63 et 64 mais marche pas non plus…

1 « J'aime »

Bonjour,
Il faut cocher cette option dans les options générales de SW:

4 « J'aime »

Merci @Cyril_f , je ne retrouvais plus cette option.

Du coup @Silver_Surfer , une alternative possible à la macro, est justement de décocher la case montrée par @Cyril_f ce qui groupe les contraintes à composants manquants à part des autres erreurs :

image

Il suffit alors de sélectionner toutes les contraintes dans le dossier « (manquants) », clic droit, puis « effacer » (la croix rouge quoi).

A confirmer quand même si rien d’autre ne peut se retrouver dans ce dossier. Moi mes habitudes de contraintes sont trop bonnes ; j’ai du mal à générer des erreurs :sweat_smile:

1 « J'aime »

C’est à elles qu’il faut les faire effacer une par une !! C’est encore le meilleur moyen de les éduquer.

2 « J'aime »

Merci à tous pour vos réponses ;
Je vais regarder tout ça et je ferai un retour sur le post.

1 « J'aime »

Pas de leur faute : Mon prédécesseur leur a dit de ne jamais cocher cette option !

En fait c’est pas une si bonne idée car ils seraient payés à réparer leurs c_nneries.
Le vrai meilleur moyen, c’est une retenue sur salaire à hauteur du temps perdu causé par leurs c_nneries ! Y a que comme ça que ça rentrera.

Certes pour l’option ok, mais pour les habitudes ya de la mauvaise volonté ; je n’ai jamais coché l’option et je n’ai jamais laissé des contraintes liées à des composants qui n’existent plus.

Après c’est peut-être juste moi qui suis trop dur, hein, mais un manque de rigueur qui impacte le reste de l’équipe ça me rend dingue.

Bonjour,

Je ne sais pas trop coder en VBA mais voici un code qui fonctionne en C# (sans gestion des sous-assemblages ni gestion des erreurs)

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 « J'aime »

Au passage l’IA invente beaucoup de méthodes qui n’existent pas dans l’API Solidworks :roll_eyes:

2 « J'aime »

Re Bonjour Tout le Monde !

Alors la meilleure réponse sera attribuée à @Konti : même si j’ai trouvé des éléments permettant de me débloquer dans beaucoup d’autres réponses, c’est la sienne qui m’a le plus permis d’avancer (et ce malgré que son code soit rédigé en C#).

Merci à toi @Konti !

Voici en détail la solution :
En effet, comme le montre le code de @Konti, c’est le code d’erreur 51 swSketchErrorExtRefFail qu’il faut utilisé.
Quand un composant est supprimé sans supprimer ses contraintes associées, les références de contrainte prennent un flag **External**
image

Pour une raison que j’ignore, la première idée que j’avais et qui consistait à aller vérifier le composant associé à l’entité de référence de contrainte bancale ne fonctionne pas : il y avait toujours un nom de fichier associé, mais qui n’avait rien à voir avec celui d’origine. Bref ! Incompréhensible.

La condition pour que cela fonctionne est que l’option système Traiter les références de contrainte manquantes comme des erreurs doit être cochés (justement pour que le code 51 soit associé à la contrainte).

ATTENTION !! Si un fichier est manquant (ie SW ne le trouve pas), celui-ci apparait comme supprimé dans l’arbre et pour toutes les configurations s’il y en a, et les contraintes qui lui sont associés remonte également avec le code d’erreur 51 ; il faut donc penser à résoudre/retrouver ces composants avant d’exploiter la macro.

L’autre problème que j’ai rencontré est lié à la fonction de groupement de contraintes par statuts (*Merci à @Sylk d’avoir fait apparaitre cette option d’affichage dans un de ses posts) :
Si la contrainte est une sous-fonction de la fonction Contraintes par défaut dans l’arbre d’un assemblage, les dossiers utilisateur ou les dossiers de regroupement automatique sont au même niveau et il faut les écarter avant d’analyser la contrainte.

Voilà ! Merci à tous encore une fois.
Ci-dessous mon 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 « J'aime »

Put*** mais comment elle est génial ta macro !

Allez hop, petite sauvegarde dans les miennes. Merci pour le partage et bravo pour le boulot abattu !

2 « J'aime »