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