Basemap maken / herladen: bestaande blokken gebruiken

Hallo SolidWorkers!

We hebben een script bij het openen van tekeningen (en een macroknop voor handmatig starten) om de basismap opnieuw te laden op alle bladen in een tekening.

De basiskaart heeft 3 blokken (cartridge, liniaal, oriëntatiemarkering).

Ik realiseerde me dat het script dat gebruikmaakt van de SetUpSheet* en ReloadTemplate API's, voor elk blad de 3 blokken van de tekening dupliceert.

Terwijl de handmatige bediening van het toevoegen van een blad of het herladen van een basismap op een bestaand werkblad, het systeem ons vraagt om te kiezen of we nieuwe blokken willen hernoemen of bestaande willen gebruiken, lijkt ons script automatisch ja te antwoorden op deze vraag:
image

Hoe antwoord ik automatisch nee en geen dubbele blokken?
Welke API's en/of API-parameterwaarden kan ik gebruiken om het gewenste gedrag te bereiken?

We hebben plannen die tot 112 pagina's lang kunnen zijn; We eindigen met 336 blokken in de boom.

Bij voorbaat dank.

Hallo Silver_Surfer,
Zonder je code te delen, is het een beetje ingewikkeld om te vinden :stuck_out_tongue_winking_eye:

De code in kwestie doet veel andere dingen op Solidworks, SmarTeam en andere niveaus die niet relevant zijn om te delen.
Het deel van deze code dat de basismap opnieuw laadt, is min of meer hetzelfde (SetUpSheet API-parameters) als het in de help wordt gevonden.

Maar hier is de code die me problemen bezorgt:

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

Die keuze kun je niet hebben met de API.
Als u al deze blokken in uw boom wilt vermijden, is de eenvoudigste manier om deze van de basiskaart te verwijderen en de schetsen vast te leggen (of ze op te meten en de afmetingen te verbergen).
Anders kunt u een code maken waarmee alle blokken worden verwijderd, behalve de blokken op het eerste blad, en deze vervolgens in de volgende bladen invoegen. Deze aanpak houdt zich aan het gedrag dat je wilt, maar het is iets meer werk om te coderen (hoewel...)

Mijn collega van IT lijkt hier een oplossing te hebben gevonden:

Hij extraheerde en " formatteerde " de onderstaande code die het mogelijk maakt om dubbele blokken te verwijderen.

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 KB)

Ik moet deze macro nog testen op tekeningen met meerdere vellen en meerdere kaders op de achtergrond en in de wrap.

2 likes

Ja, het is een goede aanpak. Houd ons op de hoogte :wink:

Na wat testen merken we dat de macro bugs met blokken waarvan het pad niet bestaat;
Het herladen van de basiskaart kost al tijd, maar het voltooien van de operatie met het schoonmaken van de blokken is helaas niet ver van de extra minuut.

Om deze code aan te vullen/te verbeteren (op dit moment zijn we qua openingstijd niet meer een paar seconden verwijderd!), zoeken mijn collega en ik naar manieren om grijze blokken te identificeren en te verwijderen (d.w.z. blokken die zijn verwijderd in en sinds de tekening, niet uit de FeatureManager-boom).

Heeft iemand deze operatie al geautomatiseerd?

Hallo;

Probeer het met de methode:

value = instance.IsSuppressed()

https://help.solidworks.com/2021/english/api/sldworksapi/SOLIDWORKS.Interop.sldworks~SOLIDWORKS.Interop.sldworks.IComponent2~IsSuppressed.html
Maar ik weet niet of het mogelijk is om het toe te passen op een blokinstantie... :woozy_face:

Aan de andere kant moet het mogelijk zijn om het te associëren met Selectiemanager:

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

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

1 like

Dit onderwerp kan worden afgesloten.

De macro hieronder doet de grote schoonmaak op blokniveau van een tekening voor

  • duplicaten verwijderen (gebouwd met ReloadTemplate API)
  • verwijder de blokken zonder instantie (d.w.z. de blokken die aanwezig zijn in de blokmap van de FM-boom, maar afwezig zijn in alle bladen van het plan).

De verwerkingstijd is afhankelijk van het aantal blokken en het aantal vellen.
<2min voor een plan van 112 vellen en meer dan 300 blokken

BlocksRepair.swp (58.5 KB)

Bedankt allemaal voor jullie hulp.
(Beste antwoord willekeurig toegeschreven aan de @Konti omdat hij als eerste antwoordde).

1 like