Hello, I'm looking to read and edit notes or attributes in VBA blocks or instances of blocks in SolidWorks drawings. I can retrieve the block objects or block instances, but after the following functions I create errors: swBlockDef.GetNotes swBlockDef.GetNoteCount with swBlockDef as SldWorks.BlockDefinition or swlockInst.GetAnnotation swlockInst.GetAttributes swlockInst.GetAttributeCount swlockInst.GetAttributeValue swlockInst.SetAttributeValue with swlockInst as SldWorks.BlockInstance
In the past, I have already used swBlockDef.GetNotes successfully, but now, it doesn't work anymore. Does anyone have a solution for me? Thanks in advance
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' 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
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
It seems necessary to replace it with: SldWorks.SketchBlockDefinition
I use SldWorks.SketchBlockDefinition and SldWorks.SketchBlockInstance I can get the block and Blockinstance objects. It's after that that I have problems...
Hello Below is the code I use for my tests When vNote is vNote() as sldworks.note, then runtime error code 13 type mismatch When vNote as variant, the line vNote = swBlockDef.GetNotes gives vNote equals empty And, the line vNote = swlockInst.GetAttributes, then error code ‹ - 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
Hello So a lot of errors in the code. Below is the corrected code that should work (works on 2024 SP5), taken from the API help code.
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
Basically, declaring variables that are incorrect:
Dim vBlockDef() As SldWorks.BlockDefinition
Variable type Variant and no parentheses to put on the name of this variable. Missing a set of the swNote variable and many others.
Hello You're right about the missing sets on swNote = vNote(i) On the other hand, when Dim vBlockDef As Variant, I get an error at the line Set swBlockDef = vBlockDef(i), that I am when Dim vBlockDef() As SldWorks.BlockDefinition
I'm in SW2022 sp5.0 It's strange from my side: When vNote as variant, then vNote = swBlockDef.GetNotes or vNote = swlockInst.GetAttributes are empty When vNote() As SldWorks.Note, then the same functions create a runtime error 13: Type mismatch
We should look at the references (Tools-> References). Mine are these, but my code contains different macros that need more references than necessary for the needs of the block macro. Then another problem that has already happened to me is the version of VBA which is not the right one and generates macOS operating errors
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' 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
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Without wanting to offend you, @Patrick_CHARDON , you don't seem very comfortable with variable declarations. I recommend that you trust @Cyril_f, moreover its macro works with us. What do you want to get as information from your bock exactly, we can probably help you but if we don't really know what you're trying to do it's complicated... And now we're going around in circles...
I don't have a file with blocks dating from 2007 so it's difficult to test a code that would solve the problem. I can, however, provide a code for testing
Below the code to be tested, works on blocks created on a version higher than 2007, as explained no debugging possible on my side on previous versions. @Maclane if you can test.
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 , your Macro seems to work without problems on old blocks before 2007. … Even if the test is a bit biased by the fact that I didn't use many attributes in my old blocks. (I had suffered way too much with Autocad's at the time...)
I took the liberty of adding a few comments to your code for educational purposes: ( In reality it was the AI " Perplexity " that did it. And this is the only use of AI that I allow myself to date... and even then they sometimes hallucinate ... ).
' 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
I took the liberty of modifying the code in both messages because I realized that the last line was useless (I had started with another idea at the beginning and I omitted to delete what was no longer useful). Thank you for the test and the addition of comments (I admit that I don't comment too much on my codes anymore since I'm the only one to code in my company) @Patrick_CHARDON , it's up to you