Hallo, ik ben op zoek naar het lezen en bewerken van notities of attributen in VBA-blokken of instanties van blokken in SolidWorks-tekeningen. Ik kan de blokobjecten of blokinstanties ophalen, maar na de volgende functies maak ik fouten aan: swBlockDef.GetNotes swBlockDef.GetNoteCount met swBlockDef als SldWorks.BlockDefinition of swlockInst.GetAnnotation swlockInst.GetAttributes swlockInst.GetAttributeCount swlockInst.GetAttributeValue swlockInst.SetAttributeValue met swlockInst als SldWorks.BlockInstance
In het verleden heb ik swBlockDef.GetNotes al met succes gebruikt, maar nu werkt het niet meer. Heeft iemand een oplossing voor mij? Bij voorbaat dank
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' OLD BLOCKS: Obsolete and not supported block
' interfaces as of SOLIDWORKS 2007
'Dim swBlockDef As SldWorks.BlockDefinition
'Dim swBlockInst As SldWorks.BlockInstance
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' NEW BLOCKS: New block interfaces as of SOLIDWORKS 2007
Dim swBlockDef As SldWorks.SketchBlockDefinition
Dim swBlockInst As SldWorks.SketchBlockInstance
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Het lijkt noodzakelijk om het te vervangen door: SldWorks.SketchBlockDefinition
Ik gebruik SldWorks.SketchBlockDefinition en SldWorks.SketchBlockInstance Ik kan de blok- en Blockinstance-objecten krijgen. Het is daarna dat ik problemen heb...
Hallo Hieronder staat de code die ik gebruik voor mijn tests Wanneer vNote vNote() is als sldworks.note, komt runtime-foutcode 13 niet overeen Wanneer vNote als variant is, is de regel vNote = swBlockDef.GetNotes geeft vNote gelijk aan leeg En, de regel vNote = swlockInst.GetAttributes, dan foutcode ‹ - 670099352 (d80f1868) ›: Error Automation
Sub main()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim SwSketchMgr As SldWorks.SketchManager
Dim vBlockDef() As SldWorks.BlockDefinition
Dim swBlockDef As SldWorks.BlockDefinition
Dim vBlockInst() As SldWorks.BlockInstance
Dim swlockInst As SldWorks.BlockInstance
Dim vNote As Variant
'Dim vNote() As SldWorks.Note
Dim swNote As SldWorks.Note
Dim i As Long
Dim j As Long
Dim k As Long
Dim Text As String
Set swApp = CreateObject("SldWorks.Application")
Set swModel = swApp.ActiveDoc
Set SwSketchMgr = swModel.SketchManager
vBlockDef = SwSketchMgr.GetSketchBlockDefinitions
If Not IsEmpty(vBlockDef) Then
For i = 0 To UBound(vBlockDef)
Set swBlockDef = vBlockDef(i)
Text = swBlockDef.Name
vNote = swBlockDef.GetNotes 'vide ou erreur
If Not IsEmpty(vNote) Then
For j = 0 To UBound(vNote)
swNote = vNote(j)
Text = swNote.GetText
Next
End If
vBlockInst = swBlockDef.GetInstances
If Not IsEmpty(vBlockInst) Then
For j = 0 To UBound(vBlockInst)
Set swlockInst = vBlockInst(j)
Text = swlockInst.Name
vNote = swlockInst.GetAttributes 'Erreur d'exécution '-670099352 (d80f1868)': Erreur Automation
If Not IsEmpty(vNote) Then
For k = 0 To UBound(vNote)
Set swNote = vNote(k)
Text = swNote.TagName
Next
End If
Next
End If
Next i
End If
End Sub
Hallo Dus veel fouten in de code. Hieronder staat de gecorrigeerde code die zou moeten werken (werkt op 2024 SP5), afkomstig uit de API-helpcode.
Sub main()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim SwSketchMgr As SldWorks.SketchManager
Dim vBlockDef As Variant
Dim swBlockDef As SldWorks.SketchBlockDefinition
Dim vBlockInst As Variant
Dim swBlockInst As SldWorks.SketchBlockInstance
Dim vNote As Variant
Dim swNote As SldWorks.Note
Dim i As Long
Dim j As Long
Dim k As Long
Dim Text As String
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
Set SwSketchMgr = swModel.SketchManager
vBlockDef = SwSketchMgr.GetSketchBlockDefinitions
If Not IsEmpty(vBlockDef) Then
For i = 0 To UBound(vBlockDef)
Set swBlockDef = vBlockDef(i)
vNote = swBlockDef.GetNotes 'vide ou erreur
If Not IsEmpty(vNote) Then
For j = 0 To UBound(vNote)
Set swNote = vNote(j)
Text = swNote.GetText
Next
End If
vBlockInst = swBlockDef.GetInstances
If Not IsEmpty(vBlockInst) Then
For j = 0 To UBound(vBlockInst)
Set swBlockInst = vBlockInst(j)
Text = swBlockInst.Name
vNote = swBlockInst.GetAttributes
If Not IsEmpty(vNote) Then
For k = 0 To UBound(vNote)
Set swNote = vNote(k)
Text = swNote.TagName
Next
End If
Next
End If
Next i
End If
End Sub
Kortom, het declareren van variabelen die onjuist zijn:
Dim vBlockDef() As SldWorks.BlockDefinition
Variabeletype Variant en geen haakjes om op de naam van deze variabele te zetten. Er ontbreekt een set van de swNote-variabele en vele andere.
Hallo Je hebt gelijk over de ontbrekende sets op swNote = vNote(i) Aan de andere kant, wanneer Dim vBlockDef als variant, krijg ik een foutmelding op de regel Set swBlockDef = vBlockDef(i), dat ben ik wanneer Dim vBlockDef() As SldWorks.BlockDefinition
Ik zit in SW2022 sp5.0 Het is vreemd van mijn kant: Als vNote als variant is, dan zijn vNote = swBlockDef.GetNotes of vNote = swlockInst.GetAttributes leeg Wanneer vNote() Als SldWorks.Note, dan creëren dezelfde functies een runtime-fout 13: Type mismatch
We moeten kijken naar de referenties (Tools-> References). De mijne zijn deze, maar mijn code bevat verschillende macro's die meer referenties nodig hebben dan nodig is voor de behoeften van de blokmacro. Dan is een ander probleem dat mij al is overkomen, de versie van VBA die niet de juiste is en macOS-bedieningsfouten genereert
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' OLD BLOCKS: Obsolete and not supported block
' interfaces as of SOLIDWORKS 2007
'Dim swBlockDef As SldWorks.BlockDefinition
'Dim swBlockInst As SldWorks.BlockInstance
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' NEW BLOCKS: New block interfaces as of SOLIDWORKS 2007
Dim swBlockDef As SldWorks.SketchBlockDefinition
Dim swBlockInst As SldWorks.SketchBlockInstance
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Zonder je te willen beledigen, @Patrick_CHARDON , lijk je niet erg op je gemak te voelen bij variabele declaraties. Ik raad je aan om @Cyril_f te vertrouwen, bovendien werkt de macro met ons mee. Wat wil je precies als informatie uit je bock halen, we kunnen je waarschijnlijk helpen maar als we niet echt weten wat je probeert te doen is het ingewikkeld... En nu draaien we in cirkels rond...
Ik heb geen bestand met blokken uit 2007, dus het is moeilijk om een code te testen die het probleem zou oplossen. Ik kan echter wel een code opgeven om te testen
Onder de te testen code werkt op blokken die zijn gemaakt op een versie hoger dan 2007, zoals uitgelegd geen foutopsporing mogelijk aan mijn kant op eerdere versies. @Maclane als je kunt testen.
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swDraw As SldWorks.DrawingDoc
Dim SwSketchMgr As SldWorks.SketchManager
Dim vBlockDef As Variant
Dim swBlockDef As SldWorks.SketchBlockDefinition
Dim OldSwBlockDef As SldWorks.BlockDefinition
Dim vBlockInst As Variant
Dim swBlockInst As SldWorks.SketchBlockInstance
Dim OldSwBlockInst As SldWorks.BlockInstance
Dim vNote As Variant
Dim swNote As SldWorks.Note
Dim bOldBlock As Boolean
Dim i As Long
Dim j As Long
Dim k As Long
Dim Text As String
Sub main()
Set swApp = Application.SldWorks
bOldBlock = False
Set swModel = swApp.ActiveDoc
Set swDraw = swModel
Set SwSketchMgr = swModel.SketchManager
vBlockDef = SwSketchMgr.GetSketchBlockDefinitions
If IsEmpty(vBlockDef) Then
vBlockDef = swDraw.GetBlockDefinitions
bOldBlock = True
End If
If Not IsEmpty(vBlockDef) Then
For i = 0 To UBound(vBlockDef)
If Not bOldBlock Then
Set swBlockDef = vBlockDef(i)
vNote = swBlockDef.GetNotes
vBlockInst = swBlockDef.GetInstances
Else
Set OldSwBlockDef = vBlockDef(i)
vNote = OldSwBlockDef.GetNotes
vBlockInst = OldSwBlockDef.GetBlockInstances
End If
If Not IsEmpty(vNote) Then
For j = 0 To UBound(vNote)
Set swNote = vNote(j)
Text = swNote.GetText
Debug.Print Text
Next
End If
If Not IsEmpty(vBlockInst) Then
For j = 0 To UBound(vBlockInst)
If Not bOldBlock Then
Set swBlockInst = vBlockInst(j)
Text = swBlockInst.Name
Debug.Print Text
vNote = swBlockInst.GetAttributes
Else
Set OldSwBlockInst = vBlockInst(j)
Text = OldSwBlockDef.Name
Debug.Print Text
vNote = OldSwBlockInst.GetAttributes
End If
If Not IsEmpty(vNote) Then
For k = 0 To UBound(vNote)
Set swNote = vNote(k)
Text = swNote.TagName
Debug.Print Text
Next
End If
Next
End If
Next i
End If
End Sub
@Cyril_f , je Macro lijkt zonder problemen te werken op oude blokken van voor 2007. … Ook al is de test een beetje bevooroordeeld door het feit dat ik niet veel attributen in mijn oude blokken heb gebruikt. (Ik had op dat moment veel te veel last van Autocad's...)
Ik ben zo vrij geweest om een paar opmerkingen aan je code toe te voegen voor educatieve doeleinden: ( In werkelijkheid was het de AI " Perplexity " die het deed. En dit is het enige gebruik van AI dat ik mezelf tot nu toe toesta... En zelfs dan hallucineren ze soms ....).
' Déclaration des variables liées à l'API SolidWorks
Dim swApp As SldWorks.SldWorks ' Objet principal de l'application SolidWorks
Dim swModel As SldWorks.ModelDoc2 ' Document actif (pièce, assemblage ou mise en plan)
Dim swDraw As SldWorks.DrawingDoc ' Document de type mise en plan
Dim SwSketchMgr As SldWorks.SketchManager ' Gestionnaire des esquisses
Dim vBlockDef As Variant ' Tableau/variant contenant les définitions de blocs
Dim swBlockDef As SldWorks.SketchBlockDefinition ' Définition d’un bloc (mode SketchManager)
Dim OldSwBlockDef As SldWorks.BlockDefinition ' Définition d’un bloc (ancienne interface)
Dim vBlockInst As Variant ' Tableau/variant contenant les instances de blocs
Dim swBlockInst As SldWorks.SketchBlockInstance ' Instance d’un bloc (mode SketchManager)
Dim OldSwBlockInst As SldWorks.BlockInstance ' Instance d’un bloc (ancienne interface)
Dim vNote As Variant ' Tableau/variant contenant les notes
Dim swNote As SldWorks.Note ' Objet note (annotation textuelle)
Dim bOldBlock As Boolean ' Indicateur : True si bloc utilisant l'ancienne API
Dim i As Long ' Compteur boucle externe
Dim j As Long ' Compteur boucle intermédiaire
Dim k As Long ' Compteur boucle interne
Dim Text As String ' Chaîne temporaire pour stocker du texte
Sub main()
' Récupère l'instance active de SolidWorks
Set swApp = Application.SldWorks
' Par défaut, on suppose qu’on utilise la nouvelle API (pas de vieux blocs)
bOldBlock = False
' Récupère le document actif dans SolidWorks
Set swModel = swApp.ActiveDoc
' Force la variable swDraw à être le document actif considéré comme un DrawingDoc
Set swDraw = swModel
' Récupère le gestionnaire d’esquisse (permet d’accéder aux blocs d’esquisse)
Set SwSketchMgr = swModel.SketchManager
' Tente de récupérer les définitions de blocs "nouvelle API" via le SketchManager
vBlockDef = SwSketchMgr.GetSketchBlockDefinitions
' Si aucune définition trouvée, on essaie via l’ancienne méthode pour les mises en plan
If IsEmpty(vBlockDef) Then
vBlockDef = swDraw.GetBlockDefinitions
bOldBlock = True ' Utilisation de l’ancienne API détectée
End If
' Vérifie si on a bien trouvé au moins une définition de bloc
If Not IsEmpty(vBlockDef) Then
' Parcourt l'ensemble des définitions de blocs récupérées
For i = 0 To UBound(vBlockDef)
' En fonction du type de bloc (nouveau ou ancien), on caste dans le bon objet
If Not bOldBlock Then
Set swBlockDef = vBlockDef(i) ' Définition de bloc "nouvelle API"
vNote = swBlockDef.GetNotes ' Récupère toutes les notes associées à ce bloc
vBlockInst = swBlockDef.GetInstances ' Récupère toutes ses instances
Else
Set OldSwBlockDef = vBlockDef(i) ' Définition de bloc "ancienne API"
vNote = OldSwBlockDef.GetNotes
vBlockInst = OldSwBlockDef.GetBlockInstances
End If
' ----- TRAITEMENT DES NOTES ASSOCIÉES AU BLOC -----
If Not IsEmpty(vNote) Then
For j = 0 To UBound(vNote)
Set swNote = vNote(j)
Text = swNote.GetText ' Récupère le texte complet de la note
Debug.Print Text ' Affiche dans la fenêtre d’exécution VBA
Next
End If
' ----- TRAITEMENT DES INSTANCES DE BLOCS -----
If Not IsEmpty(vBlockInst) Then
For j = 0 To UBound(vBlockInst)
If Not bOldBlock Then
Set swBlockInst = vBlockInst(j) ' Instance (nouvelle API)
Text = swBlockInst.Name
Debug.Print Text
vNote = swBlockInst.GetAttributes ' Récupère les attributs (métadonnées) de l’instance
Else
Set OldSwBlockInst = vBlockInst(j) ' Instance (ancienne API)
Text = OldSwBlockDef.Name ' ? Ici : on affiche le nom de la définition, pas de l’instance
Debug.Print Text
vNote = OldSwBlockInst.GetAttributes
End If
' ----- TRAITEMENT DES ATTRIBUTS DE L’INSTANCE -----
If Not IsEmpty(vNote) Then
For k = 0 To UBound(vNote)
Set swNote = vNote(k) ' Ici, un "attribut" est représenté comme un objet Note/Annotation
Text = swNote.TagName ' Récupère le nom de balise (TagName) de l’attribut
Debug.Print Text
Next
End If
Next
End If
Next i
End If
End Sub
Ik ben zo vrij geweest om de code in beide berichten aan te passen omdat ik me realiseerde dat de laatste regel nutteloos was (ik was in het begin met een ander idee begonnen en ik heb nagelaten te verwijderen wat niet langer nuttig was). Bedankt voor de test en de toevoeging van opmerkingen (ik geef toe dat ik niet al te veel commentaar meer geef op mijn codes omdat ik de enige ben die codeert in mijn bedrijf) @Patrick_CHARDON , het is aan jou