Création de feuille / Rechargement fond de plan: utiliser les blocs existants

Hello les SolidWorkers !

Nous avons un script à l’ouverture des mises en plan (et un bouton de macro pour un lancement manuel) pour recharger le fond de plan sur l’ensemble des feuilles d’une mise en plan.

Le fond de plan comporte 3 blocs (cartouche, règle, repère d’orientation).

Je me suis rendu compte que le script qui utilise les API SetUpSheet* et ReloadTemplate, duplique pour chaque feuille les 3 blocs de la mise en plan.

Alors que l’opération manuelle d’ajout de feuille ou de rechargement de fond de plan sur une feuille existante, le système nous invite à choisir de renommer des nouveaux blocs ou d’utiliser les blocs existants, notre script lui, semble répondre automatiquement oui à cette question :
image

Comment faire pour répondre automatiquement non et ne pas dupliquer les blocs ?
Avec quels API et/ou valeurs de paramètres d’API puis-je obtenir le comportement souhaité ?

Nous avons des plans qui peuvent compter jusqu’à 112 pages ; on se retrouve avec 336 blocs dans l’arbre.

Merci par avance.

Hello Silver_Surfer,
Sans partager ton code, c’est un peu compliqué de trouver :stuck_out_tongue_winking_eye:

Le code en question fait pas mal d’autre choses au niveau Solidworks, SmarTeam et autre qui n’est pas pertinent de partager.
La partie de ce code qui recharge le fond de plan reprend à peu de choses près (paramètres de l’API SetUpSheet) ce qu’on trouve dans l’aide.

Mais voilà le code qui me cause soucis :

Sub main()


Dim swApp                       As SldWorks.SldWorks
Dim swModel                     As SldWorks.ModelDoc2
Dim swDraw                      As SldWorks.DrawingDoc
Dim swSheet                     As SldWorks.Sheet
Dim swView                      As SldWorks.View
Dim vSheetProps                 As Variant

Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
Set swDraw = swModel
Set swSheet = swDraw.GetCurrentSheet
vSheetProps = swSheet.GetProperties

Dim size As String
If vSheetProps(0) = 7 Then
            '7 = A4 Portrait
            templateFormat = "A4.SLDDRT"
            size = "A4"
ElseIf vSheetProps(0) = 8 Then
            '8 = A3 Paysage
            templateFormat = "A3.SLDDRT"
            size = "A3"
ElseIf vSheetProps(0) = 9 Then
            '9 = A2 Paysage
            templateFormat = "A2.SLDDRT"
            size = "A2"
ElseIf vSheetProps(0) = 10 Then
            '10 = A1 Paysage
            templateFormat = "A1.SLDDRT"
            size = "A1"
ElseIf vSheetProps(0) = 11 Then
            '11 = A0 Paysage
            templateFormat = "A0.SLDDRT"
            size = "A0"
End If


boolstatus = swModel.SetupSheet5( _
    swSheet.GetName, _
    vSheetProps(0), _
    vSheetProps(1), _
    vSheetProps(2), _
    vSheetProps(3), _
    True, _
    templateFormat, _
    vSheetProps(5), _
    vSheetProps(6), _
    "Par défaut", _
    True _
)
               
swSheet.ReloadTemplate False
End Sub

Tu ne peux pas avoir ce choix avec l’API.
Si tu veux éviter tous ces blocs dans ton arbre, alors le plus simple est de le supprimer du fond de plan et fixer les esquisses (ou les coter et cacher les cotes).
Sinon tu peux créer un code qui supprime tous les blocs à part ceux de la première feuille, puis les insérer dans les feuilles suivantes. Cette approche collera au comportement que tu souhaite, mais c’est un peu plus de boulot à coder (quoique…)

Mon collègue de l’informatique semble avoir trouvé une parade ici :

Il en a extrait et « mis en forme » le code ci-dessous qui permet de supprimer les doublons de blocs.

Option Explicit

Sub main()
    Dim swApp As SldWorks.SldWorks
    Dim swModelDoc As SldWorks.ModelDoc2
    Dim bRet As Boolean
    
    Set swApp = Application.SldWorks
    Set swModelDoc = swApp.ActiveDoc

    BlocksRepair swModelDoc
    
    bRet = swModelDoc.ForceRebuild3(False)
End Sub

Function BlocksRepair(swModel As SldWorks.ModelDoc2)
    Dim swDrawingDoc As SldWorks.DrawingDoc
    Dim swSketchManager As SldWorks.SketchManager
    Dim swSketchBlockDef As SldWorks.SketchBlockDefinition
    Dim swSketchBlockInst As SldWorks.SketchBlockInstance
    Dim vSketchBlockOriginalNames As Scripting.Dictionary
    Dim vSketchBlockDefs As Variant
    Dim vSketchBlockDef As Variant
    Dim vBadSketchBlockDefs As Scripting.Dictionary
    Dim vBadSketchBlockDef As Variant
    Dim vSketchBlockInsts As Variant
    Dim vSketchBlockInst As Variant
    Dim sBlockFileName As String
    Dim sBlockName As String
    Dim sBlockDefName As String
    
    Set vSketchBlockOriginalNames = New Scripting.Dictionary
    Set vBadSketchBlockDefs = New Scripting.Dictionary
    Set swSketchManager = swModel.SketchManager
    
    vSketchBlockDefs = swSketchManager.GetSketchBlockDefinitions
            
    If Not IsEmpty(vSketchBlockDefs) Then
        For Each vSketchBlockDef In vSketchBlockDefs
            Set swSketchBlockDef = vSketchBlockDef
        
            sBlockFileName = swSketchBlockDef.filename
            sBlockName = Mid(sBlockFileName, InStrRev(sBlockFileName, "\") + 1, InStrRev(sBlockFileName, ".") - InStrRev(sBlockFileName, "\") - 1)
            sBlockDefName = swSketchBlockDef.GetFeature.Name
            
            If (sBlockDefName = sBlockName) Then
                vSketchBlockOriginalNames.Add sBlockDefName, swSketchBlockDef
            Else
                vBadSketchBlockDefs.Add sBlockDefName, swSketchBlockDef
            End If
        Next
        
        For Each vBadSketchBlockDef In vBadSketchBlockDefs
            Set swSketchBlockDef = vBadSketchBlockDefs(vBadSketchBlockDef)
            
            sBlockFileName = swSketchBlockDef.filename
            sBlockName = Mid(sBlockFileName, InStrRev(sBlockFileName, "\") + 1, InStrRev(sBlockFileName, ".") - InStrRev(sBlockFileName, "\") - 1)
            sBlockDefName = swSketchBlockDef.GetFeature.Name
            
            vSketchBlockInsts = swSketchBlockDef.GetInstances
            
            If Not IsEmpty(vSketchBlockInsts) And swSketchBlockDef.GetInstanceCount > 0 Then
                For Each vSketchBlockInst In vSketchBlockInsts
                    Set swSketchBlockInst = vSketchBlockInst
                                    
                    If DoesItemExist(vSketchBlockOriginalNames, sBlockName) = True Then
                        swSketchBlockInst.Definition = vSketchBlockOriginalNames(sBlockName)
                    End If
                Next
            End If
        Next
    End If
End Function

Public Function DoesItemExist(vSketchBlockOriginalNames As Scripting.Dictionary, sBlockName As String) As Boolean
    Dim vSketchBlockOriginalName As Variant

    DoesItemExist = False

    For Each vSketchBlockOriginalName In vSketchBlockOriginalNames.Keys
        If sBlockName = vSketchBlockOriginalName Then
            DoesItemExist = True
            
            Exit Function
        End If
    Next
End Function

BlocksRepair.swp (53,5 Ko)

Je dois encore tester cette macro sur des mises en plans avec plusieurs feuilles et des blocs multiple en fond de plan et en habillage.

2 « J'aime »

Oui c’est une bonne approche. Tiens-nous au courant :wink:

Après quelque test, on s’aperçois que la macro bug avec des blocs dont le chemin est inexistant ;
Le rechargement de fond de plan prend déjà du temps, mais compléter l’opération avec le nettoyage des blocs, on est pas loin de la minute supplémentaire malheureusement.

Pour compléter/améliorer ce code (au point où on en est en terme de temps d’ouverture, on est plus à qq secondes supplémentaire !), mon collègue et moi cherchons comment identifier et supprimer les blocs grisés (c’est à dire ceux qui ont été supprimer dans et depuis la mise en plan, pas depuis l’arbre FeatureManager).

Est-ce que qqn a déjà automatiser cette opération ?

Bonjour;

A essayer avec la methode :

value = instance.IsSuppressed()

https://help.solidworks.com/2021/english/api/sldworksapi/SOLIDWORKS.Interop.sldworks~SOLIDWORKS.Interop.sldworks.IComponent2~IsSuppressed.html
Mais je ne sais pas s’il est possible de l’appliquer à une instance de bloc… :woozy_face:

En revanche il doit être possible de l’associer avec Selection manager:

    Set swSelMgr = swModel.SelectionManager
    swSelMgr.SelectByID2 "NomDuBloc", "BLOCKINSTANCES", 0, 0, 0, False, 0, Nothing, 0

puis avec:
value = instance.EditSuppress2()
https://help.solidworks.com/2022/english/api/sldworksapi/SOLIDWORKS.Interop.sldworks~SOLIDWORKS.Interop.sldworks.IModelDoc2~EditSuppress2.html?verRedirect=1

1 « J'aime »

Ce sujet va pouvoir être clôt.

La macro ci-dessous fait le grand nettoyage au niveau des blocs d’une mise en plan pour

  • supprimer les doublons (générer avec l’API ReloadTemplate)
  • supprimer les blocs sans instance (ie les blocs présents dans le dossier de bloc de l’arbre FM mais absent de l’ensemble des feuilles du plan).

Le temps de traitement est dépendant du nombre de blocs et du nombre de feuille.
<2min pour une mise en plan de 112 feuilles et plus de 300 blocs

BlocksRepair.swp (58,5 Ko)

Merci à tous pour votre aide.
(Meilleure réponse attribuée arbitrairement au @Konti pour avoir été le premier à répondre).

1 « J'aime »